Exploring some ancient Git repositories on vintage pre-SSD hard-disks, code archeologists have been able to unearth traces of v8 code dating from as early as 2013—a year now generally considered as the beginning of the “v8 period”.
These old code fragments give a misleading idea of what v8 was originally meant to be. They talk about BTree, “snapshot dictionaries”, concurrent queues, XPath navigators… all giving the impression of a technology-driven effort.
And yet, the spark that lighted it all was way more practical: developers were hitting some limits of the Umbraco architecture, in their daily usage. One of Umbraco’s best asset, its Xml document cache, which keeps all content in memory and immediately available for fast rendering, was becoming a constraint.
From a technical standpoint, a monolithic Xml document is not really meant to be used as a database, nor is it designed for concurrency. Despite all efforts at working around these limitations—and users learning to “rebuild the cache” from time to time—the Xml document was causing memory and performance and stability problems.
From a functional standpoint, the content structure started to overgrow the tree structure of Xml. Content became less hierarchical, Json crept in, new content editors started to manage structured content beyond simple strings or integers yet had to “fit in Xml” somehow.
The original question therefore was: could we become more reliable and simplify developers’ life, by replacing the Xml cache with something else, that would essentially work the same yet provide more stability, finer granularity, and better support for newer content editors?
Minor to Major
Most of the old code fragments therefore implement what is known today as NuCache (or Le Cache Nouveau)—an object-based replacement for the Xml cache. It all happened in the v7 branch because, at that time, there was no v8. And the idea was that maybe, we could “just” transparently swap the cache, and solve immediate issues with live sites.
And it ran fine, and some very brave early testers even tried it on their sites, and we even supported XSLT on top of it! Alas, it rapidly became obvious that any properly-functioning cache required radical changes to other parts of Umbraco, ultimately leading to breaking backward compatibility.
And thus, the idea of a next major—v8—was born.
As soon as backward compatibility stopped being a constraint… oh the things we could do! We started to dream about dealing with all those small and irritating details we had to battle with every day when building sites. Inconsistent APIs. Weird application structure. Too many ways to do the same thing. Repetition of code.
All in all, we realized that however “convenient” the v7 codebase was, it was not very friendly. Sure, it could do many things, but in many ways, some hard to discover and understand. It could be a painful experience. And this situation was not only slowing down site implementors, but also Umbraco’s own evolution—it was becoming harder and harder to change things.
And so, v8 got defined: the simpler version.
The Maturing Years
And then, nothing happened.
Or, at least, not what you would expect.
First, v7 was relatively new, it was stable, and people loved its shiny Belle interface. There were tons of features that did not require a new major version and could be built immediately. And so, lots of efforts went into v7, leading to an impressive list of new features: new editors, grids, health checks…
Second… maybe we learned the difference between simple and easy. If you have an hour to spare, I recommend you watch Simple Made Easy, a 2011 talk by Rick Hickey. Rick is the author of Clojure, a LISP dialect, and he draws a very interesting distinction between simple, and easy.
He introduces simplicity as the opposite of complexity. And complexity is what we want to avoid because it makes everything harder to understand, to get right, to troubleshoot, to maintain, to grow. For instance, complexity is having 3 or 4 different but vaguely similar methods to modify a document in Umbraco.
He argues that simplicity is often erroneously mistaken for easiness, when they are really two different things. Easy means immediate, close to us, quick. And maybe it was easier to have these 3 or 4 methods, that were originally meant to be very intuitive, versus one single method that would require a bit of reading of some documentation.
If one chooses easiness, things move fast but accumulate complexity.
If simplicity is chosen, the project starts slower because one has to think things over.
And leaves us with this question: if v8 is the “simpler version”, what does that mean?
And so, while v7 gained features, some background work took place to slowly grow v8. It was not to be a ground-up rewrite—that had been tried in the past and... let's say it did not end well. We imposed ourselves a constraint: it had to build and run, at all time.
It has been a long effort of working with legacy code and refactoring, cleaning things up, re-designing parts. Accepting to make things better if not perfect, and then maybe better again. Always keeping the original goal in mind: is this making things simpler?
And then, sometime in 2017, we started talking about shipping… and realized that the v8 “vision” had become a huge list of cleanup ideas—and of course, meanwhile, some new feature ideas had crept in too. It seemed that anytime we cleaned something up, we had added two more cleanup opportunities to the list. And we came to the frightening realization that we would never, ever, manage to complete it all.
Thankfully, this was the time a brand-new CTO joined HQ, with little Umbraco experience—and that actually was a plus. Under his nice but consistent questioning and pressure, we did what you do when you grow trees: we trimmed v8. We learned to abandon the dream of doing everything—and it sure was frustrating at times—in order to achieve something at all.
Feature-wise, v8 was to be:
- Content Apps, simplifying how the backoffice can be extended;
- Infinite Editing, simplifying editor's day to day life by reducing round-trips in the backoffice;
- Multi-lingual, providing core support for multi-lingual content and simple tools to build multi-lingual sites.
Refactoring-wise, we would stabilize what had been done already.
We also started to proof-check what we had done. For instance, we had “simplified” the codebase by introducing a dependency injection container. Problem is, community had some feedback: though technically sound, it was in no way “simpler” for users.
I've been reading through the source for V8 and there's something really worrying me about the DI implementation. [...] I cannot recommend strongly enough that you alter your approach now before it is too late.
We engaged into some more refactoring, this time involving community members. We asked people to create PRs, but not "perfect" PRs: rather, work-in-progress PRs. And then we started pair-programming in these PRs. We learned how to, humbly, exchange ideas, share unpolished code, and welcome criticism. Some of these PRs could go on for months, before being merged.
And the same thing happened internally. With D-Team growing, new developers started to question some choices, and we had to learn how to not break everything today, but slowly keep track of where we want to go. All in all, growing v8 has also taught us a lot of lessons on how to manage the codebase. How to make bold changes through small, manageable steps. How to give structure to code—however imperfect that structure may be—so that it then becomes easy to change the structure itself.
Yes, there is a “beyond v8”. v8 will ship at some point—it is getting closer everyday—and it feels good and exciting. It will not be the ultimate, perfect Umbraco, but it is so much better than v7!
Because we already know this: by cleaning up the CMS, we have started a virtuous circle: getting things simpler gets simpler everyday things gets simpler. Maybe you want to read that sentence again.
It is our hope that v8 is not only a better and simpler CMS, but also a better and simpler codebase, enabling faster turnaround of new features and new simplifications. With Headless, .NET Core, Deploy and many other features on the radar, the future looks promising.
Stéphane is on Twitter as @zpqrtbnk