# No.JS Complete Documentation > No.JS is an HTML-first reactive framework for building dynamic web applications using only HTML attributes. ~24 KB gzipped, zero dependencies, no build step, no virtual DOM, CSP-compliant. Include one script tag and start writing directives. No.JS replaces JavaScript framework boilerplate with declarative HTML attributes. Directives like `get`, `bind`, `state`, `each`, `if`, and `on:click` handle data fetching, rendering, state management, and interactivity — all without writing JavaScript. Data lives in reactive contexts (Proxy-backed) that inherit through the DOM like lexical scoping. Directives execute by priority: state (0) → HTTP/error-boundary (1) → computed/watch (2) → ref (5) → structural (10) → rendering/events (20) → validation (30). ## Getting Started - [Installation & Quick Start](#getting-started) — CDN, npm, and your first page ## Core Guides - [Data Fetching](#data-fetching) — `get`, `post`, `put`, `patch`, `delete`, base URL, caching - [Data Binding](#data-binding) — `bind`, `bind-html`, `bind-*`, `model` - [Conditionals](#conditionals) — `if`, `else-if`, `show`, `hide`, `switch`/`case` - [Loops](#loops) — `each`, `foreach`, loop variables, nesting - [Templates](#templates) — Reusable fragments, slots, remote templates - [State Management](#state-management) — `state`, `store`, `into`, `computed`, `watch`, persistence ## Interaction - [Events](#events) — `on:*`, modifiers, lifecycle hooks, `$event`, `$el` - [Forms & Validation](#forms--validation) — `validate`, `$form`, custom validators - [Actions & Refs](#actions--refs) — `call`, `trigger`, `ref`, `$refs` ## Presentation - [Dynamic Styling](#dynamic-styling) — `class-*`, `class-map`, `style-*`, `style-map` - [Animations](#animations--transitions) — `animate`, `transition`, stagger, built-in names - [Filters & Pipes](#filters--pipes) — Built-in filters, chaining, custom filters ## Advanced - [Routing](#routing--spa-navigation) — SPA navigation, params, guards, nested routes - [Internationalization](#internationalization-i18n) — `t`, pluralization, locale switching - [Custom Directives](#custom-directives) — Extend No.JS with your own directives - [Error Handling](#error-handling) — Per-element errors, boundaries, global handler - [Configuration](#configuration--security) — Global settings, interceptors, CSRF, security - [Drag and Drop](#drag-and-drop) — `drag`, `drop`, sortable lists, multi-select ## Reference - [Directive Cheatsheet](#directive-cheatsheet) — Every directive at a glance - [Full SPA Example](#examples) — Complete app with routing, auth, i18n & more - [Playground](#playground) — Interactive code editor # Getting Started ## Installation ### CDN (recommended) ```html ``` > When using the CDN `

Loading...

