Mutable State
Mutate state directly through setters. No reducers, no dispatch.
Open Source
The JavaScript Framework for the Future
A lightweight, TypeScript-first framework with mutable state and blazing-fast DOM updates. No virtual DOM. No compiler. No JSX. 2× faster and 4× smaller than React, Built to handle Large Scale Applications
Measured, not claimed — see the benchmarks →npm install mates
Mutate state directly through setters. No reducers, no dispatch.
Trackable function utilities. Async, sync, cached, interceptable.
html`…` templates from mates. No JSX, no compiler, just JavaScript.
Reactive event bus. Send messages anywhere within the app.
Outer function runs once. Set up state, hooks, and logic cleanly.
Features
Everything you need to build production apps — nothing you don't
Templates patch only the parts of the DOM that changed. Updates are surgical, not diffed from scratch. Much faster than React.
Outer function runs once (setup). Inner function runs every render. Clear separation between initialization and reactivity.
No immutability gymnastics. Mutate state through setters or atom.set() and your views update automatically.
Just tagged template literals — html, svg, directives, and more all export from mates. No separate lit-html install. Works in any TypeScript project out of the box.
Every API is fully typed from the ground up. Amazing autocomplete, type inference, and compile-time error checking.
Share state between parent and child components without prop drilling. Like React Context, but with plain classes and zero boilerplate.
Track functions, intercept them, subscribe to results, handle loading/error states. Built-in async actions, task queues, and parallel task managers.
onMount, onPaint, onCleanup, onAllMount, onError — intuitive hooks that run at the right time. No dependency arrays to manage.
One install covers the runtime and the batteries below. Optional packages (mates-virtual, mates-db, mates-ui) stay out of the core until you need them.
DX
Familiar syntax without JSX and immutable state. Just pure JavaScript template strings as HTML.
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() =>
setCount(count + 1)
}>
Increment
</button>
</div>
);
}
function Counter() {
const count = atom(0);
return () => html`
<div>
<h1>Count: ${count()}</h1>
<button @click=${() =>
count.set(count() + 1)
}>
Increment
</button>
</div>
`;
};
Compare
Smaller ship size — and faster paints on a 100,000-item full DOM list. Toggle, add, and delete timed to the next frame.
mates is ~4.8× smaller (44 KB vs 210 KB)
Verify: Run mates bench · Run React bench · All frameworks
Bundle size
mates-ui is ~1.08× lighter (156 KB vs 168 KB)
Features
mates-ui has more features than core MUI (29 vs 21; icons and charts excluded)
Sizes: @mui/material full import (~168 KB gzip, no @mui/icons-material); mates-ui production bundle with mates-icons contribution removed (~156 KB gzip). Features: high-level capability areas in each core package (icons and charts excluded). mates-ui ~29 vs @mui/material ~21 — date/time pickers, data grid, tree, chat, media, and similar live in mates-ui itself; MUI ships many of those only in MUI X. Raw component export counts are omitted because compound sub-parts and variants make them misleading.
Mean of two dual-round production runs. Mates uses guard on keyed `repeat` rows. Mates (raw components) uses `xRaw` + cloneNode rows.
| Operation | React | mates | Mates (raw) | Ratio |
|---|---|---|---|---|
| Load | 16,557 ms | 2,676 ms | 1,605 ms | 10.3× |
| Toggle | 351 ms | 152 ms | 103 ms | 3.4× |
| Add | 417 ms | 255 ms | 175 ms | 2.4× |
| Delete | 517 ms | 342 ms | 235 ms | 2.2× |
Bench: todo-100k-bench — production builds, full DOM list (no virtualization), Chrome. Time = state update → 2× requestAnimationFrame and DOM verification (data-todo-id probes). Times are means of two dual-round runs (load + 5× toggle/add/delete each), rounded. Mates uses repeat() keyed by id and guard() so unchanged row objects skip rebuilding. Mates (raw components) mounts an xRaw shell and patches rows with cloneNode (no repeat, no scheduler). React re-renders the list. Solid, Vue 3, and Angular 19.2 are on the Benchmarks page. Real apps at this scale usually virtualize.
Included
Router, networking, dates, animations, and more ship in mates — about 44KB gzip for the whole toolkit. Add-ons stay optional.
SPA routing with params, query/hash atoms, scroll restoration, and animatedRouter for enter/exit transitions.
Typed HTTP helpers (Get/Post/Put/Patch/Delete), CSRF, interceptors, SSE streams, and wire-friendly error handling.
Locale-aware calendars, timezones, formatting, and date math — no extra date library required.
Keyframe presets, animateSwap, and animatedIf / animatedX for view transitions without a separate motion stack.
stylesheet, themes, keyframes, and SSR-friendly style collection when you want styles next to components.
portal, popup, and dialog helpers with placement math for menus, modals, and floating UI.
First-party ws() helper for realtime connections with status tracking.
formAtom plus validators (required, email, min/max, patterns) wired into reactive state.
Sync localStorage and sessionStorage into reactive atoms with LSAtom and SSAtom — including cross-tab updates.
action / asyncAction with interceptors, caching, polling, pagination helpers, and task queues.
onMount, onPaint, onCleanup, plus window/scroll/visibility/keyboard helpers for app-level wiring.
Need virtual lists, IndexedDB, or document SSR? Reach for
mates-virtual, mates-db, and
mates-fullstack — installed only when you use them.
Documentation
Every feature, hook, and utility — all in one place.
Browse the docs →Try it live
A full in-browser playground powered by mates-ide. Change the counter, tweak styles, or rewrite the whole app.
Open full playground →Get started
Get started with Mates in under a minute.
npx create-mates my-app