World-class frontend engineering at scale

How do you scale your codebase? We have more than 80 apps, 150 developers in 4 different countries and more than 700k LOC. With the codebase that big it’s vitally important to have shared patterns, principals and standards and it’s even more important to make sure everyone actually follow those standards. aLearn about the strategies and tools that Atlassian has developed to create and support a high-velocity, high-quality engineering environment, challenges and obstacles that we had to overcome and hoops that we had to jump through on the way.

(bright techno music) – So hi, like they said I’m Nadia.

I’ve been in Atlassian for two years and for the last year and a half I’ve been working on Jira. So Jira, as lots of folks know here is a tool calibration for teams. It’s very flexible, very configurable and very, very complicated.

And it’s used by millions of people everywhere. So today I just want to share with you a couple of lessons on what it’s like to work on a project on that scale. But first, what exactly is the scale I am talking about here? So it looks something like this. It’s just one project, one product, Jira, which had at least 200 contributors in the last two years in its front end repository only, from at least five different time zones, which is kinda cool.

So you may ask, what exactly is going on? What are all those people working on? And the answer is this. We are giving Jira a big

usability update. We are transforming this old, slightly dusty, but still well known interface into something like this.

Much more polished, much more fresh.

Basically what we are doing, we just completely rewriting from scratch everything front end related.

And the biggest challenge of this endeavour is Jira is very, very old. It was written in 2002

and since it’s 2018 right now, if you think about it, it’s 16 years. We now have the whole generation of developers who are actually younger than Jira (laughs). Yeah that’s slightly crazy and, because of this age, as you can imagine Jira is very, very old, insanely old. It’s so old that you probably can use it as a museum of history of web development.

I wouldn’t be surprised if we have every single front end part end of technology buried somewhere in the deep existential corner of Jira.

So when this idea of big UX rewrite came up, people saw this as an opportunity to just get rid of all this legacy. Of all the jQuery, all the backbone, and just start completely fresh, completely new. And they did.

(audience laughs) Yeah, we use only more than front end technology stack right now.

React, Redax, Webpack, Babel, you name it.

We use everything. We’re on the bleeping edge. So it was so successful and it grew up so fast that Jira new, fresh and shiny front end repository transformed in the last two years from this to something like this. One million lines of code. I’m not even joking here.

We crossed this number very recently.

40 thousand commit messages and, as I said, 200 contributors. So more than 200 people in the last two years committed something into Jira front end alone. So when I’m talking about scale, this is what I have in mind.

This was quite an exciting and interesting journey for us. And during this journey we learned a few interesting lessons, which brings me to the first one. Divide and conquer.

So consider this very typical Jira screen.

We can surely implement it as just a big react up. Well, no on stop us there, to create a big monolith. What can go wrong? In reality it will probably be something like this. The state will be huge. Views will be just unmanageable. Everything will be just so complicated.

It will be very, very difficult to reason about. What we can do instead is, we can implement just a navigation app that only manages navigation state. It deals with navigation concerns and renders navigation views.

That seems much more manageable and much, much more simple. Also we can implement boards app that deals only with board concerns and doesn’t even know about navigation. That sits somewhere on the left. Also sounds reasonable. That’s what we’re doing in Jira basically, right now. We’re converting everything into those apps. And your basic app is something like this.

We have views there, sometimes it has state, sometimes even optional side effects.

Nothing so special. It’s very, very typical react. What’s important is that all those apps, they are bounded through JessX interface and communicate with the outside world through props and callbacks only. So everything that’s inside is just complete black box and in a nutshell it’s just a very big, sometimes very complicated, but it’s still just a react component, from a consumer perspective. And since this is just a react component, nothing actually stops us from rendering those components and composing those components wherever we want. We can take this, each of you, create it as an app, and just render it into model dialogue.

That’s very, very simple to do.

Or we can just take this, each of you, and render it just exactly on the page.

That’s exactly what we’re doing and, if you look closely, you’ll see that this is exactly the same, each of your app. Everything is awesome, then.

So from the high level perspective, Jira’s front end repository, you would imagine structured something like this. All those tiny apps sitting neatly with each other. Similar shapes, similar boxes. Well reality, of course, slightly different. In reality we found ourselves in a situation that looks something like this. We have 50 different apps with 50 completely different architectures, which is not cool at all.

This makes all the apps incredibly hard to reason about. You get used to one app, the way it deals with stuff, and then you need to fix a bug in another app, and welcome to another marvellous universe. Everything is so different. It’s basically upside down.

You don’t even know how to start.

We can probably deal with that. We’re all smart people. But the more frustrating part of this is, we started reinventing solutions over and over again in all different apps.

And we got very bad at sharing knowledge and sharing code. And even if you invented the most brilliant solution in the world for structuring your redox reduces, you can’t even share it with the rest of the apps in Jira because everything is different.

So basically, instead of those tiny, equally shaped boxes Jira front end looked something more like this. Apples and pears, a whole basket of fruits and even with a chicken leg hiding somewhere in the corner. That situation had to be dealt with so about a year ago we had to introduce a programme called Tangerine to fix this fruit diversity situation. That’s a lovely insight slide for you.

World-class front end engineering with love from Jira Front End Platform Team.

The idea of this programme was to create a shared framework of patterns, practises, and technologies that can be used in every single app in Jira front end. And of course to make sure that everyone was happy with those practises and technologies and everyone used them in all the apps.

So, in a nutshell, what we actually wanted to do was transform this fruit diversity situation into something like this.