``` That's it. No `app.mount()`. No `createApp()`. No `NgModule`. It just works. ## How It Works 1. **Parse** — On `DOMContentLoaded`, No.JS walks the DOM looking for elements with known attributes. 2. **Resolve** — Each attribute maps to a **directive** that is executed by priority (data fetching first, then conditionals, then rendering). 3. **React** — All data lives in **reactive contexts** (Proxy-backed). When data changes, every bound element updates automatically. 4. **Scope** — Contexts inherit from parent elements, like lexical scoping. A `bind` inside an `each` loop can access both the loop item and ancestor data. ## Core Concepts ### Reactive Context 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) ``` ### Directive Priority Directives run in a defined order: | Priority | Directives | Description | |----------|-----------|-------------| | 0 | `state`, `store` | Initialize local/global state | | 1 | `get`, `post`, `put`, `patch`, `delete`, `error-boundary`, `i18n-ns` | Fetch data and error/i18n setup | | 2 | `computed`, `watch` | Derive values and observe changes | | 5 | `ref` | Element references | | 10 | `if`, `else-if`, `else`, `switch`, `each`, `foreach`, `use`, `drag-list` | Structural (add/remove DOM) | | 15 | `drag`, `drop` | Drag and drop setup | | 16 | `drag-multiple` | Multi-select drag | | 20 | `bind`, `bind-*`, `bind-html`, `model`, `class-*`, `style-*`, `on:*`, `show`, `hide`, `t`, `call`, `trigger` | Rendering, events, i18n, actions | | 30 | `validate` | Form validation side effects | ### Expression Syntax Most directive values accept **JavaScript expressions** evaluated against the current context: ```html
``` # Data Fetching No.JS makes HTTP requests declarative — just add attributes to HTML elements. ## Base URL Set once on any ancestor element. All descendant `get`, `post`, etc. resolve relative URLs against it. ```html
...
...
``` Override for specific sections: ```html
...
``` Absolute URLs skip base resolution: ```html
...
``` ### Programmatic Configuration ```html ``` ### Per-Request Headers ```html
``` ## `get` — Fetch and Render Data ```html
``` ### Attributes | Attribute | Type | Description | |-----------|------|-------------| | `get` | `string` | URL to fetch (GET request) | | `as` | `string` | Name to assign the response in the context. Default: `"data"` | | `loading` | `string` | Template ID to show while loading (e.g. `"#skeleton"`) | | `error` | `string` | Template ID to show on fetch error (e.g. `"#errorTpl"`) | | `empty` | `string` | Template ID to show when response is empty array/null | | `refresh` | `number` | Auto-refresh interval in ms (polling) | | `cached` | `boolean\|string` | Cache responses. `cached` = memory, `cached="local"` = localStorage, `cached="session"` = sessionStorage | | `into` | `string` | Write response to a named global store | | `debounce` | `number` | Debounce in ms (useful with reactive URLs) | | `headers` | `string` | JSON string of additional headers | | `params` | `string` | Expression that resolves to query params object | | `retry` | `number` | Override global retry count for this request | | `retry-delay` | `number` | Override global retry delay in ms (default: 1000) | ### Full Example ```html
``` ### Reactive URLs URLs that reference state variables re-fetch automatically when those values change: ```html
...
``` ## `post`, `put`, `patch`, `delete` — Mutating Requests Used on forms or triggered via `call`. > **Tip:** The `call` directive now supports the same attributes as form-based HTTP directives — including `loading`, `headers`, `redirect`, and `body`. See [Actions & Refs → `call`](#call--trigger-api-requests-from-any-element) for full details. ### Form Submission ```html
``` ### PUT / PATCH / DELETE ```html
...
``` ### Mutation Attributes | Attribute | Description | |-----------|-------------| | `post`, `put`, `patch`, `delete` | URL for the request | | `body` | Request body (JSON string with interpolation). For forms, auto-serializes fields | | `success` | Template ID to render on success. Receives response as `var` | | `error` | Template ID to render on error. Receives error as `var` | | `loading` | Template ID to show during request | | `confirm` | Show browser `confirm()` dialog before sending | | `redirect` | URL to navigate to on success (SPA route) | | `then` | Expression to execute on success (e.g. `"users.push(result)"`) | | `into` | Write response to a named global store | | `cached` | Cache responses (memory/local/session) | ### Request Lifecycle ``` [idle] → [loading] → [success | error] ↓ ↓ render tpl render tpl exec `then` log to console `redirect` ``` # Data Binding ## `bind` — Text Content Replaces the element's `textContent` with the evaluated expression. ```html ``` ## `bind-html` — Inner HTML Renders evaluated expression as HTML. Sanitized by default. ```html
``` > ⚠️ Uses DOMPurify-compatible sanitization to prevent XSS. ## `bind-*` — Attribute Binding Bind any HTML attribute dynamically. ```html Profile
``` ## `model` — Two-Way Binding For form inputs, `model` creates automatic two-way data binding: ```html

Hello, . You are .

``` # Conditionals ## `if` / `then` / `else` Renders one of two templates based on a condition. ```html

Welcome back!

``` ## `else-if` — Chained Conditionals ```html
``` ## `show` / `hide` Toggles `display: none` without adding/removing DOM elements. Better for frequently toggled elements. ```html
Welcome!
Please log in.
``` ### `if` vs `show` | | `if` | `show` | |--|------|--------| | Mechanism | Adds/removes DOM elements | Toggles CSS `display` | | Best for | Rarely toggled content | Frequently toggled content | | Preserves state | No (re-creates) | Yes | ## Switch / Case Render one of many templates based on a value. ```html
``` ### Inline Content (no templates) ```html
⏳ Pending 📦 Shipped ✅ Delivered ❌ Cancelled Unknown
``` ### Multi-Value Case ```html
``` # Loops ## `each` — Iterate Over Arrays ```html
``` ## `foreach` — Extended Loop Offers more control with filtering, sorting, pagination, and custom variable names. ```html ``` ### Attributes | Attribute | Description | |-----------|-------------| | `foreach` | Variable name for current item | | `from` | Source array from context | | `index` | Variable name for the index (default: `$index`) | | `key` | Unique key expression for DOM diffing | | `else` | Template ID to render when array is empty | | `filter` | Expression to filter items (like `Array.filter`) | | `sort` | Property path to sort by (prefix with `-` for descending) | | `limit` | Maximum number of items to render | | `offset` | Number of items to skip | ## Loop Context Variables Inside any loop, these variables are automatically available: | Variable | Description | |----------|-------------| | `$index` | Current index (0-based) | | `$count` | Total number of items | | `$first` | `true` if first item | | `$last` | `true` if last item | | `$even` | `true` if index is even | | `$odd` | `true` if index is odd | ```html
``` ## Nested Loops Child loops can access parent scope variables: ```html
``` # Templates Templates are reusable HTML fragments that are never rendered directly. They are cloned when referenced by directives like `then`, `else`, `template`, `loading`, `error`, etc. ## Basic Template ```html ``` ## Template Variables (`var`) Templates can declare which variable they expect from the calling context: ```html
...
``` ## Template Slots Allow templates to accept projected content: ```html
My Title

Main content goes here

Footer info
``` ## Remote Templates (`src`) Load templates from external HTML files: ```html ``` ### Recursive Loading Remote templates are loaded **recursively** — if a remote template itself contains `