Documentation
Everything you need to build with VirexJS.
Getting Started
bunx virexjs init my-app
cd my-app && bun install
bun run devProject Structure
src/
pages/ File-based routes
_layout.tsx Nested layout
_loading.tsx Loading state (streaming)
_error.tsx Error boundary
_404.tsx Custom 404
_middleware.ts Per-route middleware
index.tsx → /
blog/[slug].tsx → /blog/:slug
islands/ Interactive components
api/ API routes
middleware/ Auto-loaded global middleware
components/ Server componentsPages & Routing
// src/pages/blog/[slug].tsx
import type { PageProps, LoaderContext } from "virexjs";
export async function loader(ctx: LoaderContext) {
return { post: await getPost(ctx.params.slug) };
}
export function meta({ data }) {
return { title: data.post.title };
}
export default function BlogPost(props: PageProps) {
return <h1>{props.data.post.title}</h1>;
}Islands (Interactive Components)
// src/islands/Counter.tsx
"use island";
import { useIslandState } from "virexjs";
export default function Counter(props) {
const { get, set } = useIslandState(props, { count: 0 });
return (
<button onClick={() => set("count", get("count") + 1)}>
Count: {get("count")}
</button>
);
}Cross-Island Communication
// CartButton island — PRODUCER
"use island";
import { useSharedStore } from "virexjs";
export default function CartButton(props) {
const store = useSharedStore(props);
store.subscribe("cart.count");
return (
<button onClick={() =>
store.set("cart.count", (store.get("cart.count") ?? 0) + 1)
}>
Add ({store.get("cart.count") ?? 0})
</button>
);
}
// CartBadge — SEPARATE island, auto-synced!
// store.subscribe("cart.count") => re-rendersAPI Routes
// src/api/users.ts
import { json, notFound } from "virexjs";
export async function GET({ params }) {
return json(await db.select("users").all());
}
export async function POST({ request }) {
const body = await request.json();
return json({ created: true }, { status: 201 });
}Middleware
// src/middleware/auth.ts
import { defineMiddleware, redirect } from "virexjs";
export default defineMiddleware(async (ctx, next) => {
if (!ctx.request.headers.get("Authorization")) {
return redirect("/login");
}
return next();
});
// Built-in: cors(), rateLimit(), compress(), withETag()Configuration
// virex.config.ts
import { defineConfig } from "virexjs";
export default defineConfig({
port: 3000,
css: { engine: "tailwind" },
redirects: [
{ source: "/old", destination: "/new", permanent: true },
],
});CLI Commands
virex init <name> # Scaffold project
virex dev # Dev server + HMR
virex build # Production SSG build
virex preview # Preview build
virex generate <type> # Scaffold page/component/api/island
virex check # Validate project
virex info # Show project statsFull API Reference
75+ exports covering rendering, routing, auth, validation, i18n, real-time, and more.
View API Reference