@srfnstack/fntags

fntags primary goal is to make the developer experience pleasant while providing high performance and neato features.

Usage no npm install needed!

<script type="module">
  import srfnstackFntags from 'https://cdn.skypack.dev/@srfnstack/fntags';
</script>

README

fntags header


What the f?

fntags primary goal is to make the developer experience pleasant while providing high performance and neato features.

  • No dependencies and no build tools
    - Import the framework directly from your favorite cdn and start building.

  • Everything is javascript
    - There's no special templating language to learn, and you won't be writing html.
    - This removes the template+functionality duality and helps keep you focused by removing context switching.

  • Real DOM elements
    - Every element is a real dom element, there's no virtual dom and no wrapper objects.

  • It's familiar
    - fntags was inspired by React, and the state management is similar to react hooks.

  • State binding is explicit and granular
    - Bind only the text of an element, an attribute, or a style. You control the binding, replace as much or as little as you want.

  • State exists without components
    - This allows app wide states to be maintained using export/import and removes the need for complex state management like redux.

  • Dynamic routing
    - The modRouter only loads the files required by each route and doesn't require bundling.
    - Bye bye fat bundles, hello highly cacheable routes.

  • Async Rendering
    - fntags will resolve promises that are passed to element functions, no special handling required.

Documentation

Check out the documentation to learn more!

f'n examples


Components are plain functions

import { div } from 'https://cdn.jsdelivr.net/npm/@srfnstack/fntags@0.3.3/src/fnelements.min.mjs'

const hello = name => div('Hello ', name)

document.body.append( hello('world!') )

Two-way binding is a breeze with the bind functions provided by fnstate objects.

import { fnstate } from 'https://cdn.jsdelivr.net/npm/@srfnstack/fntags@0.3.3/src/fntags.min.mjs'
import { div, input, br } from 'https://cdn.jsdelivr.net/npm/@srfnstack/fntags@0.3.3/src/fnelements.min.mjs'

export const userName = fnstate('world')
export const appColor = fnstate('MediumTurquoise')

document.body.append(
  div( { style: { color: appColor.bindStyle() } },
    'Hello ', userName.bindAs(), '!'
  ),
  br(),
  input({ 
    value: userName.bindAttr(),
    oninput: e => userName(e.target.value)
  }),
  br(),
  input({ 
    value: appColor.bindAttr(),
    oninput: e => appColor(e.target.value)
  }),
)

Required HTML

Unfortunately browsers lack the ability to render a js file directly, and thus you still need a tiny bit of html to bootstrap your app.

Here's an example of the only html you need to write for your entire application.

Now that these two lines are there you're set to write sweet sweet es6+ and no more html.

<html><body><script type="module">
import { div } from 'https://cdn.jsdelivr.net/npm/@srfnstack/fntags@0.3.3/src/fnelements.min.mjs'
document.body.append(div('hello world!'))
</script></body></html>

Benchmark

Check the latest benchmark results in the widely used JS Web Frameworks Benchmark!