Documentation

Everything you need to build with VirexJS.

Getting Started

bunx virexjs init my-app
cd my-app && bun install
bun run dev

Project 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 components

Pages & 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-renders

API 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 stats

Full API Reference

75+ exports covering rendering, routing, auth, validation, i18n, real-time, and more.

View API Reference