Hacker News new | past | comments | ask | show | jobs | submit login
Triplit: Open-source DB that syncs data between server and browser in real-time (github.com/aspen-cloud)
115 points by thunderbong on Jan 13, 2024 | hide | past | favorite | 37 comments



I love seeing all of these new local-first libraries and tools popping up! I just wish they were around when I started my app several years ago :-(

I use pouchdb / couchdb right now and I think my biggest issue at the moment is the amount of time it takes to sync up the app when you open it. It's possible to load the app straight from local data, but then it might be out of sync which could be jarring / confusing for the user.

Is this named after a triple store (e.g EAV) like in datomic? If so this is looking very close to my dream database.


The problem with couchdb is that it does one request per document which makes the protocol slow for browser based applications also it has no http2 support. Also storing the full rev tree of the documents is what makes pouchdb slow. This is why RxDB moved away from pouchdb/couchdb to a replication which works on bulk operation and resolves conflicts directly when they happen, not afterwards.



Yes great catch! One of the inspirations for Triplit's name is exactly from our use of a triple store under the hood. Datomic also has been a major influence in how we've designed the internals of Triplit


Ideally, your app would be server-rendered on the first load, instead of first loading all data, and then filling a SPA from that.


We're working on exactly this. You can already do this with Triplit but it's challenging to make an out of the box solution because each framework passes context/data different from server to client differently. There's a cool project called [Vike](https://github.com/vikejs/vike) that generalizes this pattern across SSR'd UI frameworks


This looks super useful for anything requiring optimistic updates, but how do you get data from triplit into another db? Perhaps for analytics or audit purposes.

With something like electric-sql you can just use one of the many Postgres tools, and other local-first options like https://ably.com/livesync have database adaptors for replication. I think this is an important requirement whenever you build your own database


[I work on Triplit] Currently, You can accomplish this by pulling from Triplit with either a JS client that just subscribes to each collection or with the REST API but we're currently working on a way to define custom "triggers" on your Triplit Server so you could directly push into any other database as you'd like


Is “triggers” a change-data-capture like thingy? Having an easy to connect to CDC stream seems like a great feature to offer. Is your trigger concept like DynamoDB Stream + triggers? https://docs.aws.amazon.com/amazondynamodb/latest/developerg...


Yes that's pretty much what we're going for. I'm less familiar with DynamoDB Streams but we're taking inspiration from Postgres triggers https://www.postgresql.org/docs/current/sql-createtrigger.ht...


I recommend having a pre-built integration that dumps all changes to the database in a Debezium CDC compatible format. Not sure how you'd normalize Triplit changes into Debezium updates, but something to think about. Debezium CDC format lets you pipe changes from one DB into a stream system like Kafka, and then out of Kafka into another DB on the other end. It's handy.

https://debezium.io/documentation/reference/2.5/transformati...

For example, the original method for connecting Postgres to Materialize.com was using a Debezium stream: https://materialize.com/docs/ingest-data/cdc-postgres-kafka-...


That's a great pointer seems like a many birds single stone solution!


This looks like the future. Nice! If I already have an app that uses firebase, do you have some migration guidlines? Perhaps a tutorial for migration? That would help.


Interesting take, I just switched from firebase realtime to pouchdb. I was getting concerned about firebase "local first" not really working how I expected and pouch fit the bill nicely. I like the idea of field level sync and wonder if triplit would be faster than pouch.


Glad you think so! We don't have any written docs but I would be happy to help you migrate! You can email me or join our discord https://triplit.dev/discord


Tangent, but the red squiggly underlines on your website invoke spelling errors in Word (and other apps) vibes. Not what you're going for I assume :-)


Conversely, I got vibes of "this is serious business" - and I hate reds in webdev/text.


This looks so cool and might use it for my project. Are there any examples showing how to use Sqlite? I dug around the docs for some time but only found mention of sqlite in passing. I'm developing a notes app and will be using sqlite's full text search extension a lot—wondering if anyone knows if the react bindings/hooks will properly update the UI if the UI is showing data from virtual tables.


Triplit is pretty opinionated about how things get stored so it doesn't work with existing SQLite schemas. We support basic `like` operators for searching but are definitely interested in supporting full text search. If you want to try that out, we use Sqlite in our server implementation so you can see an example there: https://github.com/aspen-cloud/triplit/blob/main/packages/se...


Interesting! So with this configuration, would there be any sqlite instance running in the browser, or does triplit only sync with sqlite on the server?


For everyone super optimistic about adopting tech like this, carefully consider the ramifications of the choice, what your code supposes about the data living in the DB, and your users' expectations.


Pls excuse my complete ignorance. I'm a complete noob trying to learn web development. Why would I use this over POST and server side update db or websockets?


I’d suggest Triplit if you want to make a rich web app similar to Notion. Under the hood this thing is doing POST and websocket subscriptions. You can skip all the manual work to wire up optimistic updates, subscription, local storage, pending transaction queue by adopting someone else’s implementation. Also after doing it enough times, adding a POST endpoint per record type in your app to create/read/update/delete that type gets old.


Exactly this ^


jitl's comment summarizes it well and I'd add that if you're building a highly interactive app (especially on mobile), you can't wait for network after each action before showing feedback to the user. If you do your app will feel janky and broken. So the solution is to show what you "optimistically" expect to happen in the UI before your request has even reached the server so each interaction feels instant. E.g. if you like Tweet in the app, it'll show a heart even if you're not connected to the internet and then in the background once it has a connection it'll sync up all of the pending request. This, however, can become tricky to implement and really hard to maintain as you add more features.

So Triplit does this all for you automatically with the mental model that your database queries automatically update when any data changes happen even if you're offline. Triplit takes care of reconciling this whether the request succeeds on the server and with concurrent changes from other users.


I don't 100% know in the case of triplit, but pouchdb does what you describe for "free" (i.e. you don't need to code it). firebase uses a websocket, pouch uses (I believe) long polling.


