tau's personal site. Self-hosted, no tracking, no analytics, no BS.
Live: tau.htcusainc.info
- A static Next.js 16 site (React 19, Tailwind v4) compiled to a folder of HTML and served by nginx.
- A tiny Express + SQLite guestbook service in
guestbook-api/, living behind the same domain via Traefik. - A
taucontent CLI for adding posts, projects, gallery photos, shrines, etc. without touching React. - All content stored as JSON in
src/data/(or files underpublic/), versioned with the code.
tau-site/
├── src/ Next.js pages, components, JSON data
├── public/ shrines, gallery, music, blinkies
├── scripts/cli/ the `tau` CLI
├── guestbook-api/ Express + SQLite (the only real backend)
├── docs/ the deep docs (start here!)
├── Dockerfile multi-stage build → nginx runtime
└── docker-compose.yml site + api together, Traefik labels
| Doc | What's in it |
|---|---|
| docs/ARCHITECTURE.md | Tech stack, repo layout, build pipeline, why-this-not-that |
| docs/CONTENT.md | Every page on the site + where to edit each kind of content |
| docs/CLI.md | Full tau CLI reference (every command, every flag) |
| docs/API.md | Guestbook API endpoints, schemas, rate limits, admin tools |
| docs/DEPLOYMENT.md | Docker compose layout, Traefik routing, deploy workflow |
| docs/tau-cli-guide.pdf | Illustrated walkthrough of the tau CLI |
pnpm install
pnpm devOpen http://localhost:3000.
For the guestbook to work locally too, in a second terminal:
cd guestbook-api
npm install
npm run dev # listens on :3001Then in .env.local at the project root:
NEXT_PUBLIC_API_BASE=http://localhost:3001/api
Without it, the guestbook page shows "could not reach the guestbook service" — non-fatal, every other page works fine.
pnpm buildOutput lands in out/. Open it with any static server.
On a server with Docker + a shared Traefik network named traefik-net:
docker compose up -d --buildSee docs/DEPLOYMENT.md for the full topology (Traefik labels, persistent volumes, edit-on-server workflow).
You're not expected to touch React. Use the tau CLI:
tau post add # interactive: new blog post
tau project add # new project
tau now edit # /now page sections in $EDITOR
tau photo add img.jpg travel
tau publish # rebuild + redeploy the site containertau help lists everything. Full reference: docs/CLI.md.
If you'd rather edit JSON directly, the source files live in
src/data/*.json. docs/CONTENT.md lists which
file backs which page.
- Frontend with all routes (home, /now, /projects, /videos, /entertainment, /gallery, /music, /links, /socials, /guestbook, /shrines)
- Auto-derived home updates feed (posts + project status)
- Auto
/nowlast-touched timestamp from file mtime - Paginated post archive at
/void - Per-project detail pages
- Guestbook backend (Express + SQLite, rate-limited, spam-filtered)
- Site Dockerfile + nginx + docker-compose + Traefik labels
-
tauCLI —post,project,now,video,channel,watching,shrine,photo,album,track,link,social,button,publish - Gallery: directory-scan prebuild + per-photo detail pages
- Music: tracks.json metadata + custom audio player
- Posts RSS feed (
/feed.xml) - Guestbook RSS feed (
/api/guestbook.rss) - Footer with both feeds + AI-built disclaimer
- CrowdSec integration for the API
- Real cursor-trail tuning, real blinkies wall
The source code is MIT — do anything with it.
The site content (writing, photography, music, hand-written shrines
under public/shrine/) remains © Jadon Etuale, all rights reserved,
unless explicitly noted otherwise.
Built with Claude Code. See docs/ARCHITECTURE.md for the full story.