Show HN: Fireproof – local-first database with Git-like encrypted sync

fireproof.storage

91 points by jchanimal 2 days ago

Hi, HN! As a cofounder of Couchbase, I pioneered mobile sync, and I’ve always wanted to bring the speed and reliability of local-first data to the web, incubating PouchDB among other efforts. I learned the constraints of real world financial applications at McKinsey & Company FinLab, and Merkle integrity research at Protocol Labs taught me smart contract data structures. As part of the JavaScript community (and early hosting provider for NPM) I’ve been waiting, and now with the availability of APIs like Passkeys and Origin Private Filesystem, I’m happy to say the browser is ready to support embedded databases.

Front-ends are a lot easier to write when your database handles live sync for you, but the existing solutions rely on heavyweight cloud APIs instead of putting the smarts at the edge, where it belongs. I started from a different set of constraints, and arrived at a lightweight embedded database that uses a git-like data model to offer cryptographic causal consistency across browsers, edge functions, and anywhere TypeScript runs.

It’s designed to make building full-featured apps as simple as calling `db.put({ hello: "world" })` and syncing them as easy as calling `connect(db, remote)`. People are using Fireproof for AI character chat[1], personal finance[2], and hedge funds[3], and we aim to be simple enough for novice coders to build enterprise-critical apps. Fireproof makes product owners dangerous, because just a little bit of code can define an application’s workflow and data model. See the code sample below.

The reactive APIs[4] are designed for live collaboration so your user interfaces update automatically, making it an easy way to add query collaboration to legacy dashboards, or write new interactive tools for your team. Merkle CRDTs[5] provide multi-writer safety while maintaining tamperproof data provenance, conflict tracking, and deterministic merges. The storage engine writes content-addressed encrypted files that can be synced via commodity backends like S3 or Cloudflare[], without sacrificing data integrity.

Our contributors include legends like Damien Katz, Meno Abels, Mikeal Rogers, and Alan Shaw. Fireproof is open source (Apache/MIT) and we know there are rough edges, so we hope this post stirs up collaborators![6] Please `npm install @fireproof/core` and give us feedback[7]. We are on the stable side of beta, so it’s a great time for the adventurous to join. I’m excited to see all the apps people write now that it’s easy!

[1] https://github.com/fireproof-storage/catbot/tree/main

[2] https://fireproof.storage/posts/quickcheck:-print-checks-at-...

[3] https://fireproof.storage/posts/contributor-spotlight:-danie...

[4] https://use-fireproof.com/docs/react-tutorial

[5] https://fireproof.storage/posts/remote-access-crdt-wrapped-m...

[6] https://github.com/fireproof-storage/fireproof/issues

[7] https://discord.gg/DbSXGqvxFc

damienkatz 2 days ago

Creator of Apache CouchDB here. Fireproof is a very clever system for building secure, collaborative apps. Your apps can work offline and when connected automatically sync changes to local storage and display them immediately to the UI. It has much of that same CouchDB magic with almost no complexity or headache on the backend.

Very coo…errr…hot!

  • mainguy 2 days ago

    User of Couchdb for similar use case...been keeping up to date on a parallel branch of my solution using fireproof instead of couch. Still early, but great potential...stumbled onto fireproof because I was about to write an adapter for couch (well Pouch actually, but same same) to replicate in a similar manner to fireproof.

    • jchanimal 2 days ago

      We are working on transparent replication to Postgres JSON which will make it a lot easier to adopt.

  • bosky101 a day ago

    We have never met. But great to see you here!

  • jchanimal 2 days ago

    Thanks for pointing out the key management potential!

jchrisa 2 days ago

Thanks for reading — Fireproof creator here, happy to answer any questions.

We are in-flight on our cloud launch, so consider it a preview of the experience we are building. We’ll soon be shipping more complete authorization with UCAN capability delegation, and we are working on mature key rotation. I can't wait to hear what people want to build with it.

myklemykle 2 days ago

I wrote a demo with Firebase to sync a bunch of music data between N web clients. EZ-PZ. All of the integrity stuff was icing on the cake, but basically it was an ultra-simple way to replicate data btwn web app users, without worrying about the server side at all.

bosky101 a day ago

