return to table of content

Show HN: Triplit – Open-source syncing database that runs on server and client

candiddevmike
26 replies
2d

Why did you choose to license this under the AGPL?

victor9000
16 replies
2d

So you have to AGPL your product because of the database that it uses lol, hard pass.

mkl
2 replies
1d6h

Your link confirms victor9000's point and contradicts your first sentence. The frontend libraries (the client-side database, the React and Svelte bindings, etc.) are AGPL, so your whole frontend that builds on them must be AGPL.

matlin
1 replies
1d4h

Can you point to which part in the license gives you the impression that using an unmodified version of AGPL code requires using AGPL for your entire application?

Either way your interpretation is not our intention so I'll make sure that's clarified.

mkl
0 replies
20h9m

AGPL is a "viral" or "strong copyleft" license [0], like GPL: if any part of a piece of software is AGPL, the entire software must be AGPL.

The license [1] says this in section 5:

5. Conveying Modified Source Versions.

You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

[...]

c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.

If you intended it to be non-viral (weak copyleft) and based on distributing modified versions of your files, the Mozilla Public License [2] may be a better fit for the frontend libraries. Then people could use them unmodified in software with any license, but they would have to release source code of modified versions of those files. This would not do what you want for the server software though, as the "release source code" only applies when distributing software (which is not happening if it's staying on the server).

I am not an expert, and it is not clear to me whether the frontend and backend constitute a single work according to the license. This is important to investigate. If they did count as a single work, rather than two separate works communicating, then the AGPL from the server software would apply to the client software and licensing the frontend libraries MPL wouldn't work. This says something about that in the other direction: https://www.gnu.org/licenses/gpl-faq.html#AGPLv3ServerAsUser

[0] https://en.wikipedia.org/wiki/Copyleft#Strong_and_weak_copyl...

[1] https://www.gnu.org/licenses/agpl-3.0.html#license-text

[2] https://en.wikipedia.org/wiki/Mozilla_Public_License

dspillett
2 replies
1d18h

That article isn't right generally, by my understanding. It might be⁰ for their own use (a DB engine) but not for a library that might be more directly linked to an application.

AGPL is based on GPL, not LGPL, and like the GPL linking would be considered creating a derivative work which should then be made available as per the [A]GPL licence.

This won't stop me licensing my work using AGPL. If commercial interests don't want to use it then I'm fine with that¹. If they do want to use my stuff but don't want to use anything covered by AGPL then they can always contact me to try negotiate a different arrangement.

--------

[0] IANAL, hence “might be”. Whether loose coupling counts the same as linking is a grey area IIRC. This potential confusion is why some avoid GPL/AGPL, if only to be on the safe side from their PoV.

[1] Give the choice between “give us what we want with no come back and we'll use what we want and give nothing back” and “don't give us what we want, and we'll go away and leave you alone”, I'll take option two. I get nothing either way.²

[2] As the linked article says: “If you don’t use the AGPL[³], they’re just going to take your software and give nothing back. If you do use the AGPL, they’re just going to develop a solution in-house. There’s no outcome where Google pays you.”

[3] Here they are comparing AGPL to less restrictive licenses such as MIT.

robertlagrant
1 replies
1d6h

Give the choice between “give us what we want with no come back and we'll use what we want and give nothing back” and “don't give us what we want, and we'll go away and leave you alone”, I'll take option two. I get nothing either way

This seems less fitting if it's true that what you're "giving" is some React bindings, and what they have to "give back" is their entire frontend application.

dspillett
0 replies
59m

They don't have to give back if they don't use those bindings. They could use someone else's, or write their own.

They could also try negotiate an alternate arrangement, some authors may be willing to do that (assuming they have relevant permission from other contributors if it isn't a solo project, of course).

The example you give seems to be the unreasonable one IMO: “our thing is bigger, so we expect to use your smaller thing how we want”.

andrewmutz
1 replies
2d

What types of usage do you think the AGPL would prevent that the GPL license would have allowed? What situations were you trying to prevent?

matlin
0 replies
1d23h

From my understanding, if someone were to create a private fork of Triplit Server add some modifications and then launch a hosted service (i.e. serving the modified Triplit Server over the internet) they wouldn't be compelled to open-source their modifications under GPL but would under AGPL.

dehrmann
0 replies
1d3h

common misconception

This always comes up with copyleft licenses. It's rarely 100% clear what's allowed, except maybe the LGPL where the intent of the license is obvious. Everything else is some amount of a viral license, and it's safest to just avoid it.

andyp-kw
5 replies
2d

Why would your whole product need to be AGPL just because the database is ?

It's like saying that Oracle owns my product because I use MySQL.

scosman
3 replies
1d22h

MySQL is GPL not AGPL. Very different.

franga2000
2 replies
1d8h

But his wouldn't be the case even if MySQL was AGPL. The license would only apply to the database itself and not your backend or frontend code.

The difference would be if your code used a library that was GPL/AGPL. For server-side software, under the GPL, mere users wouldn't be entitled to the code, while under the AGPL they would be.

This also assumes that library was used in a way that counts as derivative work, which isn't always the case.

resoluteteeth
1 replies
1d4h

This also assumes that library was used in a way that counts as derivative work, which isn't always the case.

That's something a court would have to decide.

Whenever the AGPL comes up, people start arguing that in their opinion it doesn't cover certain things and therefore criticism of the license is fear mongering, but this misses the point that even if there is room to argue for that position, no company is going to want to touch AGPL software when the situation is ambiguous, since that creates a lot of risk, so that ambiguity is itself a fatal flaw of the AGPL license.

franga2000
0 replies
23h57m

But none of these problems are relevant to GPL vs AGPL, they apply equally to both. Seriously, just diff the text of both licenses - the only difference is article 13, which is very clear and unambiguous:

Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software.
debugnik
0 replies
1d10h

The client libraries are also AGPL.

matlin
8 replies
2d

Our hope with the AGPL license is that it will make Triplit easily self-hostable while ensuring that anyone who makes modifications contributes those back to the community.

pcthrowaway
3 replies
1d23h

Based on you making your frontend libraries AGPL, I believe any frontend using them would have to be generally compatible with the GPL family (so would also have to be *GPL licensed)

Is my understanding incorrect?

resoluteteeth
2 replies
1d22h

Yeah this seems like a major issue. I think the AGPL is strictly stronger than the GPL so if it was possible to use a GPL or AGPL library from non-GPL code then surely there would be no reason for the LGPL license to exist?

pcthrowaway
1 replies
1d22h

Yeah, unfortunately I think it's debatable whether LGPL is even OK for a closed-source project to use, since IIRC LGPL specifically talks about linking compiled binaries.

I guess there's the argument that transpiled, minified javascript program is a compiled binary? I'd love to know whether these things have been tested in various courts.

leni536
0 replies
1d18h

LGPL specifically talks about linking compiled binaries.

That's the context where LGPL is used most often, but the license itself is more general than that. In particular 4/d/0 in [1].

AFAIK, LGPL is about replaceability. If you distribute a compiled program (yes, a minified JS program should qualify) then you need to distribute the source of the LGPL part and document a way how the user can replace that LGPL part in your program with their own modified copy.

[1] https://www.gnu.org/licenses/lgpl-3.0.en.html

candiddevmike
1 replies
2d

while ensuring that anyone who makes modifications contributes those back to the community

The AGPL doesn't really require this though. It requires the source code to be distributed to users, it does not require anyone to contribute those modifications back.

matlin
0 replies
1d23h

Right, that's a good clarification.

mkl
0 replies
1d6h

For the backend, that makes some sense. However, your frontend libraries and bindings are AGPL too, which means any site or app using them must be AGPL as well (since they would be derivative works). That makes it almost impossible for commercial products to use Triplit, which means there won't be companies putting development resources into the community.

dehrmann
0 replies
1d3h

There's a chicken and the egg problem with this fear and approach to OSS. More permissive licenses (Apache, BSD) encourage adoption since it's hard to go afoul with them. At the same time, they allow someone like AWS to sell the DB as a hosted service.

People are trying to have their cake and eat it too with open-source DBs (and it's mostly DBs). Historically, OSS was either for anyone for anything, or it was a viral license trying to build a GNU ecosystem. The DBs playing licensing games have been using OSS as a growth hack, they doing a bait-and-switch once they're popular.

At least starting with the AGPL up-front is honest, but considering the client-server nature of this DB, it makes it a non-starter for me.

imkyle
9 replies
2d

This is just using sqlite under the hood and none of this will scale. Why build your own query builder as well when you could just hook in one of the many ORMs in the NPM ecosystem and add support for 50+ other databases. This also isn't really something you could drop into an existing project very easily. Overall, I'm not impressed.

Here are some other options I prefer:

https://feathersjs.com/ https://rethinkdb.com/

salviati
3 replies
2d

Do the databases you propone work offline too?

If they don't they're not a good match at all.

satvikpendem
0 replies
1d21h

That is not a CRDT level solution though, it doesn't work with multiple clients with disparate conflicting data.

matlin
0 replies
1d22h

React Query (and other query caching libraries) are great until you have overlapping data between your queries. E.g. you edit a message in one place but other queries that show that same message (like a preview in your chat list) don't update.

Having a complete query engine on the client makes this a lot easier to deal with. It's why most popular messaging apps will use SQLite on the client to render the UI and build their own sync engine to keep it up to date with the backend.

matlin
2 replies
2d

Can you point me to what gave you this impression? We implement our own query engine for Triplit and use a fork of tuple-database[1] for storage which is low level database that can store to SQLite (we do on the server) but in the browser it uses either an in-memory btree or IndexedDB.

Regarding compatibility with our databases, we do have some internal experiments of running a Triplit Server in front of existing databases as almost like a syncing cache. Still very experimental but maybe you'd be more into that use case.

1. https://github.com/aspen-cloud/tuple-database

crabmusket
1 replies
1d20h

Very cool to see a use of tuple-database in the wild! I've known about that project for a while and thought it looked really cool, but I don't have a use for it.

What's the reason for the fork?

matlin
0 replies
1d20h

No real reason other than we wanted to customize it and move quickly. I'm sure Chet, the maintainer, wouldn't oppose any of the changes we've made.

jstummbillig
0 replies
2d

Something something Dropbox

AlexErrant
0 replies
2d

What does "scale" here mean? Sqlite can go quite far https://use.expensify.com/blog/scaling-sqlite-to-4m-qps-on-a...

I agree with you w/r/t "Why build your own query builder" though since (AFAIK) you can't touch the underlying SQL. I'm making heavy usage of FTS5 in my app, and it doesn't look like they support that.

And, to be fair, feathers/rethink also have the weaknesses you list:

- Why build your own query builder

- This also isn't really something you could drop into an existing project very easily

Personally, I've been pretty happy with https://github.com/vlcn-io/cr-sqlite/ which is just a sqlite extension that can run in the browser.

lars512
6 replies
1d13h

Related question: when you're using databases with great offline sync protocols like this, how do you do schema evolution of your DB, especially in the face of different client versions that you cannot upgrade in lockstep?

My context here is having worked in the past on a mobile health app, and recalling all the pain we had around this problem.

matlin
1 replies
1d4h

This is a great question! The short answer is by maintaining backwards compatibility in your schema--it's basically the easiest way to guarantee compatibility. We have warnings in place to let you know when you've made a change that isn't backwards compatible, you can read about it in our docs: https://www.triplit.dev/docs/schemas/updating#pushing-the-sc...

However, overtime this can naturally lead to a mess of a schema definition that has a lot of confusing names. We haven't released a solution to fix this yet but we're working on a few things that should make this less painful. For background on the various approaches, the Cambria doc is an amazing resource: https://www.inkandswitch.com/cambria/

eevilspock
0 replies
1d3h

Lenses make total sense. You don't have to maintain lenses for all past versions, just a rolling set with old ones scheduled for deprecation announcements and a sunset schedule.

manmal
1 replies
1d12h

I think some clients (like the server) must be able to sync with very old schemas because the user might have forgotten their phone in a drawer for two years. Each client just migrates itself asap.

eevilspock
0 replies
1d3h

I don't think any user who leaves their unsynced data sitting in a drawer for more than a year can reasonably expect it to sync to a shared database, not just because of schema incompatibility but more so because of conflict resolution (imagine expecting your PR based on a two year old git commit to be accepted to a very active project). Just give them a report of the diff (the unsynced changes) so they can redo them via the latest client manually.

rockwotj
0 replies
1d7h

Only create new tables, don't make breaking changes to existing tables. If needed dual write both versions. Looks a lot like a live migration (zero downtime) due breaking change to a SQL DB, except you have to keep the logic longer because you're at the customer's mercy of when the switchover happens.

Also it's important to have a table that is used to coordinate latest version. If you make a breaking change have the client that is behind to ask the user to upgrade. You can also tie this into how long you keep the dual write/read around with a min version supported across all clients.

robertlagrant
0 replies
1d6h

I would say having a built in way to define and support historic migrations would be a pretty killer feature. Saves everyone inventing their own way of managing migrations.

arcticfox
6 replies
2d1h

This is really cool. Feels like the future of app development.

But also I’m getting old, and I had the same feeling when RethinkDB came out. Do you guys have any thoughts on how your system compares to what they were doing and what eventually happened to them?

matlin
2 replies
2d1h

I can't speak to RethinkDB's history but we're really focused on a specific use case which I think helps. Specifically, Triplit is made for web developers so we have great TS support, React and Svelte bindings, etc which makes adoption and marketing much easier.

c01nd01r
1 replies
2d

Any plans to add Vue.js support?

matlin
0 replies
2d

Yep! We've just prioritized based on what's been requested in our Discord and surprisingly Svelte has been requested a lot more than Vue so we did that first but Vue is on the way.

jamil7
0 replies
1d3h

RethinkDB was actually pretty good from memory, a little underbaked but expected for a new DB. I think they also kind of just lost out on the marketing war with MongoDB at the time.

aitchnyu
0 replies
1d12h

Cant wait for new PHP, in the sense we can stuff hundreds of apps (with dbs) in the filesystem and it takes negligible CPU if idle.

sagarjs
4 replies
1d23h

So it’s not possible to use this with an existing postgresql database?

satvikpendem
2 replies
1d21h

Look into ElectricSQL which works with existing Postgres, it is what I'm leaning towards using too.

zknill
0 replies
1d7h

Also checkout Ably LiveSync, works with postgres and makes some different (potentially simpler) tradeoffs

ochiba
0 replies
21h30m

I work on PowerSync which may be worth looking at too, for Postgres-SQLite sync https://www.powersync.com/

matlin
0 replies
1d23h

Not currently but we have an internal tool that does bi-directional syncing using Postgres's replication protocol and WAL2JSON. It's not quite ready for prime time but we're hoping to get it into people's hands soon.

munzman
4 replies
1d20h

would be great to have Rust bindings so it could work with Tauri. With tauri growth and the upcoming mobile devices support coupled with SQLite recent hype, this could bridge the gap and solve many problems for offline-first apps, thus become the go to solutions for many dev shops.

matlin
2 replies
1d20h

I thought Tauri was just using native web renderers? Seemingly Triplit should work out of the box.

OJFord
1 replies
1d18h

Yes but the 'backend' (the client, but the non-presentational bit) is Rust; it'd be there you'd want to do this sort of synchronisation or anything to do with state/database. You could absolutely shoe-horn it in, it just wouldn't be the way you'd expect it to work or feel particularly right/supported.

matlin
0 replies
1d17h

Got it, that makes sense. Probably could spin up Node process but of course that requires having Node installed or bundled with the app.

satvikpendem
0 replies
1d12h

I'm looking to add Rust bindings to ElectricSQL as that is a similar sync solution but it acts on the database layer so it's language agnostic. I'm using Rust on the server but Rust bindings would work on both the client and server. If you're interested in joining me on developing those Rust bindings, let me know.

thanhnguyen2187
3 replies
1d15h

Hi Triplit's team,

Congrats on the launch and thanks for the awesome product! I've been using Triplit in one of my projects [1], and it do work as expected. In my self-promotion on Reddit [2], I posted about Triplit as well:

I think Triplit is a nice database and works as expected. It's data model fits well with what I have in mind (more decentralized/P2P instead of having a single centralized database as the source of truth), but there are 2 areas I find lacking:

- Server side/self-hosted: Triplit server requires a token for authentication. Triplit's documentation has a section about how to start the server without explicitly showing how to generate the token, which is mildly inconvenient. Therefore, on self-hosting the server, I opted for using their CLI command dev since the command has the token generation that I needed. I know it is not a good security practice as when the command is used as a system service, the token will be logged in plain text, but I have a bigger problem when someone can access that anyway.

- Query language: I find their custom query DSL not as expressive as a full-fledged query language (lacking UNIQUE and COUNT like SQL is on the top of my mind). You'll have to do a bit of data aggregating yourself.

Recently, I found Evolu [3], which is quite similar to your project in terms of scope and functionalities as well. From a quick skim of their documentation, I think the differences are:

- Triplit have `.subscribe()`, while Evolu don't

- Evolu's querying is more familiar/advanced (typed SQL via Kysely)

- In the browser, Evolu seems to use SQLite on top of OPFS, while Triplit uses IndexedDB

I think there are more intricacies on the way Triplit differs from Evolu, so can you enlighten me on that?

Really appreciate your comment! Thanks!

- [1]: https://github.com/thanhnguyen2187/cryptaa

- [2]: https://www.reddit.com/r/sveltejs/comments/1dndpj8/cryptaa_a...

- [3]: https://www.evolu.dev/docs

steida
0 replies
1d1h

Evolu has subscribe with useQuery or separated.

matlin
0 replies
1d3h

Glad you've enjoyed using Triplit!

on self-hosting: We're cleaning up the docs on self-hosting to make the configuration clearer, thanks for point that out.

on querying: Yeah we don't have aggregations yet but it's on our roadmap. Don't want to over promise but I think we can make something awesome here by leverage our incremental querying engine. Like consider a data dashboard that needs to be updated every hour; in a traditional system (postgres, mongo, etc) you would need to rerun the query from scratch each time. Our plan is to create something closer to what Materialize does and just process the new data so it's much more efficient and can just update continuously rather than every hour.

re Evolu: I haven't actually gotten a change to try it out but there might be in someone in our Discord[1] that has that could compare/contrast

1. https://triplit.dev/discord

ddrdrck_
0 replies
1d8h

Thanks for pointing out Evolu, both solutions (Triplit and Evolu) seem very interesting. I would also be interested to see a comparison between the two

Kiro
3 replies
1d9h

I don't understand in what apps it's acceptable for the client to be able to write to the database directly. Or how you can get away without any backend logic.

I have the same questions about Supabase and Firestore so it seems like I'm missing something.

robertlagrant
0 replies
1d9h

I built a collaboration app using Firebase - it works okay for that sort of thing, where you're highly constraining what each person does to their own comments / cards, and they just have permission to do certain things. For things with a load of backend logic I can't imagine it working that well.

breakfastduck
0 replies
1d5h

Most things built 'out in the world' have hardly any business logic, they're all just CRUDs.

In enterprise this is obviously the opposite way around. It's actually super frustrating to watch discussions that ignore this, it's a really big problem on tech twitter etc especially, where people advocate for certain stacks or ways or working or whatever that make it clear as day they've never had to build a business system, they've just been building CRUDs, so they're incapable of understanding why experienced devs who have disagree with them.

Lalabadie
0 replies
1d4h

For both of these, there's backend-enforced access, so it's not without backend logic. With Supabase for example, the feature is called row-level security.

The client can fire requests to Supabase, but Supabase runs additional queries on the back-end that determine whether an incoming request is allowed or not.

A simple example would be that a client is only allowed to read, write or update a row if the value in the UserID column is the same as the requesting authenticated user's.

Jayakumark
3 replies
2d1h

Is there a pre-existing demo page.

matlin
2 replies
2d1h

We've setup a demo environment to get a feel for it here: https://demo.triplit.dev/

It's actually running two clients and the server inside the browser window so even though it's simulating real-world, it's the actual code that powers Triplit.

Jayakumark
1 replies
2d

thanks, but if i add a new todo in sync mode left say "uni" , go offline and change one side to "universe" and other to "unicorn", one overwrites another its random on who wins. Shouldn't it maintain both ?

matlin
0 replies
2d

Technically speaking both values are preserved in the history but only one "wins" because each attribute is a last-writer-wins register. This works for most use cases e.g. you wouldn't want two concurrent edits to checkbox to leave it simultaneous true AND false state.

However, when it comes to collaborative text you're absolutely right and support is on our roadmap. A researcher in this space has already implemented his collaborative sequence library on top of Triplit with the Quill text editor and you can check it out here: https://github.com/mweidner037/list-positions-demos/tree/mas...

stevage
2 replies
1d19h

Looks very useful. I didn't dive deep, but don't understand yet where you define access controls? I mean, How you say that a given Users can only Access their own data.

matlin
0 replies
1d18h

Yeah it's totally usable as is but we're nearly finished with a new system that has more granular controls like delete, preUpdate, postUpdate, insert, and read. We'll still support the existing rules for backwards compatibility.

mrtesthah
2 replies
2d

What is Triplet’s syncing latency?

matlin
1 replies
2d

I don't have official measurements but it's fast enough for most things short of realtime cursors or anything updating on an sub-second interval--we'll be adding a presence API for things like that. It'll also depend on the complexity of the query.

Do you have a specific use case in mind?

mrtesthah
0 replies
1d23h

That is my use-case: syncing things like cursor positions, scroll offsets, and other realtime metadata. I’ll await your presence API.

terpimost
1 replies
2d1h

Pretty cool guys. It would be nice to know the differences to other local first like solutions out there.

matlin
0 replies
2d1h

There are a lot of new local-first tools these days but broadly speaking Triplit lends itself to more typical client-server applications with a central, authoritative server where other tools in this space are oriented around decentralization and server-agnostic systems.

tanishqkanc
1 replies
1d23h

I've been using Triplit on my React native app for a while and it works great. Highly recommend. It's the only local-first db that hits these points for me:

- Good sane query language (not SQL) - Great typescript support - Offline support - React native support

The cherries on top is that it's open source and self-hostable.

matlin
0 replies
1d22h

Thanks for the kind words and help identifying issues in Triplit as you've built your app!

syedmsawaid
1 replies
1d22h

Would this be pluggable to any backend? Like say, Ruby on Rails or ASP.NET?

matlin
0 replies
1d21h

Triplit uses its own standalone server (similar to other database servers) which you can talk to via HTTP https://www.triplit.dev/docs/http-api

satvikpendem
1 replies
1d23h

I believe I saw your video presentations on YouTube [0] from the Local First Discord server [1], so nice to see your Show HN here. I am not using TypeScript so I might not be your target audience, I'm using local-first especially for mobile apps where connections can be spotty unlike the web which by definition (at least on first load) is always connected to the internet, and I'm using Flutter for this use case, as well as a backend in Rust. Other local first solutions are generally agnostic to the client and server because they work directly on the database layer, ie ElectricSQL and PowerSync will sync the client and server database. Other solutions with CRDTs can also work on the client and server with some FFI, ie automerge is in Rust so in my case it'll work via FFI on the Flutter side via flutter_rust_bridge (or WASM on the web) and of course on my Rust backend server, but it looks like you are looking to offer a more classic client-server syncing solution instead needing conflict free resolutions on disparate clients, ie the server is the source of truth.

So with all that, my question is, is there a reason you guys went with more of a full language level solution rather than being more agnostic to the client and server? It seems harder to support other languages and frameworks other than JS based ones in the future, but I suppose the market for that is already big enough. ElectricSQL etc also have SDKs for TypeScript as well as Flutter and others so they are similar to your solution but it seems like they can support more clients and servers in the future just by building SDKs for them.

Another question, looks like you eventually want to compete with Supabase but they are already experimenting with database level syncing and CRDTs in Postgres [2] and might catch up with your solution, any thoughts on that?

[0] https://www.youtube.com/playlist?list=PLTbD2QA-VMnXFsLbuPGz1...

[1] https://localfirstweb.dev/

[2] https://news.ycombinator.com/item?id=33931971

matlin
0 replies
1d23h

That's cool that you saw my presentation!

Re: Flutter (and other native support) it's something we've thought a lot about (Flutter specifically comes up often) but we decided to focus on pure-Typescript to start because it's a big enough market (I'm personally a big believer in the future of PWA's) and we know we can make the best experience by focusing on it. I do think that we'll eventually make something more platform agnostic but not sure when that will happen.

Re: ElectricSQL & Supabase: both teams are obviously very talented and thoughtful and, I believe, will continue growing in the SQL space which is the most fundamental difference between our approaches. I think Triplit can make the best experience for developers by avoiding SQL and think there's undoubtedly room for both philosophies.

kouohhashi
1 replies
1d18h

I used to use the meteo framework before, and I think if it's similar. By the way, is it possible to use MongoDB on the server side and Triplit on the React side? Or do I have to use a new database called Triplit?"

matlin
0 replies
1d17h

It's not currently possible to use MongoDB with Triplit, you would use Triplit's server instead but it's very easy to setup with React: https://www.triplit.dev/docs/quick-start

curtisblaine
1 replies
2d

Since this is LWW, does it mean the amount of information on the client scale linearly with the number of operations? (meaning: the more users modify a database, the more the operations log grows)? Or do you do checkpoints? How does it scale space-wise when the user does millions of ops per day?

matlin
0 replies
2d

Triplit does persist the history of edits to a given attribute but indexes on the latest values makes querying stay fast. However, LWW Registers by nature doesn't actually require storing the history that's just our current implementation that allows clients to sync efficiently even after being offline for a while.

In terms of scaling to a million-ops per day we are probably not quite there yet but one advantage to having the server be the authority is that, in the future, the Triplit server could track the timestamps that each client last synced at and progressively prune the history similar to how Postgres handles VACUUM'ing dead tuples.

armincerf
1 replies
2d

We’ve been using triplit to store user settings that can be managed by admins, it’s important users always feel like the app runs locally and they often don’t have good internet but we still needed sync as the users often switch devices and admins need to see and manage other users settings.

Overall triplit has been really great, both as a frontend dx and also their support - whenever we find an issue or have a feature it gets handled very quickly by the team which is awesome!

As soon as they have an answer for HA deployments we will be moving more critical data there instead of Postgres

matlin
0 replies
1d23h

It's been great working with you to get things right. Your feedback and bug reports have helped immensely to shape Triplit!

alex_lav
1 replies
1d23h

This looks great! I would like to use this tool.

I'm looking through the docs for more info on this line:

The server supports different storage adapters, such as SQLite

What are the other storage adapters? I may just be blind, so if so please forgive me!

matlin
0 replies
1d23h

There are adapters for LevelDB, LMDB, and File storage. We just use SQLite out of the box because it's fast and reliable. We'll make those other adapters more accessible in the future.

v4akukdX
0 replies
1d

Nice!

troyjfarrell
0 replies
2d

Looks like it could be a more batteries-included/opinionated alternative to RxDB (https://rxdb.info). The relational queries might help some people who tend to think in SQL as opposed to documents (as in CouchDB or MongoDB) and the WebSockets for synchronization will help people get started more quickly. (RxDB provides interfaces for those who want to implement their own storage engine and/or synchronization backend.)

pantulis
0 replies
1d4h

Remotely reminds of Joyent Slingshot. Oh, how times have changed.

kvonhorn
0 replies
1d21h

I used to work for a startup called TripIt 15 years ago. Took a double take when I saw your name.

danman114
0 replies
1d6h

That's really interesting & cool - I'm gonna look into this for sure!

I'd like to mention the Meteor.js framework (https://www.meteor.com/) too, which is in a bit of a transitioning phase right now to Meteor version 3, but is a really amazing full-stack app building solution I and many others have been working with for ~10 years.

It has a lot of batteries included, build system, pluggable frontend frameworks, lots of libraries, based on node.js, meaning it's pretty much compatible with the Node.js environment.

It's based on a really pretty simple syncing strategy for years:

It's original client side data provisioning layer is based on having

a) MongoDB on the Server and b) a javascript-native implementation of a subset of MongoDB in the Client.

Using a publish / subscribe mechanism the client can subscribe to the subset of data relevant to his current view, eg. dependent on the current user & view.

Updating is theoretically possible by using a syncing mechanism via writes into the client database and an elaborate allow/deny mechanism, but in practice most people use the following simple workflow:

Meteor also provides a method-call-mechanism by which a client can call the server to do (or fetch) stuff. So that's basically RPC in a very simple but powerful format.

These methods also allow for "client side simulations", optimistic updates to the client side database, with the changes getting rolled back / updated once the server part of the method has done it's updating of the database.

So the workflow for working & updating data in the DB looks like this:

- Data is "canonical" on the server DB

- Client subscribes for the necessary data for its client side cache

- When the user triggers an action, the client calls a method on the server, eg: "likePost(post_id)"

    - The client side simulation can actually increase the like count on the "Post" document in the local minimongo database

    - The server then executes the method & increments the like count in its database, if the request is valid
- The client syncs its database after the method has completed to make sure its optimistic update lead to the same results as the server call did on the server.

- The client updates its UI always reactively as soon as the data in its local db has changed.

All of this is very performant as long as you keep it cool and subscribe only what's actually needed for the current view,

Oh, and all of this has fine grained reactivity, on the client. The whole solution is really powerful, while deceptively simple.

Having the same API on both client and server allows for "isometric" code, meaning code which runs on both the client and the server, so you don't have to have two different versions of helper code, which is really cool too.

Meteor.js is pretty much a bit like "the old PHP experience" to me: As a full Stack developer I can write powerful apps with only one codebase which is shared in parts between client and server.

Link to Pub/Sub docs: https://docs.meteor.com/api/pubsub Link to the Method docs: https://docs.meteor.com/api/methods

8mobile
0 replies
1d13h

Wow, nice work. I will definitely try it out for my apps and backend. Do you have any benchmarks? Not sure about the AGPL licence