Packages
@thexjs/core
The rendering and routing engine behind x — file-based routing, SSR/SSG, islands, server functions, content collections, and a lightweight data layer.
bun add @thexjs/core
Requires Bun. You typically do not install this directly — @thexjs/cli depends on it and drives x dev / x build / x start.
Quick start
x.config.ts
import { defineConfig } from "@thexjs/core";export default defineConfig({ pagesDir: "./src/pages", contentDir: "./src/content", port: 3000,});src/pages/index.tsx
import type { RouteProps } from "@thexjs/core";export const mode = "static";export default function HomePage({}: RouteProps) { return <h1>Hello from x</h1>;}File-based routing
route mapping
File Route────────────────────────────────────────────src/pages/index.tsx /src/pages/about.tsx /aboutsrc/pages/blog/[slug].tsx /blog/:slugsrc/pages/api/users.ts API route at /api/userssrc/pages/_layout.tsx Wraps routes in directorysrc/pages/_middleware.ts Runs before matching routessrc/pages/_404.tsx Custom not-found pageFiles and directories prefixed with _ or . are never treated as routes.
Route modes
Every page defaults to server-rendered. Opt into build-time prerendering:
src/pages/index.tsx
export const mode: "static" | "server" = "static";- static — rendered once at build time to HTML in .x/client/
- server — rendered per request via x start or x dev
Loaders
loader example
import type { RouteProps } from "@thexjs/core";export async function loader({ params }: { params: Record<string, string> }) { return { user: await getUser(params.id) };}export default function UserPage({ loaderData }: RouteProps<typeof loader>) { return <p>{loaderData.user.name}</p>;}Islands
Wrap interactive pieces in <Island> for selective hydration:
island
import { Island } from "@thexjs/core";<Island name="like-button" client="visible"> <LikeButton /> ></Island>client accepts "idle", "visible", or "load".
Content collections
markdown
import { scanContent, renderMarkdown } from "@thexjs/core";const posts = scanContent("./src/content/blog");const html = renderMarkdown(posts[0].body);Data layer
sqlite
import { connectSQLite, runSQLiteMigrations } from "@thexjs/core";const db = connectSQLite({ filename: "./data/dev.db" });await runSQLiteMigrations(db, "./data/migrations");postgres
import { connectPostgres, runPostgresMigrations } from "@thexjs/core";const sql = connectPostgres({ url: process.env.DATABASE_URL! });await runPostgresMigrations(sql, "./data/migrations");Key exports
exports
defineConfig, createApp, build App setup & buildrenderPage, renderStaticPage Lower-level renderingscanRoutes, scanPages, scanApiDir Routing internalsIsland, IslandProvider Selective hydrationscanContent, renderMarkdown Markdown contentcomposeMiddleware, MiddlewareFn Route middlewareregisterServerFunctions Server function internalsconnectSQLite, connectPostgres Data layer