Cheaper to build than to buy
The build-versus-buy line moved, and narrow internal tools are now often on the build side of it.
Kira is a self-hosted Jira-ish tracker I built for myself, which is the sort of sentence that used to sound like a warning sign. A mature adult hears “I built my own issue tracker” and starts looking for the exit.
But the old warning was built on old economics. Building a competent internal tool used to mean weeks of design work, months of backend glue, and a grim little permissions system. Buying the tool was usually cheaper, even if it fit badly, because the alternative was slow and expensive.
That math is changing. Not for everything. Please don’t read this as a manifesto for rewriting payroll. But for a narrow internal workflow with one real customer and a weird shape, the cost of building has collapsed hard enough that the build-versus-buy answer can flip.
The actual problem
The problem wasn’t that I needed a project tracker in the abstract. The world has enough project trackers. I needed a human-trackable report on the work of AI agents.
I run a lot of AI coding agents in parallel. Dozens at a time, across projects, poking at bugs, writing tests, drafting docs, chasing screenshots, fixing the thing they broke while fixing the thing before it. This is useful, and a little alarming if you stop paying attention.
The bottleneck became my head. I couldn’t reliably remember which agent was working on which branch, what it claimed to have finished, what needed review, which sprint a task belonged to, or whether the release note had been updated. The agents could produce work faster than I could maintain the map of the work.
That’s the important sentence. I didn’t need better project management ceremony. I needed a board I could read, maintained by systems that were already doing the work.
Why not Jira or Linear
Jira and Linear are good products. They’re also built, sensibly, for human teams. They assume people log in, click around, move tickets, comment in prose, and attend the rituals that make the board mean something.
That wasn’t my use case.
Per-seat pricing gets silly when the “users” are disposable agents. Setup friction matters when the thing I want to track is narrower than the setup itself. Most defaults are aimed at social coordination: teams, assignees, inboxes, views, cycles, roadmaps. Useful, if you have humans. Noise, if your workers are processes with API keys.
I could have contorted one of those tools into the shape I wanted: a service account, some glue, half the interface ignored, and a pile of conventions pretending to be a system.
Instead I built the thing I actually needed.
The bit that matters
Kira has a normal web UI because I’m still, regrettably, a human. It has organizations, projects, sprints, milestones, labels, tickets, comments, documents, webhooks, audit logs, work logs, velocity reports, and burndown snapshots. Tickets get keys like KIRA-42. Epics are tickets. Milestones are the roadmap primitive.
The important part is that Kira ships an agent-facing API.
There’s a public, machine-readable skill guide at GET /api/robots/skill. An agent can fetch it, read the REST contract, and then drive the tracker over HTTP with an API key. It can create tickets, update sprint membership, move board status, write comments, and create Documents for release notes. The guide is grounded against the real API source, so it isn’t a stale wiki page I have to remember to update.
That changes the maintenance model. I don’t keep the board accurate by becoming the project-management clerk for my own automation. The agents log their own work. They open tickets, move tasks, and write release notes into Documents as part of the work.
My job is to read the board and make decisions. That’s the part humans are still decent at, on our better days.
Boring on purpose
The architecture isn’t clever, which is one of the few nice things I can say about it without lying. It’s a TypeScript monorepo: @kira/api for the Express server, @kira/web-app for the React 19 / Vite / Tailwind v4 SPA, and @kira/shared for types and enums. Locally it uses SQLite through Prisma. Production uses MongoDB. The whole thing runs as one pm2 process behind a Cloudflare tunnel.
Auth is similarly unromantic. Local JWT auth with refresh-token rotation, or Clerk / Google OAuth in production. Both modes present the same req.userId because every auth system eventually becomes plumbing if you’re lucky.
The domain model is the usual tracker furniture: projects with short keys, tickets with types like STORY, BUG, TASK, and EPIC, comments, labels, sprints, milestones, work logs, documents, webhooks, and audit logs.
This is exactly the kind of software I’d have been embarrassed to build by hand ten years ago. Not because it’s impossible, but because it’s too much surface area for a personal workflow. You’d spend so long assembling the table stakes that the original itch would heal.
Now the boring middle is cheap. Not free. Cheap. Cheap enough that a weekend can buy a tool with the right nouns, the right API, and no subscription screen asking how many synthetic coworkers I’d like to invite.
The new line
The old build-versus-buy question was usually decided by labor cost. Could you justify spending engineering time to avoid a SaaS bill? Usually no. The bill was annoying, but the engineering time was worse.
AI changes that calculation in a lopsided way. It’s much better at generating the standard parts of small software than it is at deciding what should exist. Once I know the shape of the problem, getting to a working internal tool is no longer a heroic act. It’s still engineering. You still have to read the code, run the tests, deploy it, and live with the consequences. But the activation energy is lower.
That makes weird, exact tools rational. A tracker for one person supervising a swarm of agents isn’t a venture-scale product category. It’s barely a category at all, just a use case with my fingerprints all over it.
Now it’s the argument for building it.
The point isn’t “build everything yourself.” That way lies a private graveyard of half-maintained dashboards and a person explaining, with visible strain, why his calendar app has a plugin system. The point is narrower and more useful: the boundary moved. A tool perfect for a use case of one can now be cheaper than buying a general tool and spending your life politely ignoring the parts that don’t fit.