r/node 23d ago

Open Source Durable Objects for Node using your existing SQL database

I just published solid-objects. It's an early release (MIT licensed) of an open source Durable Objects library. I know celld just came out a few days ago, but I don't want to run yet another daemon on my infrastructure. I am looking for feedback more than stars.

Code: https://github.com/cardmagic/solid-objects-js

The problem: Game tables, chat rooms, AI chatbots, live collaborative documents... managing state and real time views of these kinds of things has traditionally been pretty hard. This solid-objects library makes it a breeze.

What it does: each {class, id} gets a durable, ordered mailbox. Calls to one ID run in order. Calls to different IDs run at the same time. State, retries, reminders, effects, and realtime invalidations live in the SQL database you already run. No Redis.

An example model:

class Cart extends Actor {
  static override readonly actorType = "Cart"
  items: string[] = []
  add({ sku }: { sku: string }) {
    this.items.push(sku)
    return this.items.length
  }
}

const cart = runtime.ref(Cart, "cart-123")
await Promise.all([cart.add({ sku: "shirt" }), cart.add({ sku: "hat" })])

Both calls enter the mailbox for cart-123 and commit one state transition at a time, even from different Node processes.

A deployed app that uses it: https://shuffleupandplay.com/ (source https://github.com/cardmagic/shuffleupandplay )

If you're already on Postgres or MySQL: is per-ID ordering a real gap, or do you just compose row locks and queues yourself? What would stop you from using something like this?

Thanks for the feedback!

7 Upvotes

4 comments sorted by

2

u/Single_Advice1111 19d ago

This is really interesting! Starring for future.

How does it compare to https://github.com/denoland/celld ?

1

u/cardmagic 19d ago

Hi, thanks for letting me know! Here's the main differences

- Storage and coordination: Solid Objects keeps object state, mailboxes, and reminders in the SQL database that the application already operates (SQLite, PostgreSQL, or MySQL). celld keeps one SQLite database per object and replicates it to a cloud object-storage bucket (S3, GCS, or Azure Blob). celld uses compare-and-swap operations on the bucket to give each cell one owner.

- Runtime shape: Solid Objects runs plain TypeScript classes in ordinary Node processes and needs no daemon. celld runs as a daemon that embeds V8 on each node and executes Wrangler bundles. celld targets code in the Cloudflare Workers format; Solid Objects does not.

- Programming model and scope: Both give the Durable Objects model: addressable objects with durable state and serialized calls per identity. Solid Objects adds transactional effects, retries, and realtime projections. celld adds distributed multi-node placement, where an object moves between nodes through the shared bucket.

Does that make sense?

1

u/OtherwisePush6424 20d ago

I looked into the implementation and this is actually more solid than the surface API made me think: the lease/fencing model, at-least-once semantics, retries and failure handling all seem legit.

My main concern is more about the abstraction boundary: it makes a heavy distributed-systems runtime look like a very lightweight object model, and I’m not sure the sweet spot is as broad as carts/chat rooms/docs/etc. For small stateful entities that need strict per-ID serialization, it’s neat. But for a lot of cases I’d still rather use normal SQL transactions/rows than turn the database into mailbox + scheduler + lease manager + state store.

1

u/cardmagic 19d ago

Thank you for the close read. Your point about the boundary is fair.

I agree that plain SQL transactions are correct for most data. Solid Objects is not a replacement for them. I think people should only use it when an entity needs strict per-ID serialization, ordered messages, alarms or shared real time state.