untangled
A ClojureScript-based webapp framework
Why Untangled?
Untangled has this central design criteria: Simplicity. Eliminate as much incidental complexity as possible. Allow the developer to solve the problem at hand without having to juggle arbitrary boilerplate code and patterns that are unrelated to the real problem.
Some of the items that generate this incidental complexity in today's webapps are:
- Mutable state
- Object-oriented artifacts that poorly fit the problem domain
- Controllers that cobble together UI, user interaction, and model logic
- Ever-expanding screen-specific REST interfaces that are intended to be "general" but end up being specialized.
- Hidden (mutable) state that gets out of sync with reality (e.g. why is that date picker still showing?)
- Testing suites that are hard to set up, and don't run in the real environments you use, or that stress the UI instead of getting the real logic correct.
- UI tied to concrete domain logic (instead of abstractions)
- Two-way data binding
Why ClojureScript?
Our desire was to have a full-stack functional programming environment. The Clojure/ClojureScript story and pairing are actually quite compelling in this respect:
- A common, powerful, functional programming language for client and server.
- Metaprogramming (e.g. macros) that are much simpler than alternatives.
- Runs on the JVM (clj) and all browsers (cljs)
- A wonderful immutable app-state story for the browser. Leads to all sorts of powerful and useful results.
- Powerful (Google Closure) compiler support for optimization and minification
- Existing tools supporting hot code/css reload (without losing app state)
- Common data structures that can be used on-the-wire
- Browser libraries like Om that significantly simplify the webapp architecture
Untangled offers a pretty radical approach based on a combination of ideas from leading thinkers in software development. At the same time it is intended to be as pragmatic and usable as possible today. The Untangled team is a set of motivated professionals that use the framework in a production environment to generate real enterprise applications.
Simple, you say? Looks hard to me!
We consider simplicity an objective measurement: Minimal complexity. Easy and hard are relative terms (e.g. German might be easy for you and hard for me). We derive this standpoint both from our collective experience and from Rich Hickey's wonderful expression of it in his talk Simple Made Easy. Hard is something you can address on a personal or team level through training and time. Complexity is, well, complex! Looking at problems from different angles can often reveal simplifications, but eventually you'll arrive at the simplest possible solution (yet found). To us, hard is about the ability to reason. It is about not knowing what happens because of out-of-order execution. It is about having to write and understand dependency injection for every artifact in a system. It's about work and thought that just gets in the way of solving your problem.
Untangled Core Concepts
Untangled leverages a lot of things that were pioneered in Om 1.0 by David Nolen, and adds its own layers of simplification and opinion. The things you need to understand in order to build a simple application are:
- The client database format
- How UI queries work
- Basic mutations/transactions that update the database
It's that simple! Om deals with the rendering story. You model your data in a very simple-to-understand graph database format, write some queries and mutations, and you're well on your way to done!
Om keeps the UI up-to-date (with some nicely abstracted help from you). Untangled adds in the networking, testing, unhappy path considerations, temporary ID handling, predictable server data merging, sequential semantics, i18n, and more.
Extending that to a server requires you know almost nothing new! The same code structure for mutation is used there, with very slight augmentation for dealing with temporary IDs. The one additional server requirement is that you learn how to handle data queries from Om.
Four high-level concepts which can feel foreign at first, but soon become easy. So, which do you want: easy to start and hard to maintain, or some initial discomfort with more simplicity in the long run?