The Stack
Billet is a server-rendered TypeScript starter built on Bun. Templates are JSX compiled at the edge — no client framework, no virtual DOM, no hydration step. Pages arrive as plain HTML with optional islands of interactivity.
How data flows
Every request follows the same three-step path. Services fetch or mutate data, controllers decide what to do with it, and templates turn it into HTML. There are no loading states because data is always resolved before the template renders.
services/ → controllers/ → templates/ query the db call services receive props return typed pick a template render HTML data pass data in return Response
Project structure
src/ ├── client/ # Browser-side code │ ├── main.ts # Entry — routes to page init fns │ ├── style.css # Global styles (CSS entry point) │ ├── components/ # Shared CSS (nav, layout) │ └── pages/ # Page JS & CSS (co-located) │ ├── server/ # Server-side code (Bun) │ ├── routes/ # URL → controller mapping │ ├── controllers/ # Request handlers │ │ ├── app/ # View controllers (HTML) │ │ ├── api/ # API controllers (JSON) │ │ └── auth/ # Auth flows │ ├── templates/ # Full-page JSX templates │ ├── components/ # Reusable server JSX │ ├── services/ # Business logic & data │ ├── middleware/ # Auth, CSRF │ ├── utils/ # Shared helpers │ └── database/ # Migrations │ └── types/ # Global type declarations
Feedback stack
Four layers of automated checks run before code reaches production.
| Layer | What it catches |
|---|---|
| TypeScript strict mode | Type errors, null safety violations, implicit any |
| Biome linting | Code quality, unused variables, console statements, unsafe patterns |
| Pre-commit hooks | Formatting, lint errors, and type checks before every commit |
| Test suite | Regressions across services, controllers, templates, and client scripts |
Technology choices
A small, deliberate set of tools chosen for speed, simplicity, and minimal abstraction.
| Technology | Role |
|---|---|
| Bun | Runtime, bundler, test runner, and package manager |
| PostgreSQL | Primary data store with raw SQL via tagged templates |
| Bun CSS bundler | Native @import resolution, CSS nesting, and minification |
| Preact | Lightweight islands for interactive components — no full SPA |