In order to understand the whole point of the article, let me explain to you what is Schibsted Spain. Schibsted Media Group is one of the world’s leading online classified ads businesses, active in 22 countries around the world and reaching more than 200 million people worldwide. One of those countries is Spain 🇪🇸. In Spain, as Schibsted Spain, has different marketplaces. For Real Estate you could find Fotocasa, Habitaclia, for jobs InfoJobs, cars and motos in Coches.net, Motos.net. For the generalist, you could find Milanuncios and Vibbo.

All these marketplaces are, in fact, different products with different teams and, yeah, different developers with different opinions but, yet, very similar needs. We had spread the same company a dozen different tools to create bundles (Browserify, Webpack, manual systems…), for each we had different versions in many different repositories. And, imagine that, everyone with different configurations that supported different files in so many different ways. In one word: a chaos.

Example of the old days. A single React component in Schibsted Spain. With a bunch of files starting with a dot for config and its own Webpack configuration for creating a demo for it. Still available at https://github.com/SUI-Components/sui-autocompleted

One year ago we decided to solve this and move forward. In order to do so, we iterated over the team called Enablers Frontend. This team main objective was to grow a common frontend architecture, giving a response to all products needs while focusing on making it scalable, resilient, replicable, robust and as much cutting-edge technological possible.

Relying on Compatible Versioning. So developers always get the latest fixes and features for free using the major.

For this, we started creating a set of tools called SUI (Schibsted User Interface) in order to extract core functionality and tools for packages. We saw these tools like our AAAS (Architecture as a software) and focused on following the Unix rules in order to make the tools as much as modular, independent and replaceable as possible. Basically, we could change a whole tool always that the entry parameters and the output remained the same.

