Fork me on GitHub

Biff looks like it might be exactly what I need. How tricky do you think it'd be for me to use Datomic instead of Crux?

Jacob O'Bryant04:06:20

Hmm... it would take a fair amount of work but I don't think you'd run into any huge issues. Mainly you'd have to dive into One thing that comes to mind is that converting Biff's transactions to Datomic transactions will be more complicated since when updating a document in Crux you just clobber the entire previous document basically, whereas in Datomic you have to specify explicitly which datoms you're adding and retracting. Though it just so happens that I have written code to do that; check out (and follow the link to trident.datomic-cloud/tx which is aliased in the gist as tcloud/tx). I was using Datomic up until about February, and I had barely started using a transaction + rules system similar to what Biff has. That code is a little messy (not to mention the whole biff.crux namespace...) and probably incomplete but might be helpful. If you wanted to try doing that I'd be happy to give direction, code explanation, etc. along the way. I bet lots of people would be interested in having Datomic as an option.


@foo I have yet to re-try the example code, but thanks for the heads up. Why did you end up choosing Crux? I know you were originally considering Datomic for Biff... I have been excited to try Crux. I was impressed by Juxt by using thier Tick time library, and Reitit looks equally well thought-out. I liked their ethos and efforts at promoting and documenting Crux. I have always wanted to use a logic/graph db. I am curious about the value of bi-temporality. But I never quite got around to using either Datomic or Crux directly, as my code was primarily front-end SPA. So I am largely ignorant. Your thoughts?


I updated the example code in my repo and synced it with my droplet instance. Looks like it's up and running now!!!!simple_smile I still dont understand how scp config.edn <mailto:[email protected]|[email protected]>:biff/prod/ command works. How could the file get into biff/prod, if I am running that command on my local copy of example/ ? But somehow it must have worked, because now there is biff/prod/config.edn on the remote.


I tried the email login -> console token link. It worked. I was able to give a username and game id and start the game!

Jacob O'Bryant20:06:26

Great! glad it's working. About the command--scp is like cp, but it goes over SSH. That's why you have to specify ; that tells scp to connect to the that machine via ssh and then copy the file from your local machine. Also, relative paths are based on the user you log in as, so ...:biff/prod expands to ...:/root/biff/prod . You can also do commands like these:

scp :foo.txt bar/  # copy a file from remote machine to the local machine
scp :foo.txt :bar/  # copy a file from one remote machine to another remote machine
rsync is another useful command for when you have more sophisticated copying needs (like copying a directory without re-copying files that are already present on the destination). I used Datomic pretty heavily in my own projects for about a year prior to switching to Firestore and then Crux. My opinion on Datomic vs. Crux is that Datomic is more powerful and can probably scale better, but Crux is easier to get started with and has a lot less operational overhead (in terms of developer time). I've had many headaches from my time using Datomic (and AWS, which Datomic Cloud is coupled to). On the other hand, using Crux has been smooth (and you can use DigitalOcean instead of AWS, which I love). Since Biff prioritizes the solo-developer / early-stage / rapid-prototyping use-case, I think Crux is a much better fit. Whereas if I was in a situation with many developers/delivering an application that I knew would have scale once released, Datomic Cloud Ions I think would be great. Off the top of my head, a few more reasons: • I like that Crux doesn't enforce schema, which made it easy for Biff to use it's own schema (i.e. rules). I also think it's better for rapid-prototyping when you're still figuring out the schema and it changes often. • Although Crux is less featureful, it's good enough for me. It's immutable and has datalog queries with sub-clauses (`or`, not, etc). In some cases, it makes Crux easier to use which could be considered a benefit actually. e.g. transactions in Crux are much less complex than in Datomic. • Crux is open-source. I'm a pragmatist and I don't mind using a closed source DB like Datomic in an app. But for Biff, a web framework intended for other people to build their apps on too, I'd rather not have a hard dependency on something closed-source. It'd suck if a feature broke in Datomic that was critical for Biff but low-priority for Cognitect. (I have a small budgeting app on Datomic that was down for several months because of that). • For hobby projects, you can run Crux on DigitalOcean with filesystem persistence for $5/month, whereas Datomic Cloud starts at $30/month. Doesn't matter for a startup of course, but I wouldn't want to be shelling out $30/month forever just to keep that budgeting app running. (heck, if I had written that app with Biff, I might just run it exclusively on my laptop and then pay $0).


This is very helpful insight. Understanding your design decisions really helps me make mine. Knowing who you are seeking to serve makes all the difference as I grok your work. Excellent. Really. Thank you. In full production, I’m almost certainly headed for Datomic: • scale • schema • datoms • cost (a recent change) • code in the same VPC (Ion) • access to other AWS resources like Cognito And you know all of this far better than I do. The complexity attending an AWS-based implementation is indeed daunting. AWS really is an online operating system. The Datomic team’s templates do help. I’m struggling with the “where to start?” question. Biff is certainly the best for an MVP. It’s the MVP->NVP (*N*ext *V*iable *P*roduct) migration and the required effort and churn that are on my mind. Again, thanks. I’ll be talking all this over with the team.

Jacob O'Bryant20:09:17

Sounds pretty reasonable! One thing you might consider is playing around with Biff a bit just to get a feel for how it's structured but then build the MVP without it. Then if there are any parts of Biff's architecture etc that you do think would be helpful, you can follow the same design/copy-and-paste stuff over. The would be a good thing to understand, and then you can pretty much learn everything else just by reading through the example app's source and the (about 2k LOC last I checked).


Making a pre-MVP with Biff to get a feel for architecture is helpful thinking. “And” instead of “or”. You are a wonderful example of this community. I’m looking forward to being more useful here.

Jacob O'Bryant21:09:50

thanks, I'm flattered 🙂


No flattery intended. You’re water on dry ground.

Jacob O'Bryant22:06:47

Oh, and about bitemporality: I haven't used that feature myself at all yet. Although that's the main reason Juxt made it in the first place, the reasons above are what I care about personally. It might come in handy at some point for me though.