For people who regularly use Aircall, you might have noticed we recently released a brand-new version of our dashboard.
We’ve faced obstacles and surprises along the way, but it’s safe to say that we’ve learned a lot on this journey. Working on a similar project? We hope our insights and processes can help.
Keep reading to learn more about our team’s specific mission and how we approached rewriting our dashboard from scratch.
A year and a half ago, my team and I were hired for a specific mission: Rewrite our dashboard from scratch.
You may be wondering: “What was wrong with the former dashboard?”
The dashboard was known to be particularly slow, especially for big companies. Also, it hadn’t evolved much from its origins, as every new feature request was either automatically declined or estimated to take a ridiculous amount of time, which was really problematic for the business.
From a technical standpoint, there were two reasons for these issues:
- No clear ownership or knowledge of the project: People who had worked on the project and had a real knowledge of it had left the company
- The project was built with old technology (Angular 1) that nobody knew anything about (and we weren’t able to hire anyone to work on it)
To fix these problems, we decided to rewrite it using a more modern tech stack, opting for React and TypeScript.
What We Learned
1. Don’t dive headfirst into the code
It might seem obvious, but starting a new project can be so exciting that it can sometimes lead us to put the cart before the horse.
Since most of us were new to the company and didn’t know anything about the product, we had to take a step back and play with the existing dashboard as much as possible to make sure we understood every feature from a business point of view.
Because a good developer is mostly someone who understands the business—not only someone who is technically skilled.
We also knew it was crucial to familiarize ourselves with the original tech stack (especially the backend) since that’s what we’re most dependent on.
In our case, the API wasn’t well-documented. As a result, we spent a lot of time reverse-engineering the existing dashboard to document all the endpoints.
While we worked on that, we noticed some technical limitations that made us rethink the specs and designs we planned for specific features.
2. Don’t repeat past mistakes
Speaking of technical limitations, we also discovered that some dirty workarounds were implemented to compensate on the frontend side.
For example, in the old dashboard, we were able to search for a number, a user, or a team. The thing is, we didn’t have any endpoint allowing the search function on the backend. The searches were actually performed on the frontend by loading all the customer data after the login.
At first, it was fine because Aircall was mostly working with small businesses. As we scaled, the dashboard started lagging (sometimes taking minutes to load).
So instead of re-implementing this workaround, we worked closely with the backend teams to put proper endpoints in place. It delayed the project a bit, but we wanted to ensure we were setting the team up with a more scalable and future-proof foundation.
3. Don’t fall into the “trendy third-party library” trap
When we start a new project, it’s pretty tempting to experiment with new technologies or libraries, especially when they’re trendy.
Also, no matter how trendy a library might be, it might not fit your needs. One mistake to avoid? Bending your code to accommodate a library (it should always work the other way around).
In our case, we invested in xState, thinking it would make our code more robust. We developed a whole ecosystem around it to integrate it as smoothly as possible in our code.
However, after testing it for a few months, it wasn’t the right fit for us. From there, we had to refactor a lot of our code just to get rid of it.
If we had stuck with the standard libraries, we could’ve avoided this issue.
4. Focus on one feature at a time and deliver progressively
As we were rewriting the dashboard, we decided to deliver everything at once. We thought it’d be easier than trying to deliver features progressively. This was certainly one of our biggest mistakes.
The first problem? Instead of having multiple milestones throughout the project, we had only one big one at the end.
As a result, we started working on a lot of features and still hadn’t finished anything—even after several months of development.
When it comes to team motivation, this obviously wasn’t a great experience. Beyond that, we weren’t able to do any user testing, so we weren’t sure if what we were working on was even succeeding.
So our top takeaway here is to always try to find a way to deliver your features progressively.
On our side, we embedded the old dashboard in the new one as a fallback for every page that wasn’t rewritten yet. Since then, we’ve progressively been able to replace the embedded pages with rewritten ones.
5. Anticipate the future
As exciting as it is to rewrite an app from scratch, once you’ve done it, you don’t want to do it again anytime soon. To make sure of that, you need to take a few precautions.
For us, we knew that we would move from a REST API to a GraphQL API at some point. When we started the rewrite though, the GraphQL API was far from being ready, so we had to work with the REST API.
The thing is, we knew that the migration wouldn’t be trivial. As a result, we made it as easy as possible by implementing Apollo client (with apollo-link-rest) from the beginning.
Also, as modern and shiny as your new app might be, someone will have to rewrite it again at some point. That’s why it’s key to make it easier for your successor.
For example, you can try to mitigate the internal dependencies between all the different parts of your code. This way, it will be easier to remove any piece of code to replace it with something else.
Also, consider having the important code elements centralized and easily interceptable (like authentication, navigation, HTTP calls, loading states, etc.). This will allow you to easily drive your app from the outside or embed it in another app without too much effort.
Can we say that we’ve succeeded in rewriting the dashboard from scratch?
An easy answer would be “yes”. It’s been rolled out for 100% of our customers and provides the exact same features while increasing overall performance.
Truthfully, we can only assess this by measuring customer satisfaction, how happy developers are when they’re working on this project, how easy it is to develop a new feature, and how long this new dashboard will last before being rewritten again.