We also embraced other things: zero config Javascript (#0CJS), in order to avoid dot points and config files in our projects and repositories; and Compatible Versioning in order to rely always on the major version, get the new features and fixes for free and be as less disruptive as possible. Both characteristics forced us to be very careful about our decisions but, after one year, I could say that it was a success.

Sean Larkin talking at the JSCamp about what zero config means in terms of Developer Experience

@s-ui/bundler, using Webpack as the building platform

So, one of the most important things that all our projects had in common was a way to create the bundles. While some used Browserify, some used Gulp, and others started to use Webpack. We created a new tool called @s-ui/bundler to unify the way of creating it based on Webpack, as it was clearly the de-facto way of bundling apps in the frontend.

“What if it means that you could take just by defining this tiniest package […] and instantly, without needing configuration you automatically have those setups or specifications that you need for your build systems.” — Sean T. Larkin at JsCamp 2018

This offers a set of rules based on the minimal assumptions possible. For example, support to Sass and ES6 files using Babel with a babel-preset-sui. We tried to keep these assumptions as little of possible in order to be able to iterate fast and evolve quickly our dependencies. For example, from Webpack 1 to the actual Webpack 4 we haven’t had to do great changes and we haven’t had to create many majors of @s-ui/bundler in order to the users to adopt it.

But, as you would see, @s-ui/bundler is not a simple preset over Webpack as it also provides:

Zero configuration to get started. Just put an index.html and app.js and you ready to go.

Just put an index.html and app.js and you ready to go. Development mode with some goodies like Hot Reloading, errors in screen and where you could easily link external packages with a link-package parameter. The main difference with npm link, is that the files are compiled on-the-fly with babel which results in a fastest hot reloading. Compatible with SASS files as well.

like Hot Reloading, errors in screen and where you could easily link external packages with a parameter. The main difference with npm link, is that the files are compiled on-the-fly with babel which results in a fastest hot reloading. Compatible with SASS files as well. App Bundle, Lib mode, and Server compilations.

Built-in CLI for all the commands and also a way to analyze the bundle.

and also a way to analyze the bundle. A set of optimizations for CSS and chunks.

If you’ve got the expected project structure, you’ll be able to start a development environment with a single command

So, @s-ui/bundler gives you the possibility of creating your web app in a few seconds with the minimal boilerplate but with the desired structure and technology that we want to follow in Schibsted Spain across all the projects. But, still, there’s more…

Evolving the platform, building on top of it

In Schibsted Spain we decided to embrace React and use it to build all our UI so, as you could imagine, building your app with @s-ui/bundler let you use React as well from scratch. You just install the dependency and you’re ready to go.

Obviously, all our projects are aimed to be SPAs. Also, we wanted to offer to our developers a very easy way to create a Server-side rendering experience for their products. For that, we created two separated tools: @s-ui/react-initial-props and @s-ui/ssr.

@s-ui/react-initial-props, the first stone for universal apps

If you’re creating an SPA in React you might be tempted to fetch the data for your app in the componentDidMount. So, you could control when the data is available in order to show a placeholder. This might be right, but if you plan to create a universal app could not be convenient as in the server-side the life-cycle componentDidMount doesn’t get executed.

@s-ui/react-initial-props package offers a way to make your easily your app isomorphic. It let you create a static method called getInitialProps for your page component. This method, which returns a Promise, will be loading the chunk of your app.

You could pass a contextFactory in order to create the needed context for your page. The contextFactory should be universal. loadPage will execute the getInitialProps static method for you and deal with the async chunk.

loadHomePage has a component that will deal with the asynchronicity for you. You could even add a renderLoading in order to render a component while fetching the data.

As you can imagine, the method getInitialProps needs to be universal, the code should be executable in the server and the client. For that, getInitialProps receives the same parameters in both environments.

This approach is convenient as it avoids re-renders as other options like React-Transmit that caused a long time to respond, especially in the server.

@s-ui/ssr, transform your SPA in a Server-Side Rendering App

If you were using @s-ui/bundler and @s-ui/react-initial-props… what would you think if I say to you that you could have for free a server-side rendering app without writing a single line of code?

@s-ui/bundler is a big piece of our Lego. It connects well with @s-ui/react-initial-props and, if you do so, you’ll be able to connect with @s-ui/ssr to get Server-Side Rendering by writing zero lines of code

@s-ui/ssr package essentially relies in the convention used in @s-ui/react-initial-props so you don’t have to write a line of code to transform your SPA in a full app with SSR. Also, it doesn’t only generates the code but create a Docker container ready to be deployed and add some interesting features like the proposition of Google to perform dynamic rendering to do SSR for the bots and fetch the data in the client for your users.

This kind of tool wasn’t easy to create if it wasn’t built on top of a common platform. Now, you should think about them like Lego pieces that let you the possibility of building within the base a greater app by using this modular approach thanks for following some foundations.

Some frequent questions 🤔 and comments…

🗣 Isn’t this a simple wrapper?

Yes and no. Yes, as we’re wrapping a bunch of tools in order to provide it with a custom config and still, no, as they not only could have a config that would be reusable but also it has some nice additions (like some CLI interfaces to get the most of it). For example, isn’t create-react-app a wrapper of tools? And yet, it’s pretty powerful. Wrapping tools give a simple way of creating a project from scratch, reusing the choices, sharing the benefits of some decisions and converging to follow the same rules across different projects.

🗣 Doesn’t this bother developer opinions about what tools to use?

I understand this question. Not every developer has this concern but, usually, seniors with plenty of years of experience don’t want others to decide the tools or architecture to use in their projects. I could empathize with this feeling. However, one of the mottos of Schibsted is “One team”.

Let me say that working as “One team” in the frontend is not easy. If the debate about “semicolons or not in Javascript” could unleash a war, imagine about the limitless discussions about UI libraries, framework and different architecture approach. We try to listen and collect all the feedback before making decisions but

Also, we’re far from perfection and we’re still improving this in order to get the most of the developers comfortable but, still, some people could not just accept a different

🗣 But I think is better if everyone is free to choose whatever they want!

I wouldn’t like to start a discussion about convergence vs. divergence. From my point of view, both have advantages and drawbacks. In my experience in Schibsted Spain, converging in a set of tools has accelerated the development, improving the DX and the TTM (Time to Market) of features and new products. The start was not easy but the cost we assumed at the beginning has been more than compensated.

Now, this doesn’t mean this strategy could work in every company. As I explained in the beginning, Schibsted Spain has different products that are essentially the same structure: a marketplace. The main objective is to let developers focus on creating the best product possible without having to lose time in dealing with tools.

🗣 Still, there are better solutions out there!

create-react-app and next.js would be the most similar solutions that we could adopt. Still, there’re some important differences. We needed the build our platform to be as much modular as possible in order to be adopted by all the products step by step.

For example, we could maintain all the codebase of the old project but start using the linter, later just use the tool for testing and, maybe as the last one, use the bundler. Or maybe try to use just the react-initial-props that could give a lot of value to the user if the project already used a custom Webpack config.

NextJS, for example, provides you with a whole framework in a single piece that requires to be adopted at once. Don’t get me wrong, I love ❤️ NextJS and Zeit team but, for us, we had to build a platform for several projects at once and being able to adopt progressively the platform is a must.

🗣 I want to discuss more of this!

Well, you’re more than invited to do so. sui-bundler and the other tools are open source. Also, just post your comment or follow the conversation in Twitter. 😊 We will be happy to hear feedback to iterate or improve the platform as every improvement we perform will be shared across all our projects. Thanks for reading!