I recently applied and was accepted for the $1,000 grant tier from Clojurists Together. Afterward I asked the fine folks at JUXT if they’d like to pitch in as well—since Biff is built on XTDB, it seemed like a good fit. They’re now sponsoring Biff/me for $1,000/month. I’m deeply grateful!

Biff is a Clojure web framework which I first released in mid 2020, after a year and a half of bouncing around between different libraries and platforms as I taught myself Clojure web dev. I’ve been using it ever since for my own startup attempts—the latest of which is now a year old and is bringing in a couple thousand bucks per month. Since Biff’s initial release, I’ve spent time on it primarily to meet my own needs. I did put a lot of work into the documentation, and I’ve had a couple big follow-up releases, but other than that I haven’t yet put in the consistent work necessary to build a community around Biff. There are some people who have tried out Biff (I know from the bug reports), but I’m not aware of anyone using it in production other than myself.

(Did I mention we’re a logo on XTDB’s landing page? Look, we’re cool!)

Untitled

A couple months ago my gut started telling me that I should invest more time in Biff. I think it has a lot of potential, but it’s taken a back seat to the business since my savings won’t last forever. I see Biff as a long-term, important-but-not-urgent project. Now the business finally has enough traction that I feel comfortable with increasing Biff’s priority. I’m now spending Fridays + some time over the weekend to work on Biff, and I’ve started soliciting sponsorships to ensure that I can continue to justify doing so.

With that out of the way, let’s talk about what’s next for Biff! But first, some background for the uninitiated.

Some background

Biff is designed to help solo developers move fast. When you create a new Biff project, you start out with a minimal-but-complete starter web app, including scripts for provisioning and deploying to an Ubuntu VPS. Biff tries to make as many decisions for you as possible.

Biff is also designed to avoid getting in your way as your project grows (a common criticism of frameworks). As much of the code as possible is written as library code, often in the form of high-level helper functions for other libraries like XTDB and Reitit. The glue code is stored in a project template and copied into new projects a la Luminus, so it’s easy to change. And the various pieces are put together using something kinda-sorta like Component, but more minimalist (it’s about 10 lines and is essentially the same as (fn start-system [config components] (reduce #(%2 %1) config components))).

Also, Biff is tiny. In the mostly-finished next release, Biff’s library code is about 1,100 lines, and the example/template project is another 500 lines.

In general: Biff is designed to meet my needs as an early-stage bootstrapped entrepreneur, with all the trade-offs that entails. I’d like to expand out gradually from there. I think the Clojure ecosystem would benefit from having an opinionated, batteries-included, “simple and easy” web framework with lots of documentation and community support, and maybe Biff could become that.

(There is some scope overlap between Biff and Luminus/Kit—however there are also lots of differences between the projects, so I don’t think my time spent on Biff will be duplicating anything that’s already been done, the Lisp Curse meme notwithstanding 😉)

What’s next for Biff

Biff has evolved quite a bit since the original release. About every 8 - 12 months I make a release with significant changes based on my experience using Biff daily. I’m in the middle of another such release.

The first big change is that I’ve decided to remove the ClojureScript/SPA parts of Biff and instead go with “HTML over the wire,” the same approach used by Hotwire, Phoenix LiveView, and HTMX. See also. (I’ll be using HTMX for Biff). Biff was originally inspired partially by The Web After Tomorrow and Firebase. The idea is/was to abstract away the server as much as possible, so you mainly just write frontend code and it feels like you have direct access to the database. That includes real-time updates—I attempted to extend the reactive programming model so it reached all the way to the database, instead of just covering client-side state. That eliminated the need to write data synchronization logic between backend and frontend. If something relevant changed in the database (e.g. in a chat app, someone sends you a message), the change was synced to the frontend by Biff and then rendered by React. It was basically a clone of Firebase’s realtime queries for XTDB, and it worked great for the scale I was working at.

However, six months after Biff’s first release, I pivoted my startup and started building applications that didn’t need the full interactivity of a SPA. I added an option to Biff’s project setup script so that you could specify if you wanted a SPA or a server-rendered app. But since I wasn’t using the SPA features myself, they weren’t further developed. By switching to HTMX, we can have a single default setup that (1) doesn’t have the extra complexity of a SPA, and (2) supports enough interactivity for most applications (including real-time updates via web sockets or server-sent events).

The second big change is that I’ve switched to a develop-in-prod workflow almost exclusively. Instead of starting up a JVM on my laptop, I connect to the production web server and/or worker over nREPL. Code changes are deployed as soon as I eval them, and the updated files are rsynced to the server(s) on write, so changes won’t be lost if the process restarts. Since my app is server-side rendered, the entire application can be developed this way. Obviously this isn’t the right choice for every situation, but it’s been a huge productivity boost for me, and since Biff prioritizes small projects, I’d like to enable this workflow out-of-the-box. (Though the regular develop-locally-then-deploy workflow will still be first class too!) I will however need to do a bit more experimenting to find the right setup, since my current setup can be brittle, and I’d like anything Biff provides to be robust.

(Incidentally, Biff’s develop-in-prod workflow might also be a nice way to demonstrate REPL-driven development to not-yet-Clojurists, since the “what’s so great about the REPL” question seems to come up a lot. Perhaps Biff could even run VS Code on the server, with Calva etc preconfigured, so the entire getting-started flow is “(1) click this button to provision a DigitalOcean VPS with Biff pre-installed, (2) go to this URL to open VS Code, (3) save any file to deploy code changes.“ A bit like Replit. But I digress.)

Other than those two things, there are a handful of smaller changes based on my personal experience using Biff, some of which I’ve already completed. Here’s the entire todo list for this release.

Completed