
ArrowJS is a tiny, blazing-fast, type-safe reactive UI runtime built around platform primitives that coding agents deeply understand: JavaScript modules, template literals, and the DOM.
Use @arrow-js/core when you want direct reactive DOM updates with minimal API surface. Add @arrow-js/framework, @arrow-js/ssr, and @arrow-js/hydrate when you need async components, server-side rendering, and client-side hydration on top of the same component model.
Documentation · API Reference · Playground · Discord
@arrow-js/core: reactive state, tagged-template rendering, components, pick() / props(), and nextTick()@arrow-js/framework: async component runtime, boundary(), render(), toTemplate(), and document rendering helpers@arrow-js/ssr: renderToString() and serializePayload() for server output@arrow-js/hydrate: hydrate() and readPayload() for adopting SSR output in the browser@arrow-js/sandbox: QuickJS/WASM-backed sandbox runtime for executing Arrow code off the host window realm while rendering into the real DOM@arrow-js/vite-plugin-arrow: Vite integration package included in the monorepoScaffold a complete Vite 8 Arrow app with SSR, hydration, and the full framework stack:
pnpm create arrow-js@latest arrow-app
Agent skill: Equip your preferred coding agent to add Arrow to an existing project:
npx @arrow-js/skill
Core-only:
npm install @arrow-js/core
Full SSR + hydration stack:
pnpm add @arrow-js/core @arrow-js/framework @arrow-js/ssr @arrow-js/hydrate
No build step is required for the core runtime. You can also import it directly in the browser:
<script type="module">
import { html, reactive } from 'https://esm.sh/@arrow-js/core'
</script>
import { component, html, reactive } from '@arrow-js/core'
const Counter = component(() => {
const state = reactive({ count: 0 })
return html`<button @click="${() => state.count++}">
Clicked ${() => state.count} times
</button>`
})
html`${Counter()}`(document.body)
Async components use the same component() API, but they require the async runtime from @arrow-js/framework, @arrow-js/ssr, or @arrow-js/hydrate to be imported before rendering.
The current project structure keeps that layering explicit:
@arrow-js/core stays DOM-first and framework-agnostic.@arrow-js/framework adds async render tracking and boundaries.@arrow-js/ssr renders HTML and serializes async payloads on the server.@arrow-js/hydrate adopts existing SSR HTML instead of replacing it on the client.Install the official ArrowJS Syntax extension for VSCode to get syntax highlighting and autocomplete inside html template literals.
pnpm dev: run the docs app locallypnpm test: run Vitestpnpm test:e2e: run Playwright testspnpm typecheck: run TypeScript across the workspace$ claude mcp add arrow-js \
-- python -m otcore.mcp_server <graph>