Type to search the documentation.
A web framework built from scratch. No Virtual DOM, no diffing, no runtime dependencies. Every binding compiles to a signal that writes to exactly one DOM node.
0
dependencies
2.2 KB
runtime, gzipped
414
tests passing
MIT
licence
01 — Live
The counter below is a real Azox page, compiled with the same compiler you install. Clicking updates one text node — nothing else on this page is touched.
No Virtual DOM was consulted. The effect bound to that number is the only thing that ran.
<script>
import { signal } from 'azox/reactivity';
const count = signal(0);
</script>
<span class="readout">{count()}</span>
<button on:click={() => count.set(count() + 1)}>
Add one
</button>02 — Comparison
Most frameworks re-run your component and compare the result. Azox compiles the comparison away entirely.
function Counter() {
const [n, setN] = useState(0);
// This whole function runs again on
// every click. React then compares
// the returned tree with the last one
// to work out what changed.
return (
<button onClick={() => setN(n + 1)}>
Count: {n}
</button>
);
}<script>
import { signal } from 'azox/reactivity';
const n = signal(0);
</script>
<!-- Compiles to one effect holding a
reference to one text node. On a
click, that node is assigned to.
Nothing is re-run or compared. -->
<button on:click={() => n.set(n() + 1)}>
Count: {n()}
</button>Read why this matters for the reasoning, or the reactivity docs for the mechanics.
03 — Design
Six decisions that shape everything else about the framework.
Each binding becomes its own effect, holding a direct reference to the text node or attribute it owns. A signal change writes to that node and stops.
A component is inlined into its caller. There is no component instance at runtime, no lifecycle, and nothing to reconcile — the output matches hand-written markup.
The CLI, the compiler and the runtime are plain JavaScript against the standard library. Nothing is pulled in behind your back.
.azox files are HTML with {expr} interpolation and on:event bindings. Not JSX, and no template DSL to memorise.
Every page ships real HTML. The client module then wires up the bindings on top of it, so content is there before JavaScript runs.
A build is plain HTML, JS and assets with clean URLs. It works on any static host with no rewrite rules or adapters.
04 — Structure
The file layout is the routing table, and there is no configuration file to learn.
my-app/
├── pages/
│ ├── index.azox → /
│ ├── about.azox → /about
│ └── blog/
│ ├── index.azox → /blog
│ └── first.azox → /blog/first
├── components/
│ └── Card.azox
└── public/
└── style.css → /style.css<script>
const { title, body } = props();
</script>
<article class="card">
<h2>{title}</h2>
<p>{body}</p>
</article>05 — Next
A step-by-step walkthrough: from an empty directory to a deployed site, explaining each decision as it comes up.
Start the tutorial →Complete, working sites — a landing page, a portfolio, a blog and a dashboard. Copy the files, or download the whole thing.
Browse templates →The real compiler, running client-side. Edit a page and watch both the output and the generated JavaScript change.
Open the playground →Reactivity, template syntax, components, routing, the CLI, and an honest page about what Azox deliberately does not do.
Read the docs →