The website and example, and usage looks clean. Kudos! I have some questions around what's happening under the hood that werent evident from an initial read of both your website as well as GitHub.

1. Does subscribe listen for new changes on a transient server(just a queue). Or from a more persistent store?

2. Where do the events persist? I didn't see a connector to postgres. I did see one for s3.

3. What is the default persistence layer you are advocating?

4. Let's say you run 3 instances of the self hosted server. And a random one of them gets a teacher. And 2 random other students gets load balanced to two other servers. How does the teacher get all messages? What's the thread in a distributed setting

5. How do you filter only messages. Eg: only since time T.

6. Pagination / limits to avoid any avalanche?

7. Auth? Custom auth/jwt?

8. REST API to produce?

9. Are consumers restricted to browsers? What about one in node?

10. BONUS: Have you tested if this works embedded as an iframe or embedded in an native/react native mobile app?

  • jchanimal 20 hours ago

    I answered 1-5 in my other reply, hit save and so here's more:

    6. There is a limit parameter on the query API, and the underlying data structures utilize async iterator patterns so we have a go-forward path to a streaming (data / query larger than memory) implementation. But for now the decrypt implementation is eager instead of lazy, so that's the first place we'd want to focus to make data > memory workloads no problem.

    7. Other embedded databases don't have auth, but we are network-aware so it's a different ballgame. Our next step is read/write access control on a per-ledger basis.

    UCAN capability delegation allows us to keep an embedded mindset here, in that authorization becomes a matter of data validity, not something that has to be fetched from a centralized resources. How it works: client device agents generate non-extractable keypairs (like Passkeys) and can link them to account principals via any signing endpoint Fireproof trusts (for starters just the one we run, to an end user it looks like clicking a validation link in an email.) Agents create a new cloud database clock register by locally generating an ephemeral keypair that signs itself over to the principal. Our centralized clock register endpoint only allows updates to the resource identified by the clock's public key ID, from agents which have a valid signed delegation chain to the ephemeral key.

    To a developer it will look something like `db.share("bob@example.com")` and now Fireproof Cloud will let Bob read and/or write the db also.

    What's cool about this is that access control changes are just data manipulations, so they can happen offline. And the valid delegations can be safely delivered over any channel. In fact there are no secrets in this system except for the non-extractable keypairs.

    If you are thinking to yourself "what about revocation?" -- we are hiring.

    8. The sync endpoint has the minimal blob k/v (no list) and register APIs. And can all be floated on top of any raw kv with check-and-set semantics if needed.

    We have plans for a REST API in Fireproof Cloud, where if you allow the cloud to decrypt and process your data, we can give you raw queries instead of you replicating and then querying locally. I am thinking a CSV output here would be a good place to start.

    9. Runs great anywhere JS runs. We have examples (like CatBot linked above) that subscribe to the ledger on the backend and operate locally, often responding the user events. So the DB is acting as an RPC bus... this is a common pattern in CouchDB so I made sure Fireproof works great like that.

    To run in an edge function, you usually aren't gonna replicate to local filesystem, instead you can configure the database to read and write directly with the cloud store. Because of the eager decrypt we do, this is actually pretty fast and not that chatty.

    10. The CodePen demo on our homepage is an iframe, works great. We have a contributor (I think I see in the thread here) who is working on React Native -- most of the heavy lift is done, but our gateway interface is only now settling down to where it makes sense to finalize the integration. I have also done Socket Supply for mobile and that works great.

  • jchanimal 21 hours ago

    These are awesome questions, I'll try to fold the answers into the docs also.

    1. The embedded database subscribes to the remote sync endpoint when it is connected. This subscription might be polling, websocket, or anything else. The local embedded database will try to keep up with changes anyone pushes to the remote endpoint. This is more a backend mechanical thing than an API you'll see.

    Your code can subscribe to the local database -- this is a JavaScript event loop, and any updates, local or remote, will cause your callback to run. The upshot is all you have to do is connect your database to the sync endpoint and it will stay up to date, and you can also connect your UI to the database via `db.subscribe()`

    2. Updates are written to local storage (indexed db or the filesystem) as encrypted blobs. These are then replicated to the cloud (without being parsed by the cloud). We have SQL connectors also, but we haven't done the Postgres specific stuff (just started designing it). That is the data side. There is also the clock register, which the client updates to point to the most recent blob. This register is multi-writer safe, and can occasionally point to more than one "head" blob, in which case the client does the deterministic merge on read.

    3. In my experience most people use the defaults, so we have Fireproof Cloud which uses R2 and durable objects. We also have a SAM template for AWS, and a connector for Netlify, in addition things that are more like parts for building your own backend (file and http endpoints).

    4. Each ledger replicates 100% when it syncs, so all hosts have the same data (no sharding within a ledger.) Typically you have one centralized endpoint to sync via. (p2p is possible but you'd end up contributing some plumbing to the project I bet). So in this case the class would have a URL that is the sync point, and everyone would pull from it periodically or via streaming.

    Merges are idempotent, deterministic, associative, and commutative, so it doesn't matter what order the teacher and students apply updates to their local instance, once all updates are applied, they have the same state.

    5. The e2e encryption means you'd have to give the keys to the server to allow it to create subsets for sync, so we haven't done that yet. Our next optimization is to sync the readonly current dataset first, then any extra data needed for writing, and only when necessary, the historical log. This still doesn't solve the subset sync issue, but will benefit all use cases immediately.

    There is some cool research we might use for subset sync: https://g-trees.github.io/g_trees/

    But more practical is probably to finish the Postgres backend and then build subsetting at the global (multi-ledger) dataset level.

jchrisa 2 days ago

Here is the code sample I mentioned, example React usage (see our homepage for Vanilla JS)

    import { useFireproof, useDocument } from "use-fireproof";
    import { connect } from "@fireproof/cloud";

    export default function App() {
      const { database, useLiveQuery } = useFireproof("my_db");
      connect(database, "my-remote");
      const { docs } = useLiveQuery("_id");

      const [newDoc, setNewDoc, saveNewDoc] = useDocument({ input: "" });

      const handleSubmit = async (e) => {
        e.preventDefault();
        if (newDoc.input) {
          await saveNewDoc();
          setNewDoc({ input: "" }); // Reset for new entry
        }
      };

      return (
        <div>
          <form onSubmit={handleSubmit}>
            <input
              value={newDoc.input}
              onChange={(e) => setNewDoc({ input: e.target.value })}
            />
            <button>Add</button>
          </form>
          <ul>
            {docs.map((doc) => (
              <li key={doc._id}>{JSON.stringify(doc)}</li>
            ))}
          </ul>
        </div>
      );
    }
johnson_brad 2 days ago

Fireproof brings really solid DX with a passionate team supporting it. It's deceptively powerful as an embedded db, but delivers the kind of experience you'd typically expect from a good frontend stack. Since modern web development keeps pushing the limits of browsers, I love local-first projects like this.

mschoch 2 days ago

Fireproof engineer here, I come from the backend engineer perspective, so I thought I'd share some of my personal hacks on Fireproof:

Fireplace - tooling to deploy Fireproof apps and sync data across your Tailscale network. Once all the computers you care about are on your tailnet, of course you want all the browsers on the tailnet to easily sync with one another.

Go Implementation - Fireproof bills itself as a realtime database that runs anywhere, and I want to make sure that includes inside your Go applications. This will allow your Go application to become a full-fledged reader/writer of the Fireproof ledger.

I'm excited to see what other people want to build and answer any questions.

tvachon 2 days ago

Love this! I've been following and contributing to Fireproof for a while now and it's super exciting to see how far it's come - excited to use it on a project soon!

fastandfearless a day ago

I'm happy working on fireproof. The people are very nice. In terms of technology it's a new kind on block. Yes a bit of database and a bit of Blockchain with git rebase.That's why we moving from naming it database to ledger lately.

  • jchrisa 19 hours ago

    I didn't say enough about the ledger-like aspects above. Some databases have collections, some have tables, Fireproof has ledgers. These are the unit of sharing and access control, and also the unit of provable history.

nadyanadya2024 2 days ago

Fireproof has come a long way and If you’re looking to cut down on backend complexity while having a reliable user experience, Fireproof is worth a serious look.

  • jchanimal 2 days ago

    Thanks and thanks for the early feedback last year when I was still working on the alpha version.

lloydcenter 7 hours ago

Thing is.. Fireproof is brilliant and has a fun culture.

3jnsn 2 days ago

One of my favorite use cases for Fireproof is storing and searching across vector embeddings. It can act as a RAG for LLMs, operating on the backend for all clients, and/or the frontend for customized or offline scenarios.

dscape 2 days ago

Congrats on launching Fireproof! You mentioned syncing content-addressed encrypted files via S3 or Cloudflare. For developers already using existing cloud-first setups, how seamless is it to integrate Fireproof as a hybrid solution?

  • jchrisa 2 days ago

    Fireproof embeds in the browser, so you can add it to frontend code just like any other JavaScript module. It's useful for app data even without a backend.

    When you are ready to connect multiple users, that's when the backend comes in, which can be as simple as Fireproof Cloud or your existing AWS account.

heapwolf 2 days ago

This looks really promising, this should run in any web-like environment right? Specifically it might be interesting to build a Socket App with this (https://github.com/socketsupply/socket)

  • jchrisa 2 days ago

    Thanks -- we got hello world with Socket, but there's some interesting open source work we'll need to do to support peers acting as servers and take full advantage of the network.

    https://github.com/fireproof-storage/hello-socket-fireproof

    If anyone wants to join the effort, the semantics we are talking about are also aligned with WebRTC delivery, so you'd enable a bunch of p2p topologies with your contribution.

pajop 2 days ago

Are there tutorials available?

p1pp1n 14 hours ago

It has been quite inspiring watching you grow this from a concept into a fully functioning next gen DB. Cheers!

bburns_km 2 days ago

I had recently been experimenting with pouch/couchdb, and got it working locally, then came across a post on reddit about Fireproof. I really liked how it sounded - like the evolution of pouch/couch.

So I set it up on a node app - it works great locally -

  import { fireproof } from '@fireproof/core'

  const db = fireproof(dbname)

  db.put(doc)

  async read(id) {
    if (id) return await db.get(id)
    return await db.allDocs()
  }
Then I wanted to sync the data to the cloud - just the simplest thing possible, but I got lost in all the connector options and descriptions. I tried setting up PartyKit, but got bogged down in it all and eventually went on to something else.

So it would be great if the home page included a simple demo with a connector - Amazon S3 or PartyKit - including setting up the cloud db.

Thanks, and good luck with everything - it looks amazing...

(side note: HackerNews doesn't let you format code with ``` ??)

  • jchanimal 2 days ago

    Thanks for the feedback. That is a bridge we are crossing now. We started with open source backends for maximum coverage, and are standing up Fireproof Cloud now as the easy default. If you click "inspect data" in the demo CodePen app, it will show you a live replication in our dashboard.

    We'll be adding auth and sharing controls soon, so you should be able to build basic apps with just Fireproof and an HTML host.

    • bburns_km 2 days ago

      Thanks, looking forward to all that - will keep an eye out.

sethmhardy a day ago

Great news! I suspect we'll be using this when we have to go back to on-prem hardware.

hfnciol 2 days ago

Looks very cool.

Have been developing something similar (local first data tooling) for a project of my own.

The one thing stopping me from swapping my incomplete implementation with this is that I am unable to find how to connect to a db I control.

In another thread you self described your backend options as "maybe too many backend implementions", but I am only seeing established cloud providers (meh) and ipfs (cool, but sluggish).

https://use-fireproof.com/docs/connect

Can I have the persistent data stored in PostgreSQL on a server I am running?

Are fireproof servers involved in mediating the syncing or is it done through the client?

  • jchanimal 2 days ago

    The default gateway style doesn’t have to parse the encrypted files so the endpoint could be anything like an S3 bucket and anything like a register to redirect to the most recent file.

    Someone has a similar question in our discord, where I described what we’re planning with Postgres and unencrypted sync.

cdurth a day ago

How does this compare to Dexie js and Dexie cloud?

  • jchanimal 17 hours ago

    We focus on provable data integrity and being easy enough that new devs can find success without learning much stack.

    Many alternatives start with a backend integration mindset, I started from the React hooks and worked towards the storage engine.

NatMars 2 days ago

A real solution for real world applications!!!