How does this handle multi-user conflicting updates, e.g. OT, CRDT?


I believe individual fields are last-writer-wins. Fancier CRDTs like text/lists are not directly supported, but I found that you can layer them on top: https://github.com/mweidner037/list-demos/tree/master/tripli...


Yep exactly. We also include a [Set CRDT](https://www.triplit.dev/docs/schemas#set) you can add to any entity.

In the future, we'll have an easier way to accomplish what Matt did out of the box so you can create re-orderable lists and collaborative text that are fast and seamlessly handle conflicts automatically


Yeah, docs say last write wins (at the field level though, not the document level).


Amazing! I was looking to make a very minimal triple-store based client db with lrw sync and triplit looks great. Is the underlying db using wasm SQLite in the browser? Is it open for contributions? And also any other "competitors" with similar reach to triplit? I've been looking into the current SQLite based + CRDT implementations but not sure how they compare


That's awesome you've already considered of a similar design to Triplit. Re: storage, Triplit can basically bind to any storage capable of providing ordered key values so we have bindings for SQLite but in the browser you're best of doing either in-memory or IndexedDB (both of which are built-in), examples here: https://www.triplit.dev/docs/client-database/storage.

Regarding similar projects there are a few you can find on https://localfirstweb.dev/ but Triplit stands out in a few ways: * Support for an authoritative server * Provides an optional hosted cloud service * Relational querying without SQL * Partial replication (this is a big one) * Typescript schemas and type hinting in queries in return types

For more advanced CRDT stuff, the creator of the Fugue List CRDT, created [a Triplit-powered collaborative text editor](https://github.com/mweidner037/list-demos/blob/master/tripli...) using Quill and his [List Positions](https://github.com/mweidner037/list-positions) library that we plan to have tighter integrations with.


Your (honestly) very nice homepage made me almost book a visit to ophthalmologist, eye floaters galore!


The stars are disabled in light mode if you want to try that!


I'm on light mode by default. If you look at the "The fullstack database" text you'll see things emanating from it outwards. Fast, and barely visible, hence the initial confusion. In any case, it's not a problem at all, just caused me doubt my vision for a moment :)

Just to be on the same page, I'm talking about top section of https://www.triplit.dev/


How would this compare to RxDB?


RxDB is just provides clientside querying and a sync protocol. Triplit is full stack in that it's designed to run on both client and server and will "just work" out of the box for end to end syncing, querying, and persisting data. Triplit supports relational querying.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: