Portfolio

Selected work, delivered and in progress

Client work and my own products across both service lines: web projects from single-page catalogues to real-time dispatch, and the bookkeeping engagements I run alongside them. Most of the web work is bilingual, and most of it runs on budgets where a recurring dollar-denominated API bill would sink the project — which shapes the technical choices more than anything else.

Client names are withheld where I don't yet have written permission to use them. I'm happy to walk through any of these in detail, including the parts that didn't work.

In development

2 projects

Dispatch system for a taxi drivers' association

In development

2026 · Santa Cruz de la Sierra, Bolivia

A 25-vehicle association coordinating every trip through WhatsApp groups, replacing that with a real dispatch platform.

Problem
Voice and text coordination doesn't scale, leaves no record of who took which trip, and gives the association no way to show a passenger which vehicle collected them.
Approach
Vehicle location from the drivers' own smartphones rather than dedicated trackers, which removes the hardware cost per vehicle. A configurable assignment engine with four methods — manual, broadcast-and-claim, nearest vehicle, and FIFO by zone — so the association can choose what matches how they already work. Map tiles self-hosted with PMTiles rather than a commercial map API, keeping monthly running costs at roughly the price of a tank of fuel instead of a dollar-billed subscription.
Current state
Technical plan complete. Working demo in build, with a separate spike validating background geolocation on low-end Android handsets — the single biggest technical risk in the project.
Node.jsPostgreSQLPostGIS MapLibrePMTilesWebSocket AndroidEspañol

VAT receipt splitter for UK small businesses

Own product · in validation

2026 · United Kingdom

A tool that splits mixed-rate supermarket receipts into their correct VAT categories — a problem I hit every week doing my own bookkeeping.

Problem
A single supermarket receipt routinely mixes standard-rated, zero-rated and reduced-rate items. Splitting it correctly by hand is slow and error-prone, and getting it wrong quietly distorts the VAT return.
Approach
A product SKU database mapped to VAT treatment, with a lightweight web tool that exports a ready-to-import journal. Deliberately sequenced validation-first — community listening, then a lead magnet, then a decision gate — rather than building on the assumption that the problem is worth paying for.
Current state
Pain point validated, SKU database and pricing model drafted, stack chosen. Not yet built; the decision gate comes first.
SvelteKitCloudflare PagesUK VATExcel

Delivered

3 projects

Website and booking system for an Italian restaurant

Delivered

2025–2026 · Putney, London · ostunirestaurant.com ↗

A neighbourhood restaurant taking its own bookings, instead of routing every table through a platform that charges per cover.

Problem
Reservations arrived by phone in the middle of service and through a commission-charging booking platform, so the restaurant paid per head for tables it had already earned and kept no record of its own guests.
Approach
A five-step booking flow — date, time slot, seating preference, guest details, confirmation — on Supabase, with an admin view for the floor team. Google Places and Reviews are read live so opening hours and ratings can never go stale. Built as plain HTML with Tailwind and small vanilla-JS components rather than a framework, so someone non-technical can edit the menu without a build step, and packaged as an installable PWA.
Outcome
Live. Full multi-page site — menu, events, reservations, contact, legal — with structured data throughout, and the component structure kept deliberately plain so handover doesn't require a developer on retainer.
Tailwind CSSSupabaseVanilla JS Google Places APISchema.orgPWA

Website for a plumbing business

Delivered

2026 · Valencia, Spain

A plumbing business with nothing of its own online, given a site that sets out the full range of what it does.

Problem
The business had no site of its own — no way to set out the range of work it takes on, and nothing to point a prospective customer at beyond word of mouth.
Approach
A straightforward marketing site in Spanish, covering the services evenly rather than leading on any single one, with a contact form that routes enquiries straight to the owner. I later rebuilt it on Next.js with Tailwind v4 to improve performance, moving form handling to react-hook-form and zod, and transactional mail to Resend so delivery is observable rather than assumed.
Outcome
Delivered in Spanish and running on Vercel. The rebuild was a performance decision rather than a redesign — same content, same structure, faster to load — with the original build kept in the repository alongside a note recording what changed and why.
Next.js 16Tailwind v4TypeScript ResendzodVercelEspañol

MediMemo — medicine tracker

Own product · public beta

2026 · medimemo-beta.vercel.app ↗

A medicine tracker that keeps health data on the phone it was entered on — no account, no server, no exceptions.

Problem
Almost every medication adherence app requires an account, which means routine health data leaves the device and becomes somebody else's liability to hold.
Approach
Built entirely client-side. State lives in the browser under a versioned schema so an update never discards existing history, charts render locally, and a service worker pre-caches the shell so it opens and works with no connection. There is no backend to breach because there is no backend.
Outcome
In public beta. The architecture is the product decision: dropping the server dropped the analytics, the sync and the recurring cost, and left something genuinely private rather than privacy-policied.
PWAService workersES6 modules Chart.jsOffline-firstVercel

Ongoing

2 projects

Web platform for an FM radio station

Ongoing

2026 · Santa Cruz de la Sierra, Bolivia · stereo97.com ↗

Maintaining the web platform for an established station with a very large social following and comparatively little of its own audience.

Scope
Keeping content, integrations and technical documentation current on the station's site, working bilingually with internal teams and external suppliers across two time zones.
Approach
The strategic problem is that a rented social audience converts poorly into an owned one. I produced an analysis of the station's public presence and three competing landing page directions — one built around the live player, one around the on-air personalities as the underused brand asset, and one around a visible commercial door for advertisers, since that is where the revenue actually is.
Next.jsApp RouterSupabase Streaming embedContent opsEspañol

Website for a London futsal league

Ongoing

2020–2026 · London, United Kingdom · londonfutsalleague.com ↗

A community futsal league running across London venues — six years of continuous work on one codebase.

Scope
Team and player registration, league tables, results and fixtures, media galleries and venue information, kept current season after season.
Approach
Eleventy with Nunjucks templates and no frontend framework. Tables and fixtures are data files rendered at build time, so updating a matchweek is a data edit rather than a deployment risk — which matters when the person updating it is a volunteer on a Sunday night. CSS through PostCSS, JavaScript minified with Terser, installable as a PWA for players checking fixtures pitch-side.
EleventyNunjucksPostCSS Vanilla JSPWAStatic hosting

Earlier work

Independent web development

Various

United Kingdom / Bolivia

Web applications for small business and media clients, taken from requirements through to delivery single-handed.

Scope
Single-page applications, service workers for offline reliability on poor connections, and data reconciliation between systems and third-party integrations — the same accuracy discipline I apply to ledger work, applied to data.
JavaScriptNode.jsHTML & CSS SPAsService workers

Accounting

3 engagements

Finance function for a London restaurant

Ongoing

United Kingdom · Limited company

Sole charge of the books for a hospitality business, from daily takings through to VAT return preparation.

Scope
Daily transaction capture and coding, bank feed and batch payment reconciliation, payroll journals, and VAT returns including mixed-rate apportionment.
Approach
Tips are handled through a liability account rather than buried in revenue, and card settlements are reconciled against POS reports so the two never quietly drift apart — the difference between books that balance and books that merely close.
XeroHubdocEpos Now Evo PaymentsUK VATLimited company

Bookkeeping for a domestic cleaning business

Ongoing

United Kingdom · Sole trader

Books for a sole trader providing cleaning services to private households.

Scope
Transaction capture and categorisation, bank reconciliation, and books kept current month to month rather than assembled in a hurry at year end.
Approach
Set up in QuickBooks Online so the owner can raise invoices and capture receipts from a phone between jobs, which is the only way records stay current for a business run single-handed.
QuickBooks OnlineSole traderBank reconciliation

Bookkeeping for an elderly care and housekeeping business

Ongoing

United Kingdom · Sole trader

Books for a sole trader providing companionship, care and housekeeping to elderly clients in their own homes.

Scope
Day-to-day bookkeeping on the same QuickBooks Online footing: income and expense capture, bank reconciliation, and a clean set of records handed over ready for the year-end return.
Approach
The chart of accounts keeps care hours and housekeeping separate, so the two sides of the work can be read independently rather than averaged into one figure.
QuickBooks OnlineSole traderChart of accounts

Something similar in mind?

If you're weighing up whether a project is worth building at all, that's a useful conversation to have before anyone writes code. I'll tell you if I think the answer is no.

Send an Email Back to home

Send a message

Your details are used only to reply to this enquiry. Nothing is stored on this site and nothing is shared. Privacy