# aihu — Full Documentation > A zero-dependency Web Components meta-framework. .aihu SFCs compile to vanilla custom elements > with sub-2 kB reactive primitives. Every component is agent-discoverable and callable as an MCP tool. > Source: https://aihu.dev | GitHub: https://github.com/fellwork/aihu --- # Introduction aihu builds **durable Web Components your AI agent can read and drive — not disposable UI it has to generate.** You author `.aihu` Single-File Components (block-structured: `@state`, `@template`, `@style`, `@agent`, `@route`); a Rust compiler emits standards-compliant Web Components **plus** the machine-readable agent manifest. An agent inspects a real component (llms.txt + MCP) and calls its actions on the live, on-screen instance over a server-mediated capability bridge — the component the user sees is the one the agent drives. Most "agent UI" today is the opposite: disposable HTML/JSON the model regenerates each turn (MCP Apps, generated iframes). Durable components are inspectable, reusable, and trusted, with the server holding auth and policy. > **Status:** actively developed and shipping in `v1.0.x` releases. The reactive runtime, compiler, router, server, agent surface, CLI, styling engine, and UI primitives all work today; the `v1.0.0` tag is held for a rich-text/markdown plugin. ## What makes aihu different - **Read and drive, not generate** — an agent inspects a real component and calls its actions on the live, on-screen instance over a server-mediated capability bridge. The component the user sees is the one driven, not disposable UI regenerated each turn (the generative-UI model: MCP Apps, generated iframes). Durable, inspectable, reusable. - **Agent-native by construction** — the `@agent` block on each SFC declares its exposed state and actions; the compiler emits a matching MCP tool schema + llms.txt entry alongside the Web Component. No separate API gateway. `@aihu/agent` and `@aihu-plugin/agent-readiness` are first-class. - **Vanilla custom elements output** — no framework lock-in at the consumer boundary, no global context, no hydration step. - **Sub-2 kB runtime** — `@aihu/signals` (~1.71 kB gz) and `@aihu/arbor` (~2.72 kB gz) together cover signals, computeds, effects, and direct DOM diffing. - **Dep-free** — zero non-`@aihu/*` runtime dependencies across all packages. Every bundle that ships to a browser or edge runtime is self-contained. - **Targeted updates** — aihu uses `nodeValue` rather than `textContent` for reactive text nodes, which is 122× faster on targeted updates. ## Why "meta-framework"? Aihu lets you build whole apps, not just components. `@aihu/signals` (reactive primitive) → `@aihu/arbor` (DOM mounting) → `@aihu/runtime` (custom-element wiring) → `@aihu/router` (file-based routing) → `@aihu/server` (SSR + edge) → `@aihu/app` (the integrated framework). Each layer is usable on its own; stacked they form a complete meta-framework. File-based routing, SSR, loaders, cookies, auth, and data are first-class — not bolt-ons. Cloud adapters are in-tree, not third-party. ## Package overview | Package | Purpose | Bundle | |---------|---------|--------| | `@aihu/signals` | Push-based signals, computeds, effects | 1.71 kB gz | | `@aihu/arbor` | DOM tree primitives: branch/leaf/mount/hydrate | 2.72 kB gz | | `@aihu/runtime` | Custom element registration, onMount/onCleanup lifecycle | 3.27 kB gz | | `@aihu/context` | Async-context-friendly request/SSR context primitives | 248 B gz | | `@aihu/agent` | Agent/MCP registration primitives | 142 B gz | | `@aihu/agent-service` | Server-side agent runtime (live signal bindings) | 1.06 kB gz | | `@aihu/agent-a2a` | A2A (Agent-to-Agent) protocol bindings | 721 B gz | | `@aihu/agent-acp` | ACP (Agent Control Protocol) bindings | 591 B gz | | `@aihu-plugin/agent-readiness` | llms.txt, MCP Server Card, robots.txt emitter | build-time | | `@aihu-plugin/data` | Reactive resource and loader protocol | 774 B gz | | `@aihu/router` | File-based router with Vite plugin | 2.02 kB gz | | `@aihu/server` | Request router, SSR, streaming, loaders, cookies | server-only | | `@aihu/app` | Top-level integration — wires runtime, router, adapters | 764 B gz | | `@aihu/plugin` | Plugin contract types shared by server and meta-framework | build-time | | `@aihu/auth` | JWT scope checks, ScopeSignal, server middleware | server-only | | `@aihu/adapter-cloudflare` | Cloudflare Workers/Pages deployment adapter | build-time | | `@aihu/adapter-vercel` | Vercel deployment adapter (Edge + Serverless) | build-time | | `@aihu/cli` | Scaffold CLI — `aihu app`, `page`, `component`, `dev`, `build` | build-time | | `@aihu/compiler` | Rust SFC compiler — per-platform binary + WASM | build-time | | `@aihu/css-engine` | CSS engine — Tailwind v4 hard fork, WC-native scoped output, `cn()` + style packs | build-time + tiny runtime | | `@aihu/primitives` | Headless WAI-ARIA APG behaviors (dialog, tooltip, button, …) as vanilla custom elements, zero CSS | runtime | | `@aihu/mcp` | MCP server exposing `aihu_example` + `aihu_validate` tools | server-only | | `@aihu/scraping` | Rate limiter and bot-detection middleware for agent services | server-only | | `vscode-aihu` | VSCode syntax highlighting, snippets, language support | editor | --- # Installation ## Prerequisites aihu requires **one** of the following runtimes: - **Bun** ≥1.3.0 (recommended — faster installs, native TypeScript, built-in test runner) - **Node.js** ≥20.18.0 with a package manager of your choice (npm, pnpm, or yarn) ## Scaffold a new application Use the `@aihu/cli` to generate a new project: ```bash # Bun (recommended) bunx @aihu/cli app my-app # Node.js npx @aihu/cli app my-app ``` > **Note (TODO-001):** The ≤5 minute quick start is conditional until pre-built > `aihu-compile` binaries ship. Today the scaffolder builds the Rust SFC compiler > from source on first run, which adds a one-time toolchain step. Once the > [GitHub Actions release workflow](https://github.com/fellwork/aihu/blob/main/.github/workflows/release.yml) > publishes platform binaries, the install becomes a single download and this > note will be removed. The scaffolder generates the following files: ``` my-app/ package.json aihu.config.ts vite.config.ts src/ pages/ index.aihu layouts/ default.aihu ``` - **`package.json`** — workspace manifest with `@aihu/runtime`, `@aihu/signals`, `@aihu/arbor`, `@aihu/router`, `@aihu/server`, and `@aihu/agent` as dependencies, plus Vite and `@aihu/cli` as devDependencies. - **`aihu.config.ts`** — framework config via `defineAihuConfig` (build target, plugins, adapters). - **`vite.config.ts`** — Vite config with `viteRouterIntegration()` and `viteAgentReadinessIntegration()` wired in. - **`src/pages/index.aihu`** — the Hello World SFC with `@state`, `@template`, and `@route` blocks. - **`src/layouts/default.aihu`** — the default layout shell (``). ## Install and run ```bash cd my-app bun install bun run dev ``` The dev server starts at `http://localhost:5173` with HMR enabled. Edit `src/pages/index.aihu` and the browser updates automatically — no full reload needed. ## Build for production ```bash bun run build bun run preview ``` `bun run build` compiles all `.aihu` files through the Rust SFC compiler, bundles with Vite/Rolldown, and validates against the size budgets defined in `.size-limit.json`. `bun run preview` serves the production build locally so you can verify the output before deploying. --- # Getting Started ## Hello World walkthrough After scaffolding (see [Installation](installation.md)), open `src/pages/index.aihu`. The scaffolded template uses the v2 macro vocabulary: ``` @state { $prop: { name: { default: 'world', type: 'string' } } } @template {
Hello {name}
} @route { path: / name: home } ``` ### The `@state` block `@state` declares the reactive state for the component using the v2 collection-form macro vocabulary. Each macro keyword takes an object whose keys are entry names. **Props** — declared with `$prop`. Every entry must have at least a `default` or `type` key: ``` @state { $prop: { name: { default: 'world', type: 'string' } } } ``` Props are reactive and can be set from outside the component as HTML attributes. Add `expose: { read: true, write: true }` to expose a prop to the agent surface. **Computed values** — declared with `$computed`. The bare form uses a thunk: ``` @state { $prop: { name: { default: 'world', type: 'string' } } $computed: { greeting: () => `Hello, ${name()}!` } } ``` **Actions** — declared with `$action`. Bare form is a handler function; the wrapped form adds `describe` and `expose` metadata: ``` @state { import { signal } from '@aihu/signals' const [count, setCount] = signal(0) $action: { increment: { describe: 'Add 1 to the counter', expose: { read: true, write: true }, handler: () => setCount(count() + 1), }, } } ``` **Effects** — anonymous effects use the bare function form: ``` @state { $effect: () => { console.log('count changed') } } ``` Named effects (with optional dependency pinning) use the collection form: ``` @state { $effect: { logCount: () => { console.log(count()) }, } } ``` ### The `@template` block `@template` defines the component's DOM structure using aihu's template DSL: - `{expr}` — interpolates a reactive expression. Updates use `nodeValue` for 122× faster targeted writes. - `$href={expr}` — binds an HTML attribute reactively (`$`-prefixed curly; one per attribute). - `$on.click="handler"` — attaches an event listener. - `$show` — toggles visibility based on a boolean signal. - `$each` — renders a list of items. > **Amendment 04 (v1.0.8).** Reactive HTML attribute bindings must be `$`-prefixed (`$class={…}`, `$href={…}`). Plain-curly attributes (`class={…}`, error **C306**), the colon-form event/bind aliases (**C305**), and the Vue-shape `:attr=` alias (**C304**) are hard parse errors in v1.0. HTML-tag SFC framing (`