EngineeringMarch 15, 202612 min read

Built with Claude Code: How We Shipped a 187-Page Engineering Platform in 6 Months

Koalr is an engineering metrics platform. We built it almost entirely with Claude Code — Anthropic's AI coding assistant in the terminal. Here's the honest account: what worked, what broke, and what surprised us.

187+

Dashboard pages

126

API modules (NestJS)

16

Integrations

65+

Prisma models

40+

Test specs

6 months

Time to build

The context

Koalr tracks DORA metrics, deploy risk, AI tool adoption, code coverage, incidents, and 30+ other engineering signals across GitHub, Jira, Linear, PagerDuty, Cursor, Anthropic, and 12 more integrations. The dashboard has 187 pages. The NestJS API has 126 modules. There are 65 Prisma models.

One engineer built this in roughly 6 months, with Claude Code as the primary coding partner. Not as a co-pilot reviewing suggestions — as the primary implementer of most features, with the human as the architect and reviewer.

This is a specific way of working that's different from casual AI assistance. The human writes the plan; Claude Code writes the code; the human reviews, tests, and directs corrections. It requires a different skill set than traditional software development — closer to technical management than IC engineering.

What actually worked

Repetitive module scaffolding

Building the 12th NestJS integration module is nearly identical to the 1st. Claude Code generates the controller, service, module, and spec in a single pass. What used to take 45 minutes takes 3. This is where the 10× productivity claim actually holds up — not in complex business logic, but in the taxonomy of 'one more thing that works like everything else.'

Test spec generation

Claude Code writes thorough vitest specs with realistic mock factories — the kind you'd actually commit. It naturally covers happy paths, error cases, and edge cases without being asked. The main pattern it learned after our first correction: never mock the constructor, use helper factory functions instead.

Debugging its own changes

When a TypeScript build failed after a schema change, Claude Code read the error, traced the type chain, found the missing Prisma regeneration step, and fixed it in one go. Context continuity across a multi-step fix is genuinely useful.

Documentation and SEO content

Blog posts, integration docs, marketing use-case pages — Claude Code generates high-quality, accurate technical content. This blog post is a good example. The key: feed it real data and let it structure the narrative.

Commit message discipline

Our codebase enforces conventional commits via commitlint. Claude Code learned our exact scope list and writes commit messages that pass the hook every time. We never fight with it about this.

What broke (and what we learned)

Context limits on large files

Files over ~1,200 lines become unreliable — Claude Code loses track of earlier sections and produces edits that conflict with existing code. Our fix: enforce file-size constraints early. Every service over 300 lines gets split before it becomes a problem.

Over-engineering on the first pass

Ask for a simple feature and you'll sometimes get an abstraction layer, a generic utility, and three interfaces before any implementation. We learned to be explicit: 'just implement this, no abstractions, no future-proofing.' The CLAUDE.md rule against over-engineering helped significantly.

Missing FK dependencies

Claude Code occasionally deletes a DB relation without checking all references first. We caught this twice in production migrations before learning to always grep ALL FK references before any deletion. Now part of our standard checklist.

Hallucinated API shapes

When working with external APIs (Cursor, Anthropic, LaunchDarkly), Claude Code sometimes invents response fields that don't exist. We always verify against actual API docs before trusting generated type definitions. "Trust but verify" is the right mental model.

The pattern that changed everything: CLAUDE.md

Claude Code reads a CLAUDE.md file from the repo root at the start of every session. This is where you encode your project-specific rules, architectural constraints, and anti-patterns.

Our CLAUDE.md enforces:

  • Client/server API boundary (api-client.ts is server-only, client-api.ts is browser-safe)
  • No over-engineering — three similar lines > premature abstraction
  • Never import from @prisma/client — always use @koalr/db
  • Conventional commit format with specific allowed scopes
  • Standard layout components for all new pages
  • ESLint rules as error-level blockers

Without CLAUDE.md, Claude Code builds technically correct code that violates your project conventions. With it, the output is consistently production-quality on the first pass.

The productivity numbers

A full feature — backend module, frontend page, tests, docs — that would take a senior engineer 2-3 days takes 2-4 hours working with Claude Code. That's roughly 5-10× on features that match the pattern (integration modules, dashboard pages, CRUD endpoints).

The multiplier drops for novel business logic, complex algorithms, and anything requiring deep system knowledge that Claude doesn't have. Deploy risk scoring, forecast accuracy computation, ML model architecture — these required significant human expertise alongside AI assistance.

Net result over 6 months: a product that would normally require a 5-person engineering team to build, built by 1 person. The velocity is real. The tradeoff is higher architectural burden on the human — you need to think 3 steps ahead because you're directing, not coding.

The meta-irony

We built an engineering platform that tracks AI tool adoption — including Claude Code usage, token consumption, and productivity impact — using Claude Code to write most of the code. The AI Analytics dashboard Koalr shows your engineering team is the same one we use to measure our own development velocity. We know exactly how many tokens it took to build this.

Track your team's Claude Code usage

Koalr connects to your Anthropic API account to track daily token consumption, spend, and model breakdown across your engineering team — the same metrics we use internally.

Get early access →