My process - How I work
Three phases, roughly. They overlap more than this page suggests, but the order is real: understand the problem, build it properly, then make sure it holds up once people are using it.

Discover
I start by getting clear on the problem rather than the feature list. Who uses this, what breaks today, and what has to be true for the thing to be worth building.
That usually means reading whatever already exists — the current codebase, the data model, the support tickets — and asking the questions that surface constraints early. Auth boundaries, tenancy rules, and anything real-time are worth finding now rather than halfway through.
I come back with a plan: what I'd build first, what I'd deliberately leave out, and where the risky parts are.
Included in this phase
- Intense brainstorming sessions
- Feasibility checks that make sense
- Design mockups (approved after team debates)
- Employee-friendly surveys
- Proofs-of-concept that actually work
- A game plan to bring it all together

Build
I build in slices that ship. Rather than finishing the frontend and then starting the backend, I take one real path through the product — interface, API, data — and get it working end to end, then repeat.
Types are shared across the stack so the frontend and the API can’t quietly disagree, and tests get written alongside the code rather than bolted on before a deadline. I use AI coding tools throughout; they make the mechanical parts faster, they don’t replace the review.
You see it running as it goes. No long silences followed by a big reveal — it’s easier to change direction in week two than in week ten.

Deliver
Shipping is the start of the interesting part. I care about how the thing behaves once it has real traffic on it — slow queries, race conditions, the edge cases nobody hit in staging.
Before launch I go through the boring checklist properly: accessibility, error states, loading states, what happens on a bad network. These are the parts that get skipped under deadline pressure and they're the parts users actually notice.
After launch I'd rather hand over something you can maintain than something that only I understand. That means readable code, written decisions, and a working local setup.
What this includes
- Testing. Coverage where it earns its keep — business logic, auth boundaries, anything with money or permissions attached.
- Deployment. CI that runs the tests, preview builds per branch, and a rollback that works when you need it at 2am.
- Handover. Documentation for the decisions rather than the syntax, and access to every account and key that matters. It's your product.
How I decide - What I optimise for
Most technical decisions are trade-offs, not right answers. These are the ones I lean on when a call has to be made.
- Boring where it counts. I'll reach for the proven option in the parts that have to stay up, and save the newer tooling for places where being wrong is cheap.
- Typed end to end. The frontend, the API, and the database agreeing on shape catches a whole class of bug before anyone runs the app.
- Accessible by default. Keyboard navigation, focus states, and real semantics from the first commit. Retrofitting accessibility costs several times more.
- Secure boundaries. In multi-tenant systems, tenant isolation is enforced at the data layer — not left to whichever query someone writes next.
- Measured, not guessed. Before optimising anything I want a number for how slow it is now. Most performance intuitions are wrong.
- AI with review. I use Claude Code and Copilot daily. They write a lot of the first draft; nothing lands without me reading it.