TypeFirst is live
typefirst.io is live.
We already had the code. ts-bedrock
has been our starting point for every project for a year, and it works — a
shared Core binding an API to a frontend, five levels of types, escape
hatches banned by lint. What it could not do was answer the question we get
every single time someone new opens it.
Not what the rules are. Why.
A repository shows the how and hides the why
Read Core/Data/Email.ts and you will see an opaque type with a smart
constructor. You will not see the afternoon that produced it: the bug where a
raw string reached a mailer three layers past the only place that ever
validated it, and the review where we realised the validation had been correct
and useless because nothing carried the proof forward.
Every rule in ts-bedrock has an afternoon like that behind it. Stripped of the
story, the rule reads as ceremony — and ceremony is the first thing a
reasonable engineer removes under deadline. "No as" sounds like pedantry
until you have watched a single cast quietly change what a function is allowed
to receive.
So the site is the missing half: the arguments, with the failures that produced them.
What is on it
- The principles, each with the failure mode it prevents — banned escape hatches, never throw, decode every boundary, opaque types, impossible states.
- Learn TypeFirst, five lessons from immutability to opaque types, for someone who has never written a decoder.
- Build Your Own Bedrock, sixteen parts that rebuild the whole Core from an empty directory, one file at a time, explaining each design decision — ending with how to carry the same ideas into a language that is not TypeScript.
- In production, the patterns that only appear once a system is live: state machines that grow a variant, IDs that collide, confirmations that arrive after the response.
And, deliberately, five bugs our types didn't catch — an adversarial review of a heavily-typed codebase, published with the findings intact. A methodology that only publishes its wins is marketing. The interesting question was never "do types help", it is which mistakes survive them, and the answer turns out to be specific and learnable: types check shape, not meaning.
Why publish a house style at all
Two reasons, both selfish enough to be durable.
The first is that writing it down changed it. Three of the rules got shorter under the pressure of having to justify them in public, and one turned out not to survive its own argument.
The second is hiring and handover. A client inherits our code eventually. A repository plus a link beats a repository plus a promise that someone will explain it later.
None of it is novel. Sum types, decoders at the boundary, errors as values — this is old functional-programming furniture, carried into TypeScript and enforced by a linter. What is ours is the insistence that it be total: a rule followed 90% of the time provides 0% of the guarantee, because you still have to check.
typefirst.io. Free, open, and argumentative.