The web framework for AI agents
WebJs is a full-stack framework built on web components, SSR, and progressive enhancement with zero build step. Lean enough for an agent to read end to end. Runs on Node 24+ or Bun.
Real HTML first. JavaScript only when it earns it.
Pages and components render to real HTML on the server, so the page reads, links navigate, and forms submit before a single script loads. There is no hydration runtime to pay for, and dead JavaScript is statically elided, never shipped.
class LikeButton extends WebComponent({ count: Number }) {
render() {
return html`<button @click=${() => this.count++}>
♥ ${this.count}
</button>`;
}
}
LikeButton.register('like-button');
// No build step. No bundler. No virtual DOM.
// The panel to the right is this file, server-rendered
// and upgraded in place. Click it.
<like-button count="3"></like-button>
The whole stack, in three files
A component, a server action, and a page. No build, no boilerplate, all web standards.
Interactive component
import { WebComponent, html, signal } from '@webjsdev/core';
class LikeButton extends WebComponent {
likes = signal(0);
render() {
return html`<button @click=${() => this.likes.set(this.likes.get() + 1)}>
♥ ${this.likes.get()}
</button>`;
}
}
LikeButton.register('like-button');
Server action (RPC)
'use server';
import { eq } from 'drizzle-orm';
import { db } from '#db/connection.server.ts';
import { posts } from '#db/schema.server.ts';
// Import this from a page or client component. WebJs rewrites
// the import into a typed RPC stub (the real call at SSR). No
// fetch by hand.
export async function getPost(id) {
const [post] = await db.select().from(posts).where(eq(posts.id, id));
return post;
}
SSR page
import { html, notFound } from '@webjsdev/core';
import { getPost } from '#actions/get-post.server.ts';
import '#components/like-button.ts';
export default async function Post({ params }) {
const post = await getPost(params.id);
if (!post) notFound();
return html`<article>
<h1>${post.title}</h1>
<like-button></like-button>
</article>`;
}
Modern full-stack, on web standards
Everything you need to ship, none of the build toolchain you don't.
Zero build step
Source files run as-is, so what you write is exactly what the browser serves. An AI agent debugs against the real served code, never a bundled or minified artifact.
Light DOM web components
Web components that render to light DOM, so Tailwind and global CSS just work, no shadow plumbing.
Server actions (RPC)
Mark a file 'use server' and import it. Date, Map, Set, BigInt, and Blob all round-trip across the wire with real http verbs (GET, POST, PUT, PATCH, DELETE).
Streaming Suspense
Stream slow regions progressively. The shell paints instantly, fallbacks render, and async data fills in as it resolves.
Progressive enhancement
Real HTML first. Links navigate, forms submit, and pages read before JavaScript loads. No hydration overhead.
Built-in essentials
Auth, sessions, cache, rate limits, and websockets are built right in. Pluggable adapters, zero glue.
Light enough for AI
A zero build step means the source you read is what runs. Because the framework ships without compilation layers, an AI agent can read and reason about the entire WebJs source end to end, straight from node_modules.
A minimal Next.js client bundle is ~99 KB gzipped including React. WebJs is self-sufficient at ~29 KB, 3.4x lighter on the wire.
No compilation, no bundler. Agents edit, run tests, and verify in the browser in milliseconds.
Standard-aligned Web Component lifecycles, so models write components reliably.
Under 6.5k lines of client runtime, ~16k for the whole stack, small enough to fit an LLM context window.
Familiar from day one. WebJs uses Next.js-style file-based routing and lit-style web components, conventions both people and agents already know.
Gzipped production sizes. A Next.js app ships a client bundle around ~99 KB gzipped (react, react-dom, and the Next runtime); @webjsdev/core is self-sufficient at ~29 KB gzipped with zero runtime dependencies and no build step.
Start where you are
Pages + API + components
SSR pages, web components, server actions, Drizzle, streaming, and a browsable feature gallery. Auth (login, sessions, a protected route) ships as a gallery card. The default.
app/page.ts components/counter.ts actions/posts.server.ts
Route handlers + Database
A backend-only app, no UI or SSR. File-based route handlers, modules, middleware, rate limiting, WebSockets, a database, and a backend-features gallery.
app/api/users/route.ts app/api/chat/route.ts middleware.ts
Prefer Bun? Add --runtime bun to either template, or run bun create webjs my-app to flavor the scaffold for Bun automatically.
Start building with AI
Run the command below in your terminal, launch your AI coding agent from the app folder, and tell it what you would like to build.