The goal of the project was to institute a easy way to build webapps.
Data-driven web framework for tiny webapps.
Lucia aims to
Lucia is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Lucia shifts that work into a compile step that happens when you build your app.
Instead of using techniques like virtual DOM diffing, Lucia writes code that surgically updates the DOM when the state of your app changes.
- Declarative: Lucia makes it painless to create interactive UIs. Declarative views make your code more predictable, simpler to understand, and easier to debug.
- Reactive: When a data point is changed, the loose Virtual DOM will react and will update and render the points in realtime.
- Data-Driven: Instead of using traditional direct DOM manipulation, Lucia provides an interface to change data to mutate our loose Virtual DOM.
- Lightweight:
- Directive-based
Installation
Put this within your <head>
tags in html.
<script src="https://unpkg.com/lucia/dist/lucia.js"></script>
<script src="https://unpkg.com/lucia"></script>
Example
Below is an example of a clicker game in Lucia.
<div id="app">
<button *on:click="increment()" *html="count"></button>
</div>
const ClickerGame = {
count: localStorage.count || 0,
increment() {
localStorage.count = ++this.count;
},
};
Lucia.createApp(ClickerGame).mount('#app');
Features
Declarative Rendering
At the core of Lucia is a system that enables us to declaratively render data to the DOM using the straightforward *html
directive:
<div id="app">
<p *html="message"></p>
<p *html="message === 'Hello World!'"></p>
</div>
Lucia.createApp({
message: 'Hello World!',
}).mount('#app');
Conditionals
It’s easy to toggle the presence of an element, too:
<div id="app">
<button *if="!show">You can't see me</button>
<button *if="show">You can see me</button>
</div>
Lucia.createApp({
show: true,
}).mount('#app');
Event Handlers
To let users interact with your app, we can use the *on
directive to attach event listeners that invoke methods on our Lucia instances:
<div id="app">
<button *on:click="announce()" *html="message"></button>
</div>
Lucia.createApp({
message: 'Hello world!',
announce() {
alert(this.message);
},
}).mount('#app');
Attribute Binding
In addition to text interpolation, we can also bind element attributes like this:
<div id="app">
<h1 *bind:class="{ hello: show }">Classes are cool</h1>
<h1 *bind:style="color">Styles are sassy</h1>
</div>
Lucia.createApp({
show: true,
color: { color: 'purple' },
}).mount('#app');
List Rendering
We can use the *join
directive to render a list of items based on an array.
<div id="app">
<p *join="fruits by , "></p>
</div>
Lucia.createApp({
fruits: ['apple', 'orange', 'banana'],
}).mount('#app');
Form Input Bindings
You can use the *model
directive to create two-way data bindings on form input, textarea, and select elements.
<div id="app">
<input *model="message" />
<p *html="message"></p>
</div>
Lucia.createApp({
message: 'Nothing submitted yet',
}).mount('#app');
Mounted Callback
You can apply the callback to the mount method to read data values.
<div id="app">
<h1 *html="message"></h1>
</div>
Lucia.createApp({
message: 'Hello World',
}).mount('#app', ({ message }) => {
console.log(message);
});
License
Lucia is MIT licensed.