A functional JS framework that values elegance, simplicity and minimalism.
State Management + vDom + Template Engine + SPA Router = ❤️
- No building tools.
- Single HTML file by default.
- Built by combining ideas from small modules following the UNIX philosophy.
- Pure functional ELM architecture state management library.
- Ultrafast vDom.
- Server side rendered by default (templates are valid html).
- Built-in Single Page Application Router.
- Ridiculously small API. After reading this file you will understand
Merlin
better than me.
<!DOCTYPE html>
<html>
<head>
<title>Todo - The Merlin JS framework</title>
</head>
<body>
<main>
<h1>To do list</h1>
<input type="text" value:="value" oninput:="NewValue">
<ul>
<li each:="todos" text:></li>
</ul>
<button onclick:="AddTodo">New!</button>
</main>
<script type="module">
import {app} from "https://cdn.jsdelivr.net/gh/marcodpt/merlin/index.min.js"
app({
node: document.body.querySelector('main'),
init: {
value: '',
todos: []
},
register: update => ({
NewValue: ev => update(state => ({
...state,
value: ev.target.value
})),
AddTodo: () => update(({todos, value}) => ({
todos: todos.concat(value),
value: ''
}))
}),
view: (state, events) => ({
...state,
...events
})
})
</script>
</body>
</html>
Merlin
uses Tint as its template engine,
you should read the docs
for a complete reference.
Where to mount the app
.
An optional template
to render, if nothing is passed the node
itself will
be used.
Exactly as defined in Ring.
The only exception is that it returns data
that will be used for
Tint to render the page,
if not passed the unmodified state
will be returned to
Tint.
Exactly as defined in Ring.
The initial state
of the app
. It can be any type of data.
Exactly as defined in Ring.
It is called before initializing the app
returning the registered
events
.
Exactly as defined in Ring.
Returns a function that stops
the app
.
Where to mount the spa
.
Exactly as defined in Wand.
Accepts *
to match any path and :param
to declare variable.
A template to be rendered on the route, if nothing is passed it will use the
original content of the node
.
An optional function that will be called every time the route is started,
returning the initial state. If not passed, Params
from routeData
will be
used as the initial state
.
Exactly as defined in app
Exactly as defined in Wand.
An optional array of plugins
, which are executed sequentially with each
route
change
and which can modify the routeData
.
Exactly as defined in Wand.
Returns a function that stops the spa
.
Exactly as defined in Wand.
Plugins
can introduce new properties or change existing ones.
The url
as it was passed.
The route
that matched as declared.
The part of the url
before the ?
.
Object containing the variables declared in the route
with the associated
values in the current path
.
The part of url
after the ?
.
Parsed query string.
It's a very simple project. Any contribution, any feedback is greatly appreciated.
If this project was useful to you, consider giving it a star on github, it's a way to increase evidence and attract more contributors.
This work is hugely influenced by these amazing projects:
A huge thank you to all the people who contributed to these projects.