A history of Microfrontends at Swissquote

Stéphane Goetz
Swissquote Tech Blog
8 min readJul 13, 2021

It’s 2014, Swissquote has around 150 engineers. A big partnership is around the corner, and we need to deliver many features and deliver them fast! Here is the story of how we got started with micro frontends before they were even a thing.

Hi, I’m Stéphane Goetz, Principal Software Engineer at Swissquote. I’m member of the Design and Technology group, and have been working here on frontend related libraries, tools and frameworks for almost ten years now.

The genesis

At Swissquote in 2014 we had one main trading platform that wasn’t a single page app, and a smaller and newer platform in single page app form that was able to trade Options and Futures (I invite you to check Investopedia on what these are if you’re interested). Another company approached us, they were interested in replacing their own trading solution but wanted a single page app to trade securities.

The Fox (Futures and Options eXchange)

Done deal, we have those … just not on the same platforms.

The new platform had to be delivered in a very short amount of time and many new things needed to be added to it. Luckily, those features were very separate in nature. We decided to have different teams working on each feature. That’s how, suddenly, a product that had a team of 5 people maintaining it evolved to a 5 teams, 25 people product.

But how can we efficiently get five teams contributing on the same application for a fast-evolving product ? By the title of the article you probably see where I’m going; modular web applications were very rare in 2014, but we figured that … since IDEs can have plugins, why wouldn’t it be possible to do it for web apps ?

Progressively a small motivated team got to work on the foundation of our own microfrontend framework. Adding “extension points” to add Widgets, Menu items, Dynamic columns to tables, data sources and more. Progressively, the monolithic single page app became a platform that could be extended by adding more plugins to it.

The technologies behind the platform

At the risk of sounding repetitive, let me reiterate that this was in 2014, 7 years ago. In web time that would be around … 42 years? Bear also in mind that the engineers who created this platform were more used to complex, time-sensitive algorithms in Java than Single Page Applications in JavaScript.

The platform itself was written in ST-JS, most of the UI was using jQuery / jQuery UI. and the glue to hold it all together was (and still is) RequireJS.

ST-JS, short for Strongly Typed JavaScript, is a language created for the previous iteration of the application when we saw that dozens of JavaScript files with jQuery inside was hard to scale and debug. The idea is simple; you write your code in Java and it is then transpiled to JavaScript.

Think of it more like a cousin of TypeScript than to GWT. TypeScript didn’t even exist when the work on ST-JS was started.

Each plugin would expose an AMD module under the /plugin/define.js path and declare its extension points

Here is an example define.js:

The define.js is the manifesto of what a plugin is able to do

Now, the index page for the app (we call it container) contains a script similar to this:

The index page loads the plugin and initializes the framework

Leaving each plugin to do what they need with the current URL. One thing to note is that each URL can point to a different application or server. We use our load-balancer to have everything under the same domain (to avoid CORS issues).

Another key API we exposed is View:

I will not go into details for each API, but they allowed each plugin to expose the UI parts and logic they needed to add menu items to menus, columns to tables, and entirely new widgets to the workspace.

The finished product : eTrading

Consolidation

The product for which the platform was created was delivered, now was the time to extract the platform from the product and make it useable by other platforms. We extracted all the code, gave it a name (Swissquote Unified Web Platform, but mostly we call it SQ-UP) and started to create other products with it. The first product to benefit from it was the Account Overview Consolidation. A new app that would become the homepage once our clients log into their account to have a full overview of all their accounts on our different platforms (Swissquote has many products, ranging from Securities Trading, Forex Trading, Savings accounts to our automated Robo-Advisory).

A Mockup of the first platform to use the SQ Web Platform

The upside was that we were able to deliver the project, the downside was that we discovered that many parts could not be used in any other products than eTrading because they were too specific. Also, this new Product was the first where we started to adopt React and saw that our heavy reliance on jQuery made it more complex than anticipated to stop using it.

The road to Version 2

But all this made us realize many important things. First, technologies that were here for ten years (jQuery) are not guaranteed to stay forever. Second, bringing many features or API surface is not necessarily a good thing. Third, it gave us a better understanding of what is more interesting to have in common for all plugins, and what can be handled by each separately.

