StranglerApplication pattern: a legacy frontend use case

Or “how we transformed an AngularJS application in a shiny new Frameworkless application”

Francesco Strazzullo
Flowing
5 min readSep 24, 2018

--

What makes a codebase “Legacy”? I think that there’s no unique answer to this question. Most people associate the idea of legacy code to the fear to modify the code. It could be the absence of tests, obsolete tools or other factors. But I think that there’s something more. A good visual representation of legacy code is a cage.

Photo by Martin Wessely on Unsplash

Why a cage? Because I feel legacy code is something that can hinder the evolution of a software. In other words…

Legacy code is a roadblock to adapt software to new business needs.

Let me share with you a story.

In 2013 we started a new greenfield frontend project. We chose to use AngularJS, and it was the right decision to make.

It was a good decision.

The software, at the time, was part of an experimental business. Neither our client nor our team knew if users would be interested in that software. And when you are developing a software for an experimental business your most important non-functional requirement is to have quick feedback. AngularJS at the time was a de facto standard for the JavaScript community and it helped us to have the velocity needed to bring the software to the market as soon as possible.

Let’s jump now four years in the future. it’s 2017 and the software is a success. Most of the income of our client derive from this software. Another thing changed in the meanwhile: AngularJS died.

We’ll miss you

Angular being dead was not a problem per se. It was a problem because our business context changed drastically and our non-functional requirements changed with it. Velocity it’s not our top priority anymore.

Our greatest concern right now is the Longevity of our codebase

When we realised that our context changed, AngularJS transformed itself from an asset to a liability. Or, if you prefer, it became a cage.

When we realised that, we made a very important decision.

We decided not to use AngularJS from the moment on, and in order to keep our longevity at the maximum level possible we decided not to use another framework.

But how can we do that with our application currently in production?

A cut-over rewrite was not an option. It would take at least a year to release a frameworkless version of our project, and this scenario was not acceptable by our client. So we came up with a more feasible approach, the StranglerApplication pattern.

Photo by Kate Ausburn on Unsplash

To apply this pattern, a new application is created. This new application will slowly replace (or strangle) the old one, until the old application is so small that you can safely remove it.

In our specific case the old application was AngularJS web application built with Grunt, and the new one is a frameworkless application built with webpack.

After the creation of the new application we imposed ourself a very simple but strict rule: no commits on the old application. Every new feature should start in the new part of the application, and every change request or fix to the old part should start with the porting of the old code in the new environment, adapting it.

A schema of our StranglerApplication

In this post I will not go in detail about the code part, I will just say that:

  • we converted every service to a standard ES Module
  • we converted every controller or directive to a custom element
  • every ES Module is accessible by the old part as a service using a simple bridge function

If you are interested in more details about how to implement this kind of solution for your project you can checkout this GitHub example. In that repo it’s possible to see how, with every commit, a piece is moved from the old application to the new one.

I’ve also talked about this topic at JS Day 2018 in Verona. In the talk I explain briefly how the bridge function is designed.

My talk at JS Day 2018.

What we Learned

We learned a lot from this refactoring. The first and probably most important thing is perfectly summarised by this quote from Gerald Weinberg.

Don’t be rational; be reasonable.

What I mean is that when we first tested this solution during an Architectural Clash, we felt that it was too “strange” to really work in production. But we decided to give it a try and we loved it. Ideas that seem “not right” but that are good enough for your context, need to be explored with some experiment before deciding that they are really “not right”.

Another thing that we learned the hard way is that strangling a web app is a very long and laborious process. So when we design a new piece of software we try to design it in a way to make it easier for it to be strangled in the future. One of the principles that we adopt is the Sacrificial Architecture always by Martin Fowler.

At last we learned that working without frameworks on the frontend is completely doable with the right people in your team. From this experience we decided to create the Frameworkless Movement: a group of people interested in developing without frameworks and helping everybody make mindful technical decisions.

If you want to talk about StranglerApplication pattern, legacy frontend applications or the Frameworkless Movement just contact me on Twitter, my DMs are open.

Update: I talked about this topic at JSDay 2018 in Verona, you can see the video of my talk here:

If you liked this post, you can buy me a virtual coffee ️😊

Buy me a coffee

--

--

Francesco Strazzullo
Flowing

Partner @ flowing. Author of “Frameworkless Front-End Development” and “Decision-making for Software Development Teams”