# WebJs > An AI-first, web-components-first full-stack web framework with no build step. Pages are server-rendered and progressively enhanced; components are native custom elements that hydrate as islands. Server actions give typed client-to-server RPC. Runs on Node 24+ or Bun. WebJs is inspired by Next.js, Lit, and Rails, but ships its own no-build runtime: TypeScript is stripped at load, ES modules are served directly, and the view layer is web components rather than React. Its own source ships uncompiled in node_modules, so a coding agent opens the file it is calling at the version installed, rather than recalling an API from training data. It works with any assistant through one cross-agent contract, and scaffolds a production-shaped app from the first command. Key facts: - Agent-agnostic: a single cross-agent `AGENTS.md` contract drives Claude, Cursor, Copilot, Gemini, and others, not one vendor's assistant. - Needs no training data: WebJs is no-build and self-contained (no Lit or other view-library dependency), so its own readable source, plain JS with JSDoc under `node_modules/@webjsdev`, is what runs and is the context a model reads directly. The `.agents/skills/webjs` skill and a richly commented scaffold layer on curated context. The API is Lit-like for familiarity, but ships its own implementation and differs in places, which does not matter because the source is the context. - Production-shaped from the first file: `webjs create` scaffolds a real database (never JSON files or localStorage), a neutral design-system palette with tokens, accessible UI components, an auth and session baseline, SSR with progressive enhancement, and security headers on by default. - No build step: source ES modules are served directly, and TypeScript is stripped at load (Node 24+ `module.stripTypeScriptTypes`, or amaro on Bun). Prod perf comes from HTTP/2 plus modulepreload, not bundling. - Web components, not React: components are native custom elements with a Lit-aligned reactive API (reactive properties, signals, the Lit lifecycle and directive set), hydrated per element as islands. WebJs ships its own implementation, not Lit. - SSR and progressive enhancement by default: pages render on the server and read, navigate, and submit with JavaScript disabled; interactivity is opt-in per behaviour. - Server actions: a `'use server'` file exposes typed async functions the client imports as RPC stubs; the wire round-trips Date, Map, Set, BigInt, typed arrays, Blob, File, FormData, and cycles. - File-based routing with layouts, dynamic routes, route handlers, middleware, and streaming SSR (Suspense), all on web standards. - Runs on Node 24+ or Bun (a native `Bun.serve` listener on Bun); the source is the runtime, with no build artifact. ## Overview - [What is WebJs?](https://webjs.dev/what-is-webjs): the definitional overview, what it is, what it gives you, and how it differs from the unrelated projects that share the name - [Why WebJs](https://webjs.dev/why-webjs): the case for the architecture, and who it is not for - [AGENTS.md](https://github.com/webjsdev/webjs/blob/main/AGENTS.md): the agent-facing contract, the conventions and API for building a WebJs app - [Full documentation corpus](https://webjs.dev/llms-full.txt): every doc page below, concatenated as markdown in one file ## Documentation - [Getting Started](https://webjs.dev/docs/getting-started/llms.txt): WebJs is an AI-first, web-components-first framework with a NextJs-like API and Lit-inspired web components, built on web standards. You can use it as a full-stack framework with server-rendered... - [AI-First Development](https://webjs.dev/docs/ai-first/llms.txt): WebJs is designed from the ground up to be the framework AI agents can read, write, and ship . Every architectural decision (from the file layout to the naming conventions to the... - [Architecture](https://webjs.dev/docs/architecture/llms.txt): WebJs is a monorepo with three packages that together form the framework. Understanding the split helps when you need to import something specific or embed WebJs into another runtime. - [No-Build Model](https://webjs.dev/docs/no-build/llms.txt): WebJs has no bundler, no webjs build command, no output directory. The .js and .ts files you edit are the files the browser fetches. npm run dev and npm run start run the same source. This page is... - [Runtime (Node & Bun)](https://webjs.dev/docs/runtime/llms.txt): WebJs runs on Node 24+ or Bun . The same app source runs on either; the framework picks a runtime-neutral path internally and only the listener shell, the type stripper, and a few built-ins differ.... - [Configuration](https://webjs.dev/docs/configuration/llms.txt): WebJs is designed to work with zero configuration . File conventions handle routing, TypeScript works out of the box, and the server is pre-configured with sensible defaults. This page documents what... - [Migrating from Next.js](https://webjs.dev/docs/migrating-from-nextjs/llms.txt): A concept map from Next.js to webjs: the no-RSC execution model, isomorphic modules and the .server boundary instead of Server/Client Components, plain instead of next/link, an async page function... - [Routing](https://webjs.dev/docs/routing/llms.txt): WebJs uses file-based routing . Every file under your project's app/ directory maps to a URL based on its folder path. There is no central route configuration file. The file system is the router. - [Components](https://webjs.dev/docs/components/llms.txt): WebJs components are standard HTML custom elements built on a thin base class called WebComponent . If you are coming from React, think of WebComponent as a class component whose render method... - [Lifecycle Hooks](https://webjs.dev/docs/lifecycle/llms.txt): WebJs ships the full lit-aligned component lifecycle. AI coding agents have substantial training data on lit, so adopting lit's hook names and semantics lets agents write idiomatic WebJs code without... - [Data Fetching](https://webjs.dev/docs/data-fetching/llms.txt): When to reach for async render(), webjs-suspense streaming, Task and signals, or webjs-frame. The decision guide and anti-patterns. - [Directives](https://webjs.dev/docs/directives/llms.txt): WebJs ships the lit-html directives that have no clean native equivalent, under their familiar lit names, so AI agents writing lit-shaped directive code land on what they expect. The directives that... - [Server-Side Rendering](https://webjs.dev/docs/ssr/llms.txt): Every WebJs page is server-rendered by default . There is no client-only mode and no opt-in flag. When a request arrives, the server executes your page function, renders the result to an HTML string,... - [Progressive Enhancement](https://webjs.dev/docs/progressive-enhancement/llms.txt): WebJs pages and components are SSR'd to real HTML. Read-paths, navigation, and form submissions work without JavaScript. JS is opt-in per interactive behavior: only the click / signal / focus... - [Optimistic UI](https://webjs.dev/docs/optimistic-ui/llms.txt): optimistic() from @webjsdev/core shows a mutation's expected result immediately, runs the real server action, and releases the overlay when it settles. Covers the declarative queue API, the... - [Display-Only Elision](https://webjs.dev/docs/elision/llms.txt): WebJs never downloads a component module that does no client work. Elision is automatic and biased toward shipping. Inspect the verdict per module with webjs elision, and prove it for your own app... - [Styling](https://webjs.dev/docs/styling/llms.txt): WebJs ships two styling models and lets you pick per component. The default is light DOM with Tailwind CSS : a static compiled stylesheet (so it works with JavaScript off) with @theme design tokens.... - [Streaming & Suspense](https://webjs.dev/docs/suspense/llms.txt): WebJs supports streaming SSR with Suspense boundaries . The server flushes the page shell (header, layout, fast content) immediately, then streams deferred content as it resolves. The browser paints... - [Loading States](https://webjs.dev/docs/loading-states/llms.txt): WebJs uses loading.ts files to automatically wrap page content in a Suspense boundary. The loading UI is flushed to the browser immediately while the async page function resolves in the background. - [Error Handling](https://webjs.dev/docs/error-handling/llms.txt): WebJs provides nested error boundaries via error.js / error.ts files, plus component-level error handling via renderError() . Errors are caught at the nearest boundary and rendered without crashing... - [Client Router](https://webjs.dev/docs/client-router/llms.txt): WebJs ships a nested-layout-aware client router that intercepts same-origin clicks and
submissions, fetches the target HTML, and swaps only the deepest layout boundary the two pages don't... - [Server Actions](https://webjs.dev/docs/server-actions/llms.txt): Server actions are async functions that run exclusively on the server but can be imported and called from client-side web components as if they were local functions. WebJs rewrites the import at... - [API Routes](https://webjs.dev/docs/api-routes/llms.txt): API routes are route.ts files that export named async functions for each HTTP method you want to handle. They follow the same file-based routing as pages but produce JSON (or any Response ) instead... - [WebSockets](https://webjs.dev/docs/websockets/llms.txt): WebJs has first-class WebSocket support. Export a WS function from any route.ts file and it becomes a WebSocket endpoint at that URL. On the client, connectWS() provides auto-reconnect, JSON... - [Database (Drizzle)](https://webjs.dev/docs/database/llms.txt): WebJs uses Drizzle as the default ORM. It fits the buildless thesis: there is no codegen and no engine binary (what you write is what runs), it runs on Node and Bun, and the types are inferred... - [Build Your Own Authentication](https://webjs.dev/docs/authentication/llms.txt): Build session-based authentication on the WebJs primitives when you want to own the session format, scrypt password hashing, and middleware route protection, instead of using the built-in... - [Backend-Only Mode](https://webjs.dev/docs/backend-only/llms.txt): WebJs works as a pure API framework with no pages, no SSR, and no web components. If you only need file-based routing, middleware, TypeScript, and a fast HTTP server, you can use WebJs without... - [Caching](https://webjs.dev/docs/cache/llms.txt): WebJs provides two complementary caching layers: cache() for server-side query result caching, and HTTP Cache-Control headers for page-level browser/CDN caching. Zero config in development (in-memory... - [File Storage](https://webjs.dev/docs/file-storage/llms.txt): WebJs ships a pluggable file-storage primitive for uploaded File / Blob payloads. It mirrors the cache and session adapters: a documented FileStore interface, a default on-disk adapter ( diskStore ),... - [Sessions](https://webjs.dev/docs/sessions/llms.txt): WebJs provides a Session class with a SessionStorage interface, inspired by Remix. Storage owns the session lifecycle: storage.read(cookie) → Session , storage.save(session) → cookie . Two built-in... - [Auth Providers (createAuth)](https://webjs.dev/docs/auth/llms.txt): The built-in createAuth() surface: OAuth providers, credentials login, and JWT sessions with no external auth library. Covers setup, the auth API route, reading the session, callbacks, and session... - [Rate Limiting](https://webjs.dev/docs/rate-limiting/llms.txt): WebJs ships a fixed-window rate limiter backed by the pluggable cache store. In development it uses in-memory counters. For shared limits across multiple instances in production, switch the global... - [Security](https://webjs.dev/docs/security/llms.txt): The WebJs threat model and hardening surface: CSRF, CSP, secure headers, CORS, body limits, SRI, the .server boundary, sessions, and rate limiting, with which protections are automatic and which are... - [Metadata Routes](https://webjs.dev/docs/metadata-routes/llms.txt): WebJs supports special route files that generate SEO and PWA metadata: sitemaps, robots.txt, web manifest, favicons, and Open Graph images. These files export a function and the framework serves the... - [Reactive Controllers](https://webjs.dev/docs/controllers/llms.txt): Reactive controllers are a composition pattern for sharing lifecycle-bound logic across components without using inheritance. Instead of building mixin chains or base class hierarchies, you create... - [Context Protocol](https://webjs.dev/docs/context/llms.txt): The context protocol lets you share data across deeply nested components without threading attributes through every intermediate element. It uses DOM events under the hood, which means it works... - [Task Controller](https://webjs.dev/docs/task/llms.txt): The Task controller manages async operations inside components such as data fetching, computations, or any promise-based work. It tracks loading, success, and error states automatically, cancels... - [Lazy Loading](https://webjs.dev/docs/lazy-loading/llms.txt): Components marked with static lazy = true are loaded only when they enter the viewport. The SSR-rendered HTML is visible immediately. The JavaScript module is fetched in the background when the user... - [TypeScript](https://webjs.dev/docs/typescript/llms.txt): WebJs is built for TypeScript from the ground up, but never forces a build step you run. It runs on Node 24+ or Bun ; on Node the type-stripping is the built-in ( process.features.typescript ===... - [Editor Setup](https://webjs.dev/docs/editor-setup/llms.txt): WebJs ships a TypeScript overlay ( packages/core/index.d.ts and packages/core/src/component.d.ts ) so any editor that speaks the TypeScript Language Server ( tsserver ) gets autocomplete, hover... - [Middleware](https://webjs.dev/docs/middleware/llms.txt): Middleware in WebJs lets you intercept requests before they reach your pages, API routes, or server actions. Use it for authentication, logging, rate limiting, CORS, header injection, or any... - [Deployment](https://webjs.dev/docs/deployment/llms.txt): WebJs runs as a standard server on Node 24+ or Bun . There is no static export, no serverless adapter, and no edge runtime yet. Deploy it anywhere you can run Node or Bun: a VPS, a container, a PaaS... - [Testing](https://webjs.dev/docs/testing/llms.txt): WebJs uses Node's built-in node:test runner, so no external test framework is needed. The framework itself ships with 70+ tests covering the server renderer, router, actions, CSRF, client diffing,... - [Conventions & AI Workflow](https://webjs.dev/docs/conventions/llms.txt): WebJs is an AI-first framework . It ships an opinionated conventions system that both humans and AI agents follow. The conventions are enforced via config files, CLI commands, and guardrails that... - [Troubleshooting](https://webjs.dev/docs/troubleshooting/llms.txt): Symptom-keyed fixes for the distinctive WebJs error signatures: throw-at-load server imports, backtick-in-template 500s, TypeScript strip failures, SSR browser-global crashes, the missing-frame swap,... ## UI components, Tier 1 (class helpers on native elements) - [accordion](https://webjs.dev/ui/accordion) - [alert](https://webjs.dev/ui/alert) - [aspect-ratio](https://webjs.dev/ui/aspect-ratio) - [avatar](https://webjs.dev/ui/avatar) - [badge](https://webjs.dev/ui/badge) - [breadcrumb](https://webjs.dev/ui/breadcrumb) - [button](https://webjs.dev/ui/button) - [card](https://webjs.dev/ui/card) - [checkbox](https://webjs.dev/ui/checkbox) - [collapsible](https://webjs.dev/ui/collapsible) - [input](https://webjs.dev/ui/input) - [kbd](https://webjs.dev/ui/kbd) - [label](https://webjs.dev/ui/label) - [native-select](https://webjs.dev/ui/native-select) - [pagination](https://webjs.dev/ui/pagination) - [popover](https://webjs.dev/ui/popover) - [progress](https://webjs.dev/ui/progress) - [radio-group](https://webjs.dev/ui/radio-group) - [separator](https://webjs.dev/ui/separator) - [skeleton](https://webjs.dev/ui/skeleton) - [switch](https://webjs.dev/ui/switch) - [table](https://webjs.dev/ui/table) - [textarea](https://webjs.dev/ui/textarea) ## UI components, Tier 2 (stateful custom elements) - [alert-dialog](https://webjs.dev/ui/alert-dialog) - [dialog](https://webjs.dev/ui/dialog) - [dropdown-menu](https://webjs.dev/ui/dropdown-menu) - [hover-card](https://webjs.dev/ui/hover-card) - [sonner](https://webjs.dev/ui/sonner) - [tabs](https://webjs.dev/ui/tabs) - [toggle](https://webjs.dev/ui/toggle) - [toggle-group](https://webjs.dev/ui/toggle-group) - [tooltip](https://webjs.dev/ui/tooltip) ## Project - [GitHub repository](https://github.com/webjsdev/webjs): source, issues, and the framework monorepo (plain JS with JSDoc, so what you read is what runs) - [UI component library](https://webjs.dev/ui): the AI-first web-component kit (`webjs ui add`) - [Changelog](https://webjs.dev/changelog): the unified per-package release feed ## Articles - [What a Web Components Framework Is (and Why It Is Not Just Lit)](https://webjs.dev/articles/web-components-framework): Build your UI on the browser's own component model, then add the full-stack pieces around it. - [Server-Side Rendering for Web Components, Without a Blank First Paint](https://webjs.dev/articles/server-side-rendering-web-components): Real HTML in the first response, from custom elements, before any JavaScript runs. - [What a No-Build JavaScript Framework Actually Is](https://webjs.dev/articles/no-build-javascript-framework): The file you write is the file the browser runs. No bundler, no dist folder, no compile step. - [Web Components vs React: How They Differ and When to Use Each](https://webjs.dev/articles/web-components-vs-react): Native browser elements versus a library runtime, and what each one asks you to give up. - [HTML Web Components: Enhance Markup, Do Not Replace It](https://webjs.dev/articles/html-web-components): Custom elements that wrap real markup and enhance it, instead of rendering everything from an empty tag in JavaScript. - [How to Run TypeScript Without a Build Step](https://webjs.dev/articles/run-typescript-without-a-build-step): Strip the types at load and run the file. No tsc, no dist folder, no sourcemaps. ## Comparisons - [WebJs vs Astro](https://webjs.dev/compare/webjs-vs-astro): Islands and near-zero JS, plus a full server-action and data story. - [WebJs vs Lit](https://webjs.dev/compare/webjs-vs-lit): Lit's component model you already know, wrapped in a full-stack framework. - [WebJs vs Next.js](https://webjs.dev/compare/webjs-vs-nextjs): The Next.js developer experience, minus the build step and the RSC mental model. - [WebJs vs Rails](https://webjs.dev/compare/webjs-vs-rails): The Rails no-build, sensible-defaults philosophy, in one TypeScript language. - [WebJs vs Remix 3](https://webjs.dev/compare/webjs-vs-remix): Two frameworks that dropped React and the bundler, diverging on the view layer and on how much of your source gets compiled. ## Blog - [All posts](https://webjs.dev/blog): the full index of design notes - [Familiar on Purpose: What WebJs Invents and What It Refuses To](https://webjs.dev/blog/familiar-on-purpose-what-webjs-invents): WebJs borrows file-based routing from Next.js, a component API shaped like Lit, and import maps from Rails, then diverges in exactly 24 documented places. Why an AI-first, no-build web components framework treats novelty as a cost, and what that buys a developer and an AI coding agent. - [A Strict CSP Nonce That Survives Client-Side Navigation](https://webjs.dev/blog/strict-csp-nonce-across-soft-navigation): Strict Content-Security-Policy with a per-request nonce is the thing client-side routers classically break, because the browser keeps enforcing the original document's nonce. How WebJs keeps a strict CSP intact across soft navigations, with a header-enforced policy and a meta-tag nonce carrier the router re-stamps. - [Building on JavaScript, Not Around It: Modules, Prototypes, and Types in WebJs](https://webjs.dev/blog/building-on-javascript-not-around-it): Most frameworks ask you to forget JavaScript and learn their abstractions. WebJs bets the opposite: native ES modules, real prototype-based classes, and a wire that speaks the full type system. A tour through the language fundamentals, framed by You Don't Know JS. - [Next.js 16 File-Routing Parity in WebJs: forbidden(), unauthorized(), and Nearest not-found](https://webjs.dev/blog/nextjs-16-file-routing-parity): WebJs closed the last Next.js 15/16 file-routing parity gaps. forbidden() and unauthorized() control-flow throws, nearest-wins not-found boundaries, sync-or-await params, and an instrumentation.js boot hook, explained for anyone migrating from Next.js. - [Leaky Error Messages: Sanitizing Production Server-Action Errors](https://webjs.dev/blog/sanitizing-server-action-errors): How WebJs sanitizes production server-action errors so a thrown action returns a generic message plus a digest instead of leaking a database string, internal IP, or filesystem path. Safe by default in prod, with a digest to keep debuggability. - [Optimistic UI Without the Boilerplate (React useOptimistic, for Web Components)](https://webjs.dev/blog/optimistic-ui-without-boilerplate): WebJs now ships a declarative optimistic() API with full React 19 useOptimistic parity for Web Components. No try-catch, no manual state caching, no temp-id reconciliation. Just add, await, and reconcile. - [Device-Adaptive Link Prefetch That Does Not Bloat the Network Tab](https://webjs.dev/blog/device-adaptive-link-prefetch): How WebJs's client router prefetches links with a device-adaptive default: intent-based prefetch on desktop hover, dwell-gated viewport prefetch on mobile. Instant navigation without a bandwidth tax, tuned to the device, no import required. - [Your Page Module Should Not Be in the Network Tab](https://webjs.dev/blog/import-only-pages-zero-js): In WebJs, pages and layouts never hydrate, so their JavaScript has no job in the browser. An import-only page or layout is dropped entirely and the boot ships just the interactive component leaves it imported. How it works, when a page still ships whole, and how to check. - [How WebJs Ships Zero JavaScript for Display-Only Components](https://webjs.dev/blog/ship-zero-javascript-display-only-components): WebJs strips the JavaScript for any component it can prove is display-only, so an islands app ships only its interactive leaves. How the elision analyser works, why it is conservative by construction, and how the invariant is enforced in code. - [How WebJs Stops AI Coding Agents From Breaking Your Code](https://webjs.dev/blog/stop-ai-agents-breaking-your-code): AI coding agents commit to main, skip tests, and ignore your conventions. WebJs is an AI-first framework that bakes those guardrails into tooling so drift is caught early. - [Real-Time WebJs: WebSockets and Broadcast Without a Separate Server](https://webjs.dev/blog/websockets-and-realtime): How WebJs adds real-time features with WebSockets folded into the file router: a WS export in route.ts, connectWS with auto-reconnect and queued sends on the client, and a broadcast built-in for fan-out, no separate WebSocket server required. - [Prisma vs Drizzle: Why We Chose Drizzle as Our Default ORM](https://webjs.dev/blog/prisma-vs-drizzle-default-orm): Prisma vs Drizzle for a no-build framework. Why WebJs picked Drizzle ORM as the scaffold's default ORM, how the buildless, source-is-the-runtime model made the decision, and how to bring your own if you prefer Prisma. - [Server-Side Caching for Beginners (ETags, Tags, and 304s)](https://webjs.dev/blog/server-side-caching-explained): A beginner guide to server-side caching in WebJs. Learn HTTP Cache-Control, the cache() helper, tag-based invalidation, and conditional GET with ETags and 304s. - [A Web Framework That Works Without JavaScript](https://webjs.dev/blog/works-without-javascript): In WebJs, progressive enhancement is the default architecture. Pages SSR and never hydrate, forms submit through server actions with JS off, and interactivity is opt-in. - [Accessible Web Components Out of the Box](https://webjs.dev/blog/accessible-web-components-by-default): How @webjsdev/ui ships accessible web components by default, with keyboard navigation, screen-reader labels, and focus management wired in from the start. - [Server Actions Without React Server Components](https://webjs.dev/blog/server-actions-without-react-server-components): WebJs has no server/client component split, no Flight protocol, and no use client boundary. It gets await-data-in-the-leaf and typed server mutations from one RPC boundary instead. How the execution model works and why it drops the RSC machinery. - [Per-Action Middleware: Auth and Context Around a Single Server Action](https://webjs.dev/blog/per-action-middleware): How WebJs attaches per-action middleware to a single server action for auth, rate-limit checks, logging, and tenant resolution. Declarative middleware that runs automatically on the RPC boundary, short-circuits cleanly, and feeds context via actionContext(). - [Give AI Coding Assistants Live Access to Your App](https://webjs.dev/blog/mcp-server-for-ai-coding-agents): WebJs ships a read-only MCP server for AI coding agents. Learn how the Model Context Protocol lets Claude, Cursor, and other AI assistants read your app's real routes, actions, and components instead of guessing them. - [Cancelling Server Actions With AbortSignal (No Wasted Work on Disconnect)](https://webjs.dev/blog/cancel-server-actions-abortsignal): WebJs wires the platform's own AbortSignal through the server-action RPC boundary in both directions, so a client that navigates away actually cancels the in-flight request and the server stops paying for work nobody is waiting for. - [Cacheable Server Actions With GET, ETags, and 304s](https://webjs.dev/blog/get-server-actions-caching): Make a server action cacheable in WebJs by declaring it a GET. Args ride the URL, it is CSRF-exempt, and a weak ETag answers 304 so repeat reads are nearly free. ## Optional - [Sitemap](https://webjs.dev/sitemap.xml): every crawlable page, enumerated