How we build
Small team, shared foundations
Every Harbor Media product is built the same way, from the same parts, and checked the same way before it ships.
The approach
Six habits we build by
None of these are clever. Doing them every time is the point.
-
Start from building blocks
Harbor Forge keeps the parts every product needs (sign-in, the server, the database, logging, deploys, CI) as versioned blocks. A new product is composed from them, and records which versions it uses.
-
Share one sign-in
Our identity server handles login for the apps built on it, with two-factor and passkeys. The apps never see a password; sign-in tokens stay on the server.
-
Use one design system
Colour, type and spacing come from one set of tokens, in light and dark. A contrast check runs in CI, so an unreadable colour fails the build.
-
Test what people actually use
Unit tests run on every change. After a release, smoke checks hit the live site and its API, and a failed check rolls the release back.
-
Ship to the web, iPhone and Android
Native Swift and Kotlin apps for each phone and a fast web front end, all talking to one server. iPhone builds go to TestFlight for testing before anything else.
-
Check it where people see it
A healthy server is not the same as a working page. We open it in a browser, at phone width as well as desktop, and install the build on a phone.
Harbor Forge
The block catalogue, as it prints
This is real output from our command line. Every block is marked beta: a block only earns stable by surviving real use.
$ hm-forge catalogueauth beta auth-bff 1.0.0 auth.session auth.oidcbackend beta node-app 1.1.0 http.server secrets.envdatabase beta db-postgres 1.0.0 db.postgres db.migrationsdeploy beta deploy-droplet 1.6.1 deploy.release deploy.rollbackobservability beta obs-health-version 1.0.0 obs.health obs.version beta obs-logging 1.0.0 obs.loggingci beta ci-node 1.0.0 ci.node ci.deploy ci.secretscan$
The stack
What it's made of
-
Phones
Swift and SwiftUI on iPhone. Kotlin on Android.
-
Web
Astro for sites like this one, React and Next.js for web apps.
-
Servers
Node.js and PostgreSQL, behind nginx, on DigitalOcean.
-
Identity
Keycloak, with OpenID Connect and passkeys.
-
Releases
GitHub Actions: tests, build, deploy, smoke checks and rollback.
-
Design
One token file for colour and type, generated for every surface.
Rules we keep
Things we don't do
-
Write our own login code
Sign-in comes from the shared identity server, never from code written fresh for one app.
-
Build ahead of a need
A block gets built when a product actually needs it, not to round out a catalogue.
-
Write legal documents
Lawyers write terms and privacy policies. We write software.
-
Overstate where things are
Every product on this site carries its real status, including the paused ones.
Get in touch
Curious about how something works?
Ask. We're happy to talk about how we build.
Or email [email protected]