A tiny frontend framework

Build fast web apps with plain JavaScript, HTML, and CSS.

Zoijs is built entirely on the web platform you already know. If you know HTML, CSS, and JavaScript, you already know most of Zoijs — and there are only seven functions to learn.

$ npm create zoijs@latest my-app
import { html, mount, createState } from "@zoijs/core";

function Counter() {
  const count = createState(0);

  return html`
    <button onclick=${() => count.set(count.get() + 1)}>
      Clicked ${() => count.get()} times
    </button>
  `;
}

mount(Counter, "#app");

That's a complete, working app that runs straight in the browser. Updates are fine-grained: only the text node that changed is touched.

Why Zoijs?

Instant start

A <script type="module"> is the whole toolchain. Open an HTML file and you're running.

Real HTML

Write real HTML in tagged template literals — familiar syntax you can read at a glance.

Fine-grained updates

Updates touch the exact node that changed. Cost scales with what changed, not app size.

Tiny API

Seven core functions, learnable in about 30 minutes. Optional packages add the rest.

Secure by default

Text is inert, dangerous URLs are blocked, no eval. CSP- and Trusted-Types-friendly.

Plain web skills

Native events, native CSS, native DOM. The platform you already know.

The ecosystem

The core stays small. Add optional packages only when you need them.

@zoijs/core

The framework: html, mount, state, computeds, lists.

@zoijs/router

A tiny client-side router. Routes are a plain object.

@zoijs/resource

Reading async data: loading / data / error / refresh.

@zoijs/action

Writing async data: pending / error / done for submits.

@zoijs/head

Set the document title and meta description per page.

@zoijs/storage

A persistent createState backed by localStorage.

@zoijs/forms

Native-forms-first state: values, errors, touched, validation.