const model = new Model({ count : 0 });
const Counter = Component.create`
<div>
<div>Counter: ${() => model.count}</div>
<button onClick=${() => model.count++}>Increment</button>
<button onClick=${() => model.count--}>Decrement</button>
</div>
`;
Counter.mount({ model }, document.body);
Build dynamic UI components using intuitive template literals.
Simplify event handling with built-in delegation.
Keep your UI and data in sync with ease.
Render as plain text for server-side use or static builds.
Minimal overhead with efficient rendering.
Seamlessly integrates into existing Backbone.js legacy projects.
Built on modern web standards, no tooling required.
$ npm install rasti
import { Model, Component } from 'rasti';
import { Model, Component } from 'https://esm.run/rasti';
Include Rasti directly in your HTML using a CDN. Available UMD builds:
<script src="https://cdn.jsdelivr.net/npm/rasti"></script>
The UMD build exposes the Rasti global object:
const { Model, Component } = Rasti;
Component// Define a Timer component that displays the number of seconds from the model.
const Timer = Component.create`
<div>
Seconds: <span>${({ model }) => model.seconds}</span>
</div>
`;
// Create a model to store the seconds.
const model = new Model({ seconds : 0 });
// Mount the Timer component to the body and pass the model as an option.
Timer.mount({ model }, document.body);
// Increment the `seconds` property of the model every second.
// Only the text node inside the <span> gets updated on each render.
setInterval(() => model.seconds++, 1000);
// Define the routes for the navigation menu.
const routes = [
{ label : 'Home', href : '#' },
{ label : 'Faq', href : '#faq' },
{ label : 'Contact', href : '#contact' },
];
// Create a Link component for navigation items.
const Link = Component.create`
<a href="${({ props }) => props.href}">
${({ props }) => props.renderChildren()}
</a>
`;
// Create a Navigation component that renders Link components for each route.
const Navigation = Component.create`
<nav>
${({ props, partial }) => props.routes.map(
({ label, href }) => partial`<${Link} href="${href}">${label}</${Link}>`
)}
</nav>
`;
// Create a Main component that includes the Navigation and displays the current route's label as the title.
const Main = Component.create`
<main>
<${Navigation} routes="${({ props }) => props.routes}" />
<section>
<h1>
${({ model, props }) => props.routes.find(
({ href }) => href === (model.location || '#')
).label}
</h1>
</section>
</main>
`;
// Initialize a model to store the current location.
const model = new Model({ location : document.location.hash });
// Update the model's location state when the browser's history changes.
window.addEventListener('popstate', () => model.location = document.location.hash);
// Mount the Main component to the body, passing the routes and model as options.
Main.mount({ routes, model }, document.body);
// Create a model to store the counter value.
const model = new Model({ count : 0 });
// Create a Counter component with increment and decrement buttons.
const Counter = Component.create`
<div>
<div>Counter: ${({ model }) => model.count}</div>
<button onClick=${function() { this.model.count++; }}>Increment</button>
<button onClick=${function() { this.model.count--; }}>Decrement</button>
</div>
`;
// Mount the Counter component to the body and pass the model as an option.
Counter.mount({ model }, document.body);
// Event listeners are bound to 'this' and use delegation from the root element.
// When buttons are clicked, only the text node gets updated, not the entire component.
Rasti is built for developers who want a simple yet powerful way to create UI components without the complexity of heavy frameworks. Whether you're building a high-performance dashboard, or embedding a lightweight widget, Rasti lets you:
You can find a sample TODO application in the example folder of the Rasti GitHub repository. This example serves as a great starting point for your own projects. Try it live here.
For detailed information on how to use Rasti, refer to the API documentation.
For those working with LLMs, there is an AI Agents reference guide that provides API patterns, lifecycle methods, and best practices, optimized for LLM context. You can share this guide with AI assistants to help them understand Rasti's architecture and component APIs.
We strive to minimize breaking changes between major versions. However, if you're migrating between major versions, please refer to the release notes below for details on any breaking changes and migration tips.