This is how we went back to our drawing boards and created SQUP V2:

  • Removed most APIs (We kept extension points, routing, views and notifications. Our I18n library was also left as-is, but it has its own lifecycle anyway)
  • Rewrote from ST-JS to TypeScript, TypeScript 2 had become much more mature and had a big community around already. With the introduction of @types/* NPM packages, the move became a no-brainer.
  • Ensure forward compatibility : You can run a SQUP V2 plugin on SQUP V1, but you can’t run an SQUP V1 plugin on SQUP V2 (because of the removed APIs)
  • Provide a Maven archetype (Think create-react-app but for the Java world) that contained all the boilerplate to get started including an example application using all the existing features, comments everywhere in the code and tests to show how this can be tested

But the most important thing we did was not code related; we made sure that the documentation covered all the features of the V2, a very complete migration guide and a training to get the people to spend an afternoon toying around with the features and get used to the concepts.

Not everybody has used microfrontends in the past, and jumping in that universe can feel overwhelming. We tried to make the transition from single-owner apps to multi-tenant apps as smooth as possible.

Lessons Learned

Nevertheless, we are now three years into the release of V2, and we have seen a big adoption, but not how we expected it.

All our main platform containers are still using the V1, they have many plugins using V2 as we were expecting, but each container has multiple plugins with cases of “I actually needed that little function that was provided there and thus can’t migrate”. My personal lesson learned is : start by exposing as few APIs as possible, then add more if needed.

Another reason for slow adoption is : We expose React through RequireJS so that it’s loaded only once and not by each plugin separately. The upside is faster page loads because of fewer library downloads. The downside is that before upgrading React, you need to test all plugins independently. We were not able yet to have each plugin say “I need React 16” and be able to get an instance of React 16 while others were at React 17 or 15. Although we are making progress and most containers are using React 16.8 now.

We have an internal component library where the CSS is separated from the React part. So we have a single CSS file imported for the whole application. Upgrading this is also very painful. We didn’t try it, but we feel that CSS-in-JS wouldn’t be a huge help either. It’s a trade-off between a consistent design and the ability for each plugin to be fully isolated.

We could see one more time that providing examples that worked out of the box helped a lot to use best practices from the beginning. For example, our boilerplate includes Code Splitting for routes and everybody started to naturally use it when implementing new routes. Whereas before, all the plugins would have one big bundle and would be very slow to load.

The present and the future

The technical landscape has massively evolved around microfrontends. There are now plenty of libraries to choose from. Plenty of companies presenting what they do. Knowledgeable people helping to understand the trade-offs. And if we had to start over, there are many things that we would do differently:

  • Probably go with an off-the-shelf microfrontend library.
  • Webpack 5 module federation to share some dependencies
  • Drop RequireJS; it’s a powerful library, but maybe in-browser dynamic imports can be better suited for this in the future.
  • Provide only a tiny API surface; Routes, Views and extension points could be enough to start building most applications.

We did get some big parts right too; there are many things that we would probably do the same:

  • Framework-agnostic: We use React, but each plugin can use a different technology if they need to. That keeps the integrations cleaner to use.
  • Common Styles, maybe not exactly the way it was done currently, but having the look-and-feel dictated by the container feels like a must.
  • We still see the advantage that multiple teams can each have the ownership of a part of the UI. Not everybody knows the business of everybody, and to stay efficient, they probably don’t need to.

Conclusion

It’s 2021, Swissquote has more than 250 engineers, many more teams, and more need for decoupling in our architecture than ever before.

This brings me to the end of this article. Here are the main takeaways :

I think that starting to use microfrontends was the right strategy in 2015, but maybe it was a bit too early. Doing micro frontends in modern browsers seems much easier today, and there are even more reasons to use it now, if the structure of your product and organization is a good fit for it.

Our early move to microfrontends also paved the way nicely for our adoption of Self Contained Systems (presented by my colleague Marc-Olivier Fleury in a previous article : Our journey from Microservices towards Self Contained Systems)

A quick internal survey with our frontend engineers showed that they believe microfrontends is the way to go in our case but that SQ-UP is probably not the best way to get there. That’s definitely a thing to take into account; any home-made solution, if left unattended, WILL become obsolete. If possible, design your home-made solutions to be simple and easily replaceable if you know you won’t be maintaining it full-time.

When designing an home-made tool, framework, library, be sure to make it in collaboration with your first users. There are not many things worse than creating a whole new platform and discovering on first use that it doesn’t fit the use case for which it was created.

I’m confident that we will continue with microfrontends in the foreseeable future. I am looking forwards to discovering how their implementation at Swissquote will evolve, and how far it will get!

--

--