Fireproof Logo

Beta is available

Today we shipped a fresh codebase written in TypeScript, that is compatible with existing useFireproof React hook installs. Some highlights:

  • 1/3 the lines of code (from 3410 to 1137!)
  • Tree shakeable imports
  • Exported types for IDE inline documentation

Everything is cleaner about this new beta, except the esbuild output is seeing public feedback for the first time. Experts are encouraged to help with the bundler effort. One of the big lessons I learned as a co-founder of Couchbase, is that in infrastructure software it’s better to optimize for simpler implementations, and upgrade them all the time, than to build complex irreplaceable systems. This aligns with Fred Brook’s advice in the Mythical Man Month to “write one to throw away.”

The main new feature is that it's much easier to reason about the code. Here's a quick tour (of 0.11.2). First, almost all the code is in the src directory. The fireproof.ts file is the entry point, and it exports the main fireproof and index functions, separately for tree-shaking. Database.ts implements the public API, and orchestrates the CRDT's write queue and listeners. The CRDT class uses Alan Shaw's Pail library which is compatible with w3clock so we can broadcast updates. The CRDT class also manages indexes, which use Mikeal Roger's Prolly Trees for sharable index data structures, driven by a map function architecture inspired by CouchDB.

The rest of the implementation is behind-the-scenes. The TransactionBlockstore class uses pluggable Loaders which track updates as logs of CAR files and can compact the database to a single CAR file.

The only real API difference to look out for is a consequence of optimizing for tree-shaking. Instead of importing a global object and instantiation the database from there, and indexes from the database, your import fireproof and index at the top level, so for apps that don't need indexes, they don't have to load the code. It looks like this now:

import { fireproof, index } from '@fireproof/core'

const db = fireproof('my-app')
const ok = await db.put({ fieldName: 'value' })
// index on doc.fieldName
const myIndex = index(db, 'fieldName')
const result = await myIndex.query()

To anyone who is caught by this change, thank you for being an early adopter, your feedback is making Fireproof better.

Beta release status

The latest versions of @fireproof/core and use-fireproof are now available on npm. We are updating the website and documentation at the time of this writing.

Existing demos will be rolled to the new package soon, but it's worth noting that upgrading the use-fireproof package should "just work" in your existing apps. There's a known issue with a workaround for create-react-app

Features that are not yet implemented in the beta:

  • Snapshot and undo APIs: The underlying data structures are still there, but we didn't want to implement API support without a real world use case. Except undo to be added during the demo app upgrade cycle.
  • Sync: This was mostly an application-level proof of concept anyway. When sync shows up in beta it will be based on the identity capabilities that come from our focus on the connect() API.
  • Forked and branched databases: Same as snapshot — the new architecture means we don't run into forks during normal operation, so we can move the fork handling to the connect() feature.
  • Vector and full-text integration: The alpha versions of these features are also application-level integrations - the hope is to have a plugin API so eg a vector index can bring its own data structure but take advantage of Fireproof's transactions and storage. Expect vector support to be added during the demo app upgrade cycle.

Help with any of these would be amazing. But the real joy of open source is the features you bring that I wouldn't have thought of. Pull requests welcome!

Tagged: