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!
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())
Check the latest benchmark results in the widely used JS Web Frameworks Benchmark!