Overview

Mates is a closure-based UI framework: components are plain functions (no class, no JSX compiler). An outer setup function runs once on mount; an inner template function re-runs whenever reactive dependencies change.

State is explicit — create an atom, read it with count(), write with count.set(…). Templates use lit-html tagged literals (html`…`) exported from mates. Mount with renderApp.

Start here to scaffold a project and ship your first reactive component. For where you may create atoms and hooks, read the Mental Model, then the Restricted Usage table (SPA vs SSR).

Start a new project

npm create mates

Your first component

One atom, one button. Click Count — the number updates. That’s the whole mental model.

import { html, atom, renderApp } from 'mates';

const Counter = () => {
const count = atom(0);

return () => html`
<h1>${count()}</h1>
<button class="btn-primary" @click=${() => count.set(n => n + 1)}>
Count
</button>
`;
};

renderApp(Counter, document.getElementById('app'));

Reactive input

Bind an input to an atom. Typing updates the greeting — same outer/inner pattern.

import { html, atom, renderApp } from 'mates';

const Greet = () => {
const name = atom('Ada');

return () => html`
<p>Hello, ${name()}!</p>
<input
.value=${name()}
@input=${(e) => name.set(e.target.value)}
placeholder="Your name"
/>
`;
};

renderApp(Greet, document.getElementById('app'));