Getting rid of this chicken leg and turning all the fruits into citruses. We still have different shapes, different sizes, different flavours. They still serve different purposes, but at least now they have something in common.

So the programme was operational for a year now and in the process of integrating it we learned a few interesting lessons as well.

Which brings me to the second one.

Radically automate. Automate everything.

So we have an amazing programme.

We decided, on some incredible principle, it’s just the best thing in the world and we want to use it in every app in our one million lines of code. How exactly would we do that? If it’s just between you and your colleague that’s very simple. You can always talk to each other. You can always agree on something.

You can always hold each other accountable. When it’s different teams, different departments, sometimes different time zones, that’s much more complicated and what we, unfortunately, found out is that if it’s not automated, it basically doesn’t exist. Because of that, we developed something like an obsession with all forms of static analysis.

In Jira front end starting, the most important tool is Eslint.

Most people have probably heard of it. It’s a tool that forces code conventions in your javascript projects. Why is this so important? Well, for example, should it be typed with issue upper case, lower case? Should it be appended with type? Should it be type with upper case or lower case? Discussions about those most important things in the world can continue for hours and developers, all developers, they love their codes. They treat their codes as their babies.

And of course, every single developer has their own opinion on how their baby should look like. Well, not in Jira. With the help of Eslint we can just make a decision once on something like that and continue all this stuff.

So have a basis discussions, and just implement a rule, and just force it for the entire repository. We use all the standard configs, of course. AirBnB has done standard configs for each year, wherever. We use all of it. On top of that, we didn’t stop there. We implemented a bunch of our own custom Eslint controls. I think it’s more than 70 now.

The interesting thing about those is they force specific things to Jira, and also that most of them are alter-fixable and, because of that, it’s a very interesting experience to code in Jira front end now. You type something, the way you used to type. Then you press save and your code magically just transforms into something completely different. It’s like your code is a living, breathing creature that sits slightly outside of your control, which takes some time to get used to, but after a few times you start enjoying that and then, unfortunately, you cannot code any way else. So, Eslint is a very nice tool when you want to enforce something on a file level.

But it doesn’t help you when you want to enforce some rule on a whole project level. And we solved this by creating another tool. It’s also a static analysis tool. It’s open source. You can check it out right now. It’s very, very cool. We even have the author of this tool sitting right in this audience.

It’s a static analysis tool and it focuses on a project as an entity. As a whole.

It has access to all of your files, to all the information in those files, and to all the dependencies of those files. With the help of this tool, which is very, very flexible, we can write our own rules as well. And of course we did. We are very, very big on static analysis.

So first, and the most important, most noticeable rule of all is a rule that detects circular dependencies in your code. And all those circular dependencies, they are very nasty buggers. They turn your shiny,

beautiful code into big ball of mud in a matter of seconds. Unfortunately. Thankfully, to Sictor, not in Jira, not any more. With this rule we can detect all those nasty circular dependencies from something as simple as this to something as beautiful as this, which is a real dependency graph from one of the real apps in Jira front end before introduction of this rule. Just another example of another rule, just to illustrate how flexible the tool is and how synced we can be with it. Hence the name.

This is the config of a rule that can force a project structure of your app on a folder and file basis. So you can specify that you want to have specific folders there, specific files, and nothing other than those files. And the end result will look something like this.

Two very different apps, but if you look closer you will see that they are structured absolutely the same. They all have model. They all have services, rests, index, dodges, wherever.

This creates a very, very strong model of how your app works and how your app operates. And this enables developers to switch from one app to another very simply and in just a matter of seconds. So robots are awesome. We use them all the time,

but what about humans? Let’s talk about humans, and jump into the third lesson, and talk about ownership. (coughs) So I’m sure most of you know or have been in this situation. Some code sits somewhere in the corner just gathering dust and slowly falls apart. We’ve all been there.

In Jira with our high pace environment, this slowly falls apart turns into disarray rapidly. And this can become nasty really quickly.

We experienced a bit of this situation and, of course, we wanted to take it under control ASAP.

So we built a system around what we call Manifest. Manifest is basically an adjacent file that has all the information you need about who owns this file. How to contact them. What are their Jira projects. Stuff like that.

And of course we didn’t stop just with creating those manifest adjacents. We also integrated it into our build system. So if someone wants to commit something that doesn’t have an associated manifest adjacent, we will just fail your build.

No owner, no code. Plain and simple.

We also didn’t stop there. We took it a step further as well and we also built a bot that sits in our poll request. The bot’s named Gollum. That’s the best name ever for a bot, in my opinion. Gollum sits in your poll requests and it can detect all the changes that you’re doing if they are from an app that is not owned by you or your team.

And, if Gollum detects something horrible like this, it will just read the associated manifest adjacent, it will assign reviewers to this poll request, and everything will be under Gollum’s control. No changes will go unnoticed.

So that’s more or less it from me.

If you want to build a very, very big app, you would want to remember those lessons that we had.

Divide and conquer. Monoliths are not for scale.

Something like Jira, if you want to build something with more than one team, credit composition is the key. Woops, sorry. Automate everything.

If it’s not automated, it basically doesn’t exist. Let the robot do the boring work and focus humans on solving real, actual customer problems.

And also create ownership. This goes without saying.

If you have some code in your repository that is not owned or maintained by someone, you’re doing something wrong. Thank you.

(audience claps) (bright techno music)

Join the conversation!

Your email address will not be published. Required fields are marked *

No comment yet.