CODEMYBM UK
My first web-dev client: a BMW and MINI coding, retrofit and tuning workshop in Brierley Hill. I rebuilt its one-page GoDaddy template as a full site, in 2 days.

- Role
- Solo, client work
- Timeline
- 2 days, 11 to 12 Oct 2026
- Status
- Preview live, not yet on the client’s domain
- Stack
- Next.js 16, React 19, TypeScript, Three.js
Sources for these facts
- Role: git shortlog: 95 commits, 1 contributor
- Timeline: git log, first and last commit
- Status: curl of both URLs, 15 Oct 2026
- Stack: site/package.json
tl;dr
A workshop that codes and tunes BMWs had a one-page template site with a shop bolted on. I rebuilt it from scratch: a tool that tells you what your car can have, a page for every service, booking over WhatsApp, and a 3D wireframe car you can turn. Lighthouse scores it 90 on mobile and 100 on desktop.Source: site/QA-REPORT.md, section 2
First commit: 21:15 on a Sunday. Last: 17:10 the next day. 95 commits in between.Source: git log, 11 to 12 Oct 2026
One page and a shop
The old site was a GoDaddy Website Builder template: a single page with a GoDaddy store, no menu, no About, Services or Contact pages, a GoDaddy ad bar, an Instagram link with a typo in it, and a privacy policy that said "coming soon".
The people who use it are BMW and MINI owners around the West Midlands, plus remote and trade customers further away. Most arrive on a phone, from Instagram, TikTok or Google Maps. They want three answers, fast:
Source: CodeMyBM research/site-audit.md, sections 0 and 1.1- Can you do my car?
- How much?
- When can I come in?
A checker for 31 chassis codes and a page for each of 22 jobs
Each part answers one of those questions. Every price lives in one file, so the client can change it without a developer.Source: site/CONTENT-GUIDE.md; site/src/data/services.ts
- Check my car
- Pick your chassis from 31 codes across F, G, M and MINI, and see every service sorted into compatible, check first, or not for your car, with prices.Source: site/src/data/chassis.ts, lines 21 to 27; site/src/lib/compat.ts
- 22 service pages
- One per job, from CarPlay activation to MHD tuning, each with its own compatibility checker, FAQ and a generated share card.Source: site/src/data/services.ts; QA-REPORT.md route table
- A WhatsApp booking tray
- Add services as you browse. The tray writes the WhatsApp message for you: car, jobs, VIN, and workshop or remote.Source: site/src/store/booking.ts; site/src/lib/whatsapp.ts
- Live open or closed
- The header says "Open now" or when it opens next, worked out from the opening hours in UK time.Source: site/src/hooks/useWorkshopStatus.ts; site/src/lib/hours.ts
- A 308 redirect for every old URL
- Each GoDaddy address, including the 8 old shop pages, sends people and search engines to the right new page in one hop.Source: site/next.config.ts, redirects(); research/site-audit.md, section 0
- Structured data for search
- Sitemap, per-page titles, and JSON-LD for the business, each service, the FAQs and the breadcrumbs. The Google map only loads when you tap it.Source: site/src/app/sitemap.ts; site/src/components/ui/MapEmbed.tsx

The hard part: a 70 MB car on a phone signal
The design idea was a diagnostic session: wiring, codes, live data. Its centrepiece is "From dash to exhaust", a wireframe BMW M4 CSL that turns as you scroll and shows the services for each of its 6 zones.
The model I started from weighed 70 MB. Nobody waits for that on a phone in a car park.
Source: mockups/DESIGN-NOTES.md; site/src/content/en/carZones.ts; car-preview/model.glb
Draw the edges, hide the back
A script runs once at build time, not in your browser. It keeps only the edges where the surface folds, stored as lines, then adds invisible solid copies of the panels that only write depth. Lines behind the body fail the depth test and vanish, so you see a clean drawing instead of a hairball.
Squeeze what is left
The same script removes the badges, mirrors the car to right-hand drive, and compresses the geometry. 70 MB becomes about 3 MB.
Do nothing when nothing moves
The scene only draws a frame when you scroll, drag or it is easing to a stop. Scroll it off screen and it stops completely. When idle, it costs the graphics chip nothing.
Phones get a drawing
The 3D code never loads on phones. They get a flat SVG line drawing of the same car, made by the same build script. If a desktop browser loses its WebGL context, it falls back to the drawing too.

| Source model | 70,253,276 bytesabout 70 MB |
|---|---|
| After the build step | 3,075,208 bytesabout 3 MB |
| Sent over the wire | 1,733,597 bytesgzipped |
The 3D chunk is about 310 KB gzipped and starts loading 900 px before you reach it, so the first screen is no heavier than it was without the car.Source: CarZonesClient.tsx, lines 340 to 347; QA-REPORT.md
The source model is by Mpgs Studios on Sketchfab, under CC BY 4.0. The credit is shown on the client’s page as well.Source: site/public/models/README.md; site/src/content/en/carZones.ts, lines 25 to 34
Lighthouse 90 on a phone, and 0 axe violations on every route
I measured the production build, not the dev server. Lighthouse figures are the median of 3 runs.
| Performance, mobile | 90 |
|---|---|
| Performance, desktop | 100 |
| Accessibility, mobile | 100 |
| Best practices and SEO | 100 |
| Cumulative layout shift | 0 |
| Total blocking time, mobile | 10 ms |
- axe-core found 0 accessibility violations on every route, at 1440 px and at 390 px.Source: QA-REPORT.md route table
- I checked the layout at 6 widths, from 375 px to 1440 px.Source: QA-REPORT.md
- I tested 17 old GoDaddy URLs. Every one answers with a single 308 to a page that loads.Source: QA-REPORT.md, sections 6 and 9
- A performance pass took the home page from 82 to 90 on mobile. One fix in it: dropping an italic font file saved about 100 KB on every page.Source: QA-REPORT.md, section 2
16 countries stayed, thousands of customers went
A local business site is full of easy claims. I worked to one rule: no claim or number goes on the page unless something backs it up.
Dropped
Thousands of customersNothing I had could prove it, so the site does not say it.
Kept
Customers in 16 countries
I counted the country flags across 948 of the client’s own Instagram captions and found 19 outside the UK. 16 is the safe side of that.
The service copy follows the same rule: it was written from the client’s own captions. And the build fails if any copy contains an em or en dash, which is a rule I have kept on this site too.Source: site/scripts/check-copy.mjs, lines 1 to 30; site/CONTENT-GUIDE.md
Known issues
- It is not live on the client’s domain yet. The new site runs on a preview address, and codemybm.co.uk still serves the old template while a few decisions sit with the client.Source: curl of codemybm.co.uk and the preview, 15 Oct 2026; QA-REPORT.md launch checklist
- The email form has no backend. It checks what you typed, then opens your mail app with the message filled in. WhatsApp does the real booking work.Source: site/src/components/services/contact/EmailForm.tsx, lines 16 to 19
- There is no automated test suite in the repo. The checks above ran from scripts in a scratch folder, so nobody can rerun them from a fresh clone.Source: QA-REPORT.md, lines 6 to 7
What I would do next: move those QA scripts into the repo so they run on every change.
Three chunks in the index point here
Each one is a fact from this page. Ask the full index anything on the home page.
- 1CODEMYBM UK: my first web-dev client, a BMW and MINI coding workshop in Brierley Hill.source: CodeMyBM research/site-audit.md; site/src/lib/site.ts
- 2CODEMYBM UK: rebuilt in 2 days, Lighthouse performance 90 on mobile and 100 on desktop.source: CodeMyBM site/QA-REPORT.md, section 2; git log
- 3CODEMYBM UK: a 3D wireframe BMW M4 CSL, cut from a 70 MB model to 3 MB.source: CodeMyBM site/scripts/build-car-model.mjs; QA-REPORT.md