arrowjs
Tagged templates + reactive data, <img align="top" height="24" src="./img/arrow-jscore.svg">
The UI framework for coding agents
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
Core Package
@arrow-js/core: reactive state, tagged-template rendering, components,pick()/props(), andnextTick()
Framework Packages
@arrow-js/framework: async component runtime,boundary(),render(),toTemplate(), and document rendering helpers@arrow-js/ssr:renderToString()andserializePayload()for server output@arrow-js/hydrate:hydrate()andreadPayload()for adopting SSR output in the browser@arrow-js/sandbox: QuickJS/WASM-backed sandbox runtime for executing Arrow code off the hostwindowrealm while rendering into the real DOM@arrow-js/vite-plugin-arrow: Vite integration package included in the monorepo
Install
Scaffold 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>
Core Example
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, SSR, and Hydration
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/corestays DOM-first and framework-agnostic.@arrow-js/frameworkadds async render tracking and boundaries.@arrow-js/ssrrenders HTML and serializes async payloads on the server.@arrow-js/hydrateadopts existing SSR HTML instead of replacing it on the client.
Editor Support
Install the official ArrowJS Syntax extension for VSCode to get syntax highlighting and autocomplete inside html template literals.
Community
- Discord — ask questions, share what you're building, and connect with other Arrow developers
- GitHub Issues — report bugs and request features
- Follow @jpschroeder on X for updates and releases
Monorepo Development
pnpm dev: run the docs app locallypnpm test: run Vitestpnpm test:e2e: run Playwright testspnpm typecheck: run TypeScript across the workspace