Why Biff's New Core Library Proves Simplicity Wins in Web Development
There's something refreshing about software that doesn't try to solve every problem by adding more abstraction layers. That's exactly what makes the newly released biff.core library so interesting.
If you're not familiar with Biff, it's a Clojure-based web framework that takes a modular approach to building applications. The framework has historically bundled everything together, but the team is now splitting it into separate libraries—and biff.core is the foundation that ties them all together.
The Problem with Boilerplate
The core challenge biff.core tackles is something many developers recognize: the gap between library code and application code. When a library needs to contribute something to your system (like a route handler or configuration), the typical advice is "paste this into your main namespace." That's clunky, hard to maintain, and breaks the promise of modularity.
Biff's solution is elegant: init functions. These are functions stored in your module maps that take a collection of modules and return a map to merge into your system. Libraries can ship their own init functions, and you simply add the module to your project. No pasting required.
The Late Binding Trick
Here's where things get clever. In the old Biff pattern, you'd define a handler var in your application code. This var had a hidden benefit—it supported late binding. Change your modules, and the handler automatically picks up the updates without restarting the server.
Extracting this logic into library code breaks that pattern. Libraries can't create vars in your namespace. So the biff.core approach does something smart: it uses a function on your system map instead of a value.
Instead of setting :biff/handler to the handler itself, you set it to a function that dereferences a modules var and builds the handler on-the-fly using memoization. The result? Clean namespaces that rarely need editing, but code that stays fresh.
Why No Dependency System?
The author makes a point that's worth dwelling on: Biff deliberately avoids complex dependency management for lifecycle functions. You could add metadata to express "this init function must run after that one." You could build a dependency resolver. But you don't have to.
Why? Because it's not that hard to order your components yourself. And when something is explicit and manual, it's easier to understand. The starter project handles ordering for you anyway. If you need something fancier later, you can layer it on top—but you don't start with the complexity.
This is a philosophy worth celebrating. Not every problem needs a graph-based dependency resolver. Sometimes "put things in the right order" is enough, especially when it makes the system transparent.
The Takeaway
Biff.core isn't flashy. It won't generate headlines. But it's a solid example of solving real architectural problems with pragmatic solutions. If you're building with Clojure or interested in how modern frameworks handle modularity, it's worth taking a look.
Sometimes the best code is the code that gets out of your way.
Read in other languages: