Client · Live
MVS Global Pools
A pool company in Greenstone, Johannesburg, working across the
country: construction, renovation, leak repairs, pumps and weekly
maintenance. Founded in 2014, eleven staff. A national outlet
profiled the founder in February 2026, and anyone who read it and
went looking found a Facebook page, because there was no website and
no domain. That gap was the entire pitch.
One page, built around 22 photographs they supplied, with no prices
on it. Every pool is a different quote, so the page explains why
there is no price list rather than inventing a starting number.
Enquiries arrive at an address on their own domain.
It started as a cold pitch nobody asked for. It is now a paying
client on a monthly, so the hosting, the DNS, the email routing and
any changes are mine to run. The domain is registered in their name,
not mine, which is where it should stay.
You've been professional, helpful, and patient throughout the
process, and I really appreciate the effort you put into
understanding my business and creating a website that represents
MVS Global Pools professionally. I would definitely recommend
your services to anyone looking for a reliable and professional
web designer.
Madodana Vodloza, Founder, MVS Global Pools
HTML · CSS · JS · Cloudflare Pages
Open the site (opens in a new tab)
Project · Live
Silver Lakes Marketplace
A resident-to-resident marketplace for a Johannesburg gated estate,
built with a co-founder. Auth, listings, offers, in-app messaging with
live updates, wishlists, seller ratings, and an admin panel for
category moderation, reporting and takedown.
Card payments run on Paystack subaccounts with a server-side split: an
item's price settles straight into the seller's own bank account and
only the service fee reaches the platform. The transaction is
initialised server-side and the browser only resumes it, so the amount
and the split can't be edited in devtools. Every table is row-level-
security locked to its owner, and the migrations are tracked in the
repo rather than only in a dashboard.
Live at the domain below since 29 August 2026.
Supabase · Postgres RLS · Paystack · Cloudflare Pages · vanilla JS
Open the site (opens in a new tab)
Code (opens in a new tab)
Project · Live demo
Faircopy
Paste a client's messy brief and get back a proposal you can edit,
save and export. Handed a brief with no budget, no scope and no
deadline, it opens with the three questions it needs answered and
marks itself provisional, rather than inventing a number. Billing,
quotas, webhooks, credit grants and PDF export all work.
The demo needs no account and no API key: it runs on fixtures and
touches no database, which is why it is never the part that is down.
I finished it and then stopped selling it. Proposal tooling for
freelancers is a crowded market where customers churn the moment
they land the contract that made them sign up. Nothing failed
technically. It is here as work, not as a product.
Next.js 15 · Supabase · TypeScript · Anthropic API
Open the demo (opens in a new tab)
Code (opens in a new tab)
Project · Playable
Syzygy
A small planet you roll a marble around, in the browser. Gravity
points at the centre of the planet instead of downwards, so there is
no floor and no edge: roll in one direction for about fourteen
seconds and you arrive back where you started. Five monuments stand
unlit on the surface: the four projects below, and one that is how
you reach me. Light all five and dawn breaks over the whole planet.
25 modules, roughly 7,000 lines, and one image file in the entire
repository. No build step, no package.json and no game engine. The
terrain, the sky, the monuments, every piece of in-world type and
every sound are generated at runtime. Collision is hand-rolled
sphere against sphere and sphere against capsule, and the ground is
an analytic sum of sines, so it can be sampled without touching the
mesh.
Three.js r169 · Web Audio · Supabase
Open it (opens in a new tab)
Code (opens in a new tab)
Client · Live
Kohi by Ifuku
A coffee shop, micro-gallery and jazz kissa at 44 Stanley in
Johannesburg. Menu, hours and directions, built to load instantly on
a phone in the queue. Still mine to maintain.
HTML · CSS · JS
Open the site (opens in a new tab)
Project · Running
Vivarium
A personal, non-client artificial-life simulation. A free simulate
loop runs every five minutes with no LLM involved: grazers and
hunters in a predator-prey relationship, terrain, a day-night cycle.
Separately, a guardrailed evolve loop calls Claude Code CLI a few
times a day to propose one real code change to the simulation's own
rules.
The interesting part is the guardrail engineering, not the ecosystem
content: a working pattern for letting an LLM modify its own codebase
without needing to trust it, because every constraint is enforced in
code rather than asked for in the prompt. Evolve can only write three
paths, a diff cap measured against the actual changed lines, not file
length, holds it to 900 lines and 8 files a run, and a daily budget
caps it at three runs. The 17-test suite has to pass before anything
commits. A rejected or failing proposal is reverted whole, never
partially applied.
Seven evolve runs so far, one landed. Four were rejected by a
guardrail bug that measured proposed files' full length instead of the
real diff, making success mathematically impossible until it was
caught and fixed on 2026-09-04. One failed to parse as JSON, one was
reverted when a fix broke on a test that didn't model real terrain. The
one that landed gave grazers a camouflage gene: it shrinks a hunting
hunter's effective sense range specifically against that grazer, and
grazers now visibly fade toward the background in proportion to it.
Python · vanilla JS/Canvas · Cloudflare Workers/KV · Windows Task Scheduler · Claude Code CLI
Code (opens in a new tab)
Watch it (opens in a new tab)