Timeline
How Sapphire was built — from the first idea to 1.0 and beyond.
Click a season to open its phases · Click a phase for details
Sapphire starts as an idea: define a data shape once and emit a schema for every ORM. No code yet — just the problem and the goal.
The concept gets a first hand-written implementation — no real structure, just enough to show the one-schema idea could work.
An architectural refactor: fields no longer know about any ORM, and adapters are resolved by name through a registry. The project was still called "Ruby" at this point.
The builder API becomes immutable and TypeField is pulled out of type inference, making the inferred types tighter and more predictable.
Release plumbing: continuous integration, lint and formatting rules, the package exports map, and a prepublishOnly guard.
The codebase moves into a monorepo — packages/core and packages/mongo — with a dual ESM + CJS build.
Field is reworked into a brand-type, and Infer derives a precise TypeScript type straight from the schema definition.
A real validation API lands: parse and safeParse, returning structured issues, with a message hierarchy for custom error text.
The full modifier vocabulary is completed, and the adapter registry moves from an ORM enum to string keys — opening the door to third-party adapters.
New field types — tuple, literal, enum, record and ref — plus a homogeneous ArrayField and a named-schema registry, built on a new intermediate representation.
ObjectField gains composition operators — pick, omit, partial, required, extend, merge — plus schema-level options like timestamps and indexes.
The Mongo adapter is rewritten from the ground up so it honors every part of the intermediate representation.
A new package converts the Sapphire IR into a JSON Schema 2020-12 document.
A new package emits Drizzle table definitions — pgTable, mysqlTable and sqliteTable — from the IR.
No new runtime code — this phase produces /docs, runnable examples, a rewritten root README, and a docs check wired into CI.
A pass comparing the V1 design and plan against the real code, plus a triple QA audit of test coverage, benchmarks, and type-level tests.
Acting on a large code review: 6 correctness bugs, 5 API/IR inconsistencies, 10 code smells, and 4 documentation drifts.
A second round of bugs, inconsistencies and smells — the items the earlier passes left behind, cleaned up on main after PR #16.
Planning the split of sapphire-mongo into a Mongo-native package and a separate sapphire-mongoose package.
A heavy review of the whole library, hunting for bugs, inconsistencies and smells before going public.
npm-publish readiness — changesets, packaging and release workflows — culminating in the 1.0.0 release.
refine adds custom synchronous validation — arbitrary single-field predicates and cross-field rules — expressed inside the one schema.
Async refine plus parseAsync / safeParseAsync, for rules that need to hit a database — uniqueness, existence.
llms.txt and llms-full.txt, plus a Context7 listing, so AI coding assistants generate correct Sapphire code instead of guessing the API.
Clearing the leftover code-review backlog and adding a real-MySQL integration test to CI.
A typed .adapter() via module augmentation, and mock-data generation from a schema. A sketch — not yet planned in detail.
A fifth adapter, sapphire-prisma, emitting a .prisma schema — a text DSL, unlike the runtime-object output of the other four. A sketch.