Bold, structural UI kit inspired by Dutch graphic design: zero-radius geometry, high contrast, and loud typography. Built around Bun SSR + a server-only JSX component library in src/components/.
bun install
bun run dev:css # watch Tailwind CSS
bun run dev # start Bun server (watch mode)Open http://localhost:3000
- Bun SSR app (for demos/showcases): routes in
src/routes/, server insrc/index.ts - JSX SSR components: reusable building blocks in
src/components/(no client-side React) - Design tokens + docs: Markdown docs in
docs/ - Static assets:
public/assets/(generated CSS + vanilla JS modules)
- Runtime: Bun
- Rendering: React SSR via
renderToReadableStream()(no hydration) - Styling: Tailwind CSS 4 + CSS-first design tokens
- Routing: file-based (see
src/utils/loadRoutes.ts) - Interactivity: vanilla JS modules +
data-*hooks (seepublic/assets/js/)
Components in src/components/ render to static HTML on the server. There is no React runtime in the browser.
- Don’t use React hooks (
useState,useEffect, …) - Don’t rely on JSX event handlers (
onClick,onChange, …) for behavior - For interactive components (tabs, modal, toast, file upload, …) load a small script from
public/assets/js/and bind viadata-*
/— home/components— component gallery (driven bysrc/components/componentRegistry.ts)/components/<id>— component demo pages (implemented as routes insrc/routes/components/)/showcase— full-page compositions/patterns— patterns gallery/typography,/colors— foundation pages
src/
index.ts # Bun server entry
components/ # JSX SSR components (folder-per-component)
routes/ # File-based routing (index.tsx + method files)
middleware/ # Request helpers (e.g. CORS)
utils/ # Routing + static asset helpers
styles/dutchy.css # Tailwind source (tokens + theme vars)
public/assets/
css/styles.css # Generated Tailwind output (build artifact)
js/ # Vanilla JS modules (tabs, modal, toast, ...)
docs/ # Design system docs (tokens/components/patterns)
.claude/skills/ # Claude Code project skills
.agents/skills/ # Codex project skills
Routes are discovered under src/routes/:
index.tsx→GEThandler (React component or(req) => Response)get.ts,post.ts,put.ts, … → explicit HTTP method handlers$paramfolder names are supported by the router (become:param), even if your current routes are mostly static
Themes are CSS variables (default, purple, crimson). Tailwind utilities (bg-primary, text-primary, border-primary, including opacity modifiers) follow the active theme.
For the complete flow from Tailwind source to runtime theme switching and Bun static asset serving, see Theme and CSS Build Lifecycle.
- Tailwind 4 is configured in
src/styles/dutchy.csswith@import "tailwindcss",@source, and@theme. There is no requiredtailwind.config.jsfor the app. public/assets/css/styles.cssis generated bybun run build:cssand is intentionally not tracked.- Renovate is configured to create update branches and PRs against
developonly. - Claude Code project skills live in
.claude/skills/; Codex project skills live in.agents/skills/. .claude/settings.local.jsonstays ignored because it is machine-local.
| Script | Description |
|---|---|
bun run dev |
Start Bun server in watch mode |
bun run dev:css |
Watch and rebuild Tailwind CSS |
bun run build |
Build generated assets |
bun run build:css |
One-time Tailwind CSS build (minified) |
bun run typecheck |
Run TypeScript without emitting files |
bun run lint |
Run Biome format, lint, and import checks |
bun run lint:fix |
Apply Biome safe fixes |
bun test |
Run tests in tests/ |
docker build -t dutchy:2.1.2 .
docker run -p 3000:3000 dutchy:2.1.2The image builds Tailwind CSS at build time and serves the Bun SSR app on port 3000.
docs/01-design-system/— design principles, tokens, components, patterns (HTML-first)docs/03-using-with-bun/— Bun SSR notes and conventionssrc/components/— the canonical JSX SSR component implementation used by the demo app
MIT