← Back to work
Case Study
spec-driven-developmentisochronesgeospatialcloudflare-workersr2mapboxtanstack-querypythonreact

Spec-Driven Development: IsoHome

At Great Yellow, our lead engineer has been investigating spec-driven development — the practice of writing structured specifications that an AI coding agent can execute with minimal hand-holding, rather than vibe-coding from scratch. This video has a good explainer of the general idea.

I used start-work as a lightweight starting framework — a set of Claude Code skills that enforce a brief → spec → plan → execute workflow — and gave it a real problem: find the best places to live within a given commute time of London. The result is IsoHome, built in roughly four hours from a dictated brief to a live deployment. The source is public.

We’ve since moved to spec-kit from GitHub — a more comprehensive toolkit that formalises the full lifecycle: constitution (project principles), specify (product scenarios), plan (technical implementation), tasks, and implement. It supports Claude Code natively and enforces the discipline that start-work hinted at. We’re leveraging it at Great Yellow on production codebases where the stakes are higher and the specs need to be more rigorous.

What IsoHome does

The core question: for a given time budget (say, 60 minutes), which areas of the UK can you commute from to a London terminus? Areas of equal travel time are called isochrones — hence the name.

But reachability alone isn’t enough. You also want to know which of those reachable places are actually desirable. IsoHome overlays four weighted data layers as a heatmap inside the isochrone boundary:

LayerSourceWhat it measures
SunshineMet Office climate averagesAnnual sunshine hours (900–1,900 h/yr)
House priceLand Registry Price Paid DataMedian price by postcode district
Crime ratedata.police.ukCrimes per 1,000 population per year
DeprivationEnglish Indices of Deprivation 2025IMD score per LSOA

Users control a multi-select of terminus stations, a time slider, transport mode toggles, and per-layer weight sliders (0–10). The desirability score at each point is a weighted average of z-score-normalised values — so a location at the population mean always scores 0.5, regardless of which isochrone is visible.

Architecture

The key architectural decision was pre-computation over runtime computation. All the expensive work — fetching train timetables from the Transport API, computing drive-time polygons via a self-hosted OpenRouteService Docker instance running the full GB road network, enriching with environmental data — happens offline in a Python pipeline. The pipeline is checkpoint-resumable and rate-limited against upstream APIs.

The output is a set of static GeoJSON files (one per terminus per time bucket), uploaded to Cloudflare R2. The Cloudflare Worker at runtime is a pure key-value proxy — zero computation, just serving pre-built files. Fast, cheap to run, and scales without thinking about it.

On the frontend, a React SPA uses Mapbox GL JS for rendering and TanStack Query for data orchestration — firing parallel fetches for multiple terminus isochrones with staleTime: Infinity for static layers that only need loading once per session. The desirability scoring engine runs entirely client-side: grid sampling within the isochrone polygon, z-score normalisation against fixed population statistics, weighted aggregation, and rendering as a heatmap with zoom-adaptive radius. MSW provides a full mock API layer so the frontend runs without any backend during development.

The spec-driven process

The initial prompt was dictated — badly — into a brief. From there, the process produced a structured SPEC.md and a phased PLAN.md before any code was written. Claude recommended a lead agent on Opus 4, with sub-agents on Sonnet 4 (it recommended against full agent teams — the plan was straightforward enough, and cheaper this way).

The experience was good. Not transformative, but noticeably better than an unstructured session. The specs gave the agent clear boundaries and acceptance criteria, which reduced drift and rework. For a weekend experiment, the output-to-effort ratio was impressive — and the approach has since informed how we structure agent-assisted development at Great Yellow on production codebases.