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
Merlinbetter 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.