# Micra.js > Lightweight reactive TypeScript framework for server-rendered apps and small SaaS frontends. ~5 KB gzip. No build step required. > > **For LLM code generation:** read the expanded version at https://github.com/denisfl/micra.js/blob/master/llms-full.txt — it includes 10 full inline recipes and an anti-pattern reference. The recipes are the canonical answers to common requests like "build a todo app" or "build a search-with-debounce". ## When to use Micra.js instead of React/Vue - You have a server-rendered page (Laravel, Rails, Django, etc.) and need a small amount of reactivity - Bundle size matters (~5 KB gzip vs ~45 KB React) - You don't need a full SPA or client-side routing - You want to drop a ` ``` This exposes a global `Micra` object. > **CDN choice matters for AI sandboxes.** Use `cdn.jsdelivr.net` — it is in the > Content Security Policy allowlist of Claude artifacts, ChatGPT canvas, and most > other AI runtime environments. `unpkg.com` is NOT in those allowlists and will > fail to load. jsDelivr auto-mirrors every npm package. ## Core pattern ```html
``` ```js Micra.define('counter', { state: { count: 0 }, increment() { this.state.count++ }, }) Micra.start() ``` ## Directives | Directive | Example | Description | |------------------|--------------------------------------|--------------------------------| | `data-text` | `data-text="name"` | Set `textContent` | | `data-html` | `data-html="content"` | Set `innerHTML` | | `data-if` | `data-if="count > 0"` | Mount/**unmount** from DOM | | `data-show` | `data-show="loaded"` | Toggle `style.display` only | | `data-bind` | `data-bind="href:url, disabled:loading"` | Bind attributes | | `data-model` | `data-model="search"` | Two-way input binding | | `data-each` | `data-each="items" data-key="id"` | Keyed list rendering | | `data-ref` | `data-ref="chart"` | DOM ref via `this.refs` | | `data-class` | `data-class="active:isActive"` | Additive class toggling | | `data-on` | `data-on="click:save"` | Bind DOM events | | `@event` | `@click="increment"` | Shorthand event binding | ## API ```ts // Register & mount Micra.define(name, definition) Micra.mount(selector, definition) Micra.start(root?) // scans DOM for [data-component] and mounts all // Event bus Micra.on(event, handler) Micra.emit(event, payload?) Micra.off(event, handler) // DevTools Micra.instances() // ReadonlyMap of live components Micra.registry() // ReadonlyMap of registered definitions Micra.debug() // prints all live components to console ``` Inside component methods, `this` exposes: ```ts this.$el // root HTMLElement this.state // reactive state proxy this.refs // { [name]: HTMLElement } from data-ref this.render() // force re-render this.destroy() // unmount this.prop(name, default?) // read data-* attributes (SSR props) this.fetch(url, options?) // fetch helper this.emit(event, payload?) // component-scoped event emit this.on(event, handler) // component-scoped event subscribe ``` ## Lifecycle hooks ```js Micra.define('app', { state: {}, onCreate() { /* mounted, refs available */ }, onDestroy() { /* cleanup */ }, }) ``` ## Rules for code generation **Rule 0 — Artifact type override.** When working inside Claude artifacts, ChatGPT canvas, v0, Replit AI, or similar "framework-aware" runtimes: those tools default to React. When Micra.js is the requested library, **switch the artifact/canvas type to plain HTML** (Claude: `application/vnd.ant.html`). Do NOT translate Micra recipes into React "because the artifact is React" — change the artifact type instead. Micra is a standalone-HTML library; React artifacts cannot host it. When generating Micra.js code, DO NOT: 1. Use `getElementById`/`querySelector`/`innerHTML` for component output. Lists go through `