<script src="https://cdn.no-js.dev/"></script>When using the CDN
<script>tag, initialization is handled automatically onDOMContentLoaded.
Download dist/iife/no.js and include it with a <script> tag.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.no-js.dev/"></script>
</head>
<body base="https://jsonplaceholder.typicode.com">
<div get="/users/1" as="user">
<h1 bind="user.name">Loading...</h1>
<p bind="user.email"></p>
</div>
</body>
</html>That's it. No app.mount(). No createApp(). No NgModule. It just works.
- Parse — On
DOMContentLoaded, No.JS walks the DOM looking for elements with known attributes. - Resolve — Each attribute maps to a directive that is executed by priority (data fetching first, then conditionals, then rendering).
- React — All data lives in reactive contexts (Proxy-backed). When data changes, every bound element updates automatically.
- Scope — Contexts inherit from parent elements, like lexical scoping. A
bindinside aneachloop can access both the loop item and ancestor data.
Every element can have a context — a reactive data object. Contexts are created by state, get, store, etc. Child elements inherit their parent's context automatically.
body → context: { baseUrl }
div[get] → context: { user: { name, email } } ← inherits from body
span[bind="user.name"] ← reads from div's context
div[each] → context: { post: { title } } ← inherits from div (can access user + post)
Directives run in a defined order:
| Priority | Directives | Description |
|---|---|---|
| 0 | state, store |
Initialize local/global state |
| 1 | get, post, put, patch, delete |
Fetch data |
| 5 | route |
SPA routing |
| 10 | if, switch, each, foreach |
Structural (add/remove DOM) |
| 20 | bind, class-*, style-*, show, hide |
Rendering (update existing DOM) |
| 20 | on:* |
Event binding |
| 30 | validate, animate |
Side effects |
Most directive values accept JavaScript expressions evaluated against the current context:
<!-- Simple path -->
<span bind="user.name"></span>
<!-- Ternary -->
<span bind="user.age >= 18 ? 'Adult' : 'Minor'"></span>
<!-- Arithmetic -->
<span bind="cart.total * 1.1"></span>
<!-- Filters (pipes) -->
<span bind="user.name | uppercase"></span>
<!-- Template literals (bind-html) -->
<div bind-html="`<strong>${user.name}</strong>`"></div>Next: Data Fetching →