Getting started
Azox compiles .azox files into server-rendered HTML plus a small module that wires up signal bindings in the browser.
Stable. Azox is at v1.2.0. The template syntax, the reactivity exports and the shape of the build output will not change without a 2.0. See limitations for what it deliberately does not do.
Requirements
Node 18 or newer. Nothing else — Azox has no dependencies.
Create a project
npx azoxjs create my-app cd my-app npm install npm run dev
The dev server starts at http://localhost:4321, rebuilds when you save, and reloads the browser.
The npm package is azoxjs, but the command it installs is azox. The short name was already blocked on npm.
What you get
my-app/ ├── package.json ├── pages/ │ ├── index.azox → / │ └── about.azox → /about ├── components/ │ └── Counter.azox └── public/ copied to the build root
There is no configuration file. The folder layout is the configuration: pages become routes, and public/ is copied as-is.
Your first page
A page is markup, with an optional <script> block for state and an optional <head> block for document metadata.
<head>
<title>My app</title>
</head>
<script>
import { signal } from 'azox/reactivity';
const count = signal(0);
</script>
<main>
<h1>Hello</h1>
<button on:click={() => count.set(count() + 1)}>
Clicked {count()} times
</button>
</main>signal(0) creates a reactive value. Reading it as count() inside markup binds that spot in the DOM to it — and only that spot.
Build for production
npm run build
The output lands in .azox/build/:
index.html the / route page.client.js its bindings azox-runtime.js shared by every page about/ ├── index.html the /about route └── page.client.js style.css copied from public/
That directory is a complete static site. Every route is a directory with an index.html, so clean URLs work on any host without rewrite rules. See deployment.
Next
- Reactivity — signals, effects and derived values
- Template syntax — interpolation, events, attributes
- Components — props and slots