How this site is built
This site is also a work sample. It is one application containing the public pages, a client portal, and the admin tools I run projects with.
The stack
- Framework
- Next.js 16 and React 19, written in TypeScript
- Rendering
- Static HTML for public pages; a static shell with streamed data for the portal
- Styling
- Tailwind CSS 4 with a small set of design tokens; light and dark from one palette
- Database
- PostgreSQL with Drizzle ORM and versioned migrations
- Sign-in
- Better Auth with emailed links; invite-only, no passwords
- Payments
- Stripe invoices on Stripe's hosted pages, mirrored by webhooks
- Files
- S3-compatible object storage with expiring upload and download links
- Resend for sign-in links and notifications
- Hosting
- Docker and Caddy on a virtual server; images built in CI
- Type
- Bricolage Grotesque and Instrument Sans, self-hosted
Standards
Fast by default
Public pages are prerendered. Fonts are self-hosted and there are no third-party scripts, so nothing waits on someone else's server.
Usable by everyone
Every control works from the keyboard, focus is always visible, colors meet contrast guidelines in both themes, and motion respects your system setting.
Private by design
No advertising trackers. Each client's data is isolated at the query level, and files are only reachable through links that expire.
For the reasoning behind each choice, read the longer write-up.