Stack
What I build with, and the reason for each choice.
updated August 27, 2026
This is what I build with and why, taken from lockfiles, configs, and git history rather than from memory. An item is marked as in use only when it is in an active repo this month.
Languages and runtimes
- TypeScriptusing2023Every active repo, strict, run directly by Bun. One observation from 2026: agents do better in Rust because they actually run the compiler, whereas in TypeScript they skip the type check.
- Bunusing2024-09Runtime, package manager, test runner, and SQLite driver. It runs TypeScript without a compile step, and it is the hard constraint: nothing that needs a JVM gets in.
- Rustused2020-03 – 2023These were the smart-contract years.
- Pythonused2024-03 – 2024-08That was the year of orchestration frameworks. My rule since then is that Python trains and TypeScript ships.
- Lisp, Clojureused2024-08 – 2025-08studied, never shippedA year around the idea that prompts and agent decisions are plain data. The runtime constraint ended it; the code-is-data framing stayed.
Frameworks and libraries
- Next.js, Reactusing2024-09I left it once for a mobile backend in 2025 and came back for every site since, including this one.
- Turborepousing2025-08It is only in repos with real build graphs; the rest are plain workspaces.
- Vercel AI SDKusing2024-08The one framework layer I keep, because provider abstraction is the part a framework can solve. It sits behind one wrapper so every model call runs on a subscription.
- Zodusing2024-08It is in every repo, and I still wish for grammar-based validation.
- Drizzleusing2025-07Chosen over Prisma because I already knew SQL and did not want a layer that hid it.
- Tailwind 4, Biome, Shiki, MDXusing2024-08This site. Lint is advisory in CI on purpose; a check that is red by default teaches everyone to ignore red.
- Remotionusing2026-02Hard to make a nice video with at first. The explainer-video studio runs on it, and on the Linux box it renders faster than realtime.
- commanderusing2026-01Every tool in my personal system is a subcommand. The binary is the interface.
- Eveusing2026-08Close to the shape I want: an agent is a directory of files and the whole system is version-controlled.
Data
- SQLiteusing2026-01Habits, relationships, the search index, every business body. Files are for what a human writes and diffs; a database is for many rows of one shape that a machine writes.
- sqlite-vecusing2026-01Vectors in the same file as the text. About a hundred times faster than the local-first tool I tried first.
- 2026-08A local file by default. One environment variable makes it a replica shared across hosts with no server I run.
- Markdown in a folder, under gitusing2026-03the recordThe daily log is markdown and SQLite only indexes it. Event-sourced designs were rejected three times.
- Zepused2026-03 – 2026-05temporal factsIt holds the memory organ's graph, still registered and unused since May.
- Postgresused2024-12 – 2026-07One venture ran on it in mid-2026 before moving to SQLite.
Infra and machines
- The Linux boxusing2026-08everything scheduledA daily money reading died once because the laptop had no network at 7:30am, and a missing datapoint looks like a quiet day. Since then nothing scheduled runs on a laptop; the Mac is authoritative and the box is a replica for compute.
- Coolifyusing2026-08The deploy layer on the box, next to a self-hosted job runner and a local container registry.
- Dockerusing2026-03Agent sandboxes with a coding agent and Bun baked in.
- 2026-08It keeps run history with unlimited retention, and the daily money digest lives here.
- 2026-08A push to main is picked up by a runner on the box over an outbound connection. No webhooks, no open ports.
- Cloudflare Pagesusing2026-08Thirty small sites up in August 2026 with a hundred planned, each a probe to see whether anyone clicks.
- Vercelusing2024This site and one cohort of the business sites.
- Stripe, Resendusing2026-07rails, not mirrorsThe repo never mirrors their state, because a mirror is a cache and caches drift.
- Upstash Redisusing2026-08A rotating credential can have exactly one writer, so the shared token store lives here.
- Subscriptions, not API keysusing2026-08Model calls route through one provider on the chat subscription. Headless agent calls are billed as API and treated as real spend.
Workflow
- git, GitHubusingGit is the convergence mechanism: uncommitted means proposed, a commit means accepted. Agents cannot delete repositories, because the token lacks the scope, on purpose.
- Worktrees, one writer per checkoutusing2026-07Several branch-mutating agents in one working directory corrupt each other, because a branch switch is global to the directory.
- Stacked PRsusing2026-08Each PR is one reviewable idea. I review from my phone, so a small diff is the difference between a review and a rubber stamp.
- Linearusing2024-06the queueA good issue is a home for convergence rather than a task. What it lacks is a long-running view of ends and monitors, something that is not a chat.
- Claude Code, Cursor, Codex, pi, OpenClawusing2025-07the agents in the loopThe loop as of August 2026: something becomes a Linear issue, I approve it, a cloud agent picks it up, I review and merge.
- MCPusing2026-01a wrapper, not the primitiveScripts come first; the protocol wraps them for when a second harness needs the same thing.
- Slackusing2026-08the agent surfaceOne bot, pull-based, no server. Each business agent is bound to its own channel.
Dropped, with the reason
- Azuredropped2024-12 – 2026-08Sponsored credits were the whole reason. When they expired every call became real billing, so it went behind one switch and off, with two exceptions nothing else serves.
- Cloudflare Durable Objectsdropped2025-11 – 2026-01as a foundationThe design started from schemas and runtime machinery before it had touched enough reality. Replaced by a folder under git, local-first.
- Convexdropped2024-09 – 2025Fast to move with, and it limited how much I could over-schematize. It survives as the analogy for what I want to be for agents.
- Supabase, then MongoDBdropped2024-03 – 2025-08Schemaless felt right when I did not know what I was building. Both gone by 2026; the journals are markdown files.
- LangChaindropped2024-03 – 2024-08Its core abstraction was the thing I kept working around, which told me it was solving a different problem than mine.
- n8ndropped2024-03 – 2024-08I found I could standardize the input to rich text plus attachments and let scripts decide.
- Railway, Honodropped2025-08 – 2025-10It lasted two months, and the home server took that role.
- A Telegram bot for capturedropped2024-03 – 2024-09A log command and a voice recorder on walks replaced it.