About
I build software end to end.
Frontend, API, database and deployment. Owning all four is what stops awkward decisions being made at a boundary, by whoever happens to be standing on the far side of it.
At a glance
- Experience
- 5+ years
- Day job
- Data engineering
- Based in
- Nairobi, Kenya
Most of what I build starts as a question about how something works and ends as a running product with real data in it, real money moving through it, and someone other than me using it.
In practice that means the person who designed the endpoints is the one who has to live with them in the UI, so the shapes that do not fit get fixed rather than worked around. Payment gateways, geospatial queries, real-time sockets and third-party data feeds are the pieces I’ve had to make behave in production.
I’m as useful in a codebase I didn’t write as in one I did. Reading unfamiliar architecture, tracing why something breaks and not only where it surfaces, extending what is there instead of proposing to replace it: that is most of the job on any real team, and I’m equally happy doing it on an open-source project.
The work I’m proudest of is mostly invisible: error handling that says the same thing everywhere, access control with more than two answers, uploads that check what a file is and not what it is called, interfaces that work from a keyboard. None of it demos. All of it is the difference between something that runs and something that can be relied on.
Currently
Deepening
Testing discipline and the operational side of shipping: logging, migrations and safe rollbacks.
Exploring
Where AI tooling earns its place in a web product instead of decorating it.
Next in the stack
Converting these projects from JavaScript to TypeScript, starting with the API layer where the contracts already exist.
Available for
Full-time, contract and freelance work, remote. New builds, existing codebases, or open source.
Background
5+ years, mostly on data that did not want to be collected.
Data engineering by day, full-stack the rest of the time. The projects I can show are the public part of the work; the crawlers and pipelines are not mine to publish.
Data Engineer, Web Scraping & ETL
Jan 2021 to present · Remote
Legal research platform
Production crawlers and parsers in Node.js and Python, ingesting high-volume datasets from web platforms built to keep programs out. The obstacles are the job: dynamic DOM execution, pagination that changes shape, rate limiting, CAPTCHAs and modern anti-bot systems. Downstream of the crawl, ETL pipelines clean, validate and transform what comes back before it reaches a search index or an analytics surface.
- Crawler architecture
- ETL pipelines
- Parser performance
- REST integrations
Full-stack Developer
Oct 2022 to present · Remote
Freelance
Custom web applications and backend systems for clients, built on React, Next.js, Node and Express. REST APIs, Stripe and PayPal integrations, and PostgreSQL and MongoDB schemas modelled for the traffic they would actually see.
- Client delivery
- Payments
- Schema design
How I work
Four defaults I don’t argue about
Most decisions in a build are small and get made fast, which means they get made by whatever the default is. These are mine, and they are the ones I hold to when nobody is looking at that part of the code.
The data model comes first.
Names, relationships and what is allowed to be missing get settled before any framework does. Everything above inherits those decisions, and they are the only ones that get more expensive every week they stand. A record should store what actually happened, not a pointer to something that can change underneath it later.
The client asks; the server decides.
Anything a user could benefit from misreporting is resolved server-side: a price, a total, a role, the contents of a file. The browser is an interface to the rules, never a participant in them, and a file is whatever its bytes say it is, never whatever its name claims.
One rule, one place.
A rule applied at each call site is a rule that will be missed at the next one, and the next one is always written under time pressure by someone who has not read the first. A single composed check decides who may see what, so a new endpoint inherits the rule instead of having to remember it.
Assume it will need recovering.
Software is easy to write and hard to keep running. Seeds, migrations, exports and a scripted way back to a known state decide whether a bad afternoon is survivable. They get written while things are calm, because they cannot be written while things are not.
Capabilities
What I actually do
The areas of the stack I work in, described by the work I do in each, not by how highly I’d rate myself.
Frontend
Component architectures that stay legible past the first thousand lines. Routing, data fetching, form state and accessible interaction are each decided once and applied everywhere.
- React
- React Router
- Tailwind CSS
- Framer Motion
- Vite
Backend & APIs
REST APIs that keep one shape from the first endpoint to the last: routed controllers, typed error classes, centralised error handling, and JWT auth with role-based access, never a boolean admin flag.
- Node.js
- Express
- JWT
- REST
- Multer
Data
Both sides of the SQL/NoSQL divide. Mongoose schemas with geospatial indexes and aggregation, and hand-written SQL migrations against PostgreSQL with no ORM in between.
- MongoDB
- Mongoose
- PostgreSQL
- SQL migrations
Scraping & pipelines
Collecting data nobody published for the purpose, and making what comes back trustworthy: crawlers that survive a site changing shape underneath them, and ETL that cleans and validates before anything downstream is allowed to depend on it. This is the one capability here whose output is not a screenshot.
- Puppeteer
- Playwright
- Scrapy
- Cheerio
- Python
- SQL
Delivery
Getting it running somewhere other people can reach it, and keeping it there: split frontend and API hosting, environment-scoped config, containerised builds, seed and ingestion scripts, and third-party data pulled from live APIs, never fixtures. Where it lands is a per-project decision, and none of the setup is tied to it.
- Docker
- CI from Git
- Managed databases
- Cloudinary
Toolkit
Technologies I work with
That’s the pitch.
If it sounds like the person you need, tell me what you’re building and where it’s stuck.