/fntags

html as functions with user defined state

Primary LanguageJavaScriptMIT LicenseMIT

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.

Check out the documentation to learn more!

f'n examples


Start a new app with one file

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

Make re-usable, customizable components using plain js functions

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

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

Explicit two-way state binding

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

const helloInput = () => {
  const name = fnstate('World')

  const nameInput = input({
    value: name.bindAttr(),
    oninput (){ name(nameInput.value) }
  })

  return div(
    div('Hello ', name.bindAs(), '!'),
    br(),
    nameInput
  )
}

document.body.append(helloInput())

Benchmark

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