With this article, we want to shed some light on the Wrike technical stack: how it was before and how we see it in the future. We will tell you why five years ago we chose Dart as the main language for the frontend development of our product and why now we decided to look towards other languages and frameworks.
What is Wrike?
To fully understand our technical solutions, it is necessary to explain what Wrike is as a product. Wrike is a large SaaS platform for project management and team collaboration. When we say “large”, we mean not only the number of features of the product itself (which you can read about here), but also the codebase. Over the years of its development, while the product has grown and evolved, we have come a long way from:
The technical stack and development team have evolved just as rapidly.
If you try to tell “on your fingers” what Wrike is, then it is worth noting that in the world of project management there are quite a few must have features, without which it is difficult to imagine a full-fledged product on this market:
This illustrates well the complexity and complexity of the Wrike UI, which imposes additional responsibilities on the engineering team in terms of performance requirements, development speed, and support costs.
A brief history of the tech stack
Wrike appeared in 2006, but we won’t dig that far. Raik’s history of frontend development of the “new time” can be roughly divided into several stages, considering the last six years.
JS + EXT
At that time (2013-2014), we had already written a fairly impressive amount of code in pure JS, which then had no alternatives. As the main engine (or framework, if you like), we used Ext.js third version. Despite the current archaism, you will be surprised, but he is still alive and well! At that time, it had quite a lot of breakthrough opportunities, which then, after years, transformed into what we are used to now. For example, data stores, with some stretch, can be considered a herald of the stores we are used to in React.
great opportunities “from the box“
good work with large amounts of code (assembly, minification, etc.)
DART. Why not TypeScript?
2014-2015 were difficult years in terms of making engineering decisions. We were faced with a choice: to use TypeScript, which had just come out to the stable version at that time, or to take Dart, which was more “Mature”but less common. You can read more details here…
The key points in our choice were:
Capabilities “from the box”… Sometimes third-party libraries can be very useful and sometimes harmful. One of the problems of the modern web world, and TypeScript does not solve it, is the abundance of libraries that can help speed up development, but which still need to be selected, maintained and updated from time to time. Jokes about node_modules already entered history… At the same time, Dart has a fairly rich built-in library, core libraries are updated and maintained by themselves Google
Aggressive Tree-Shaking. Since Wrike has a huge set of features that ultimately turn into a large amount of code, the language should have helped us not to download a large amount of code to the client (see. Minification is not enough, you need tree shaking by Seth Laddand also github).
These and some other features convinced us to opt for Dart. And looking back at the nearly six-year history of Dart and Wrike, we can see that the choice was right. Of course, we’ve come a long way from Dart 1.x with its dynamic typing and Polymer integration to AngularDart and Dart 2.x. Dart has helped us grow the product from an engineering and business point of view year after year, promoting the company and product to the market leaders of Work Management Platforms (Gartner and Forrester ratings).
Now we have already written 2.5 million lines of code in Dart, and the codebase consists of 365 repositories. We have created a large number of solutions for building and validating Dart code: for example, Dart Code Metrics… Without exaggeration, we note that Wrike is one of the largest consumers of Dart outside of Google, as far as its web hypostasis is concerned (the appearance of Flutter contributed to the explosive growth of Dart’s popularity, but still mostly in the world of mobile development).
However, the reality is that the language itself cannot provide all the necessary tools to build a large web application. The ecosystem is just as important, if not more important. Build systems, syntax highlighting, internationalization, frameworks for View – without this it is impossible to imagine modern development.
We would not want to completely retell documentationso let’s focus on the most important part – frameworks. Despite the fact that in theory, Dart allows you to work with all web frameworks through JS interop, in fact, the choice is not very large:
OverReact – wrapper over React by Workiva.
Flutter for Web – a popular cross-platform framework written in Dart, recently web support has been released in stable versions…
AngularDart – de facto standard for developing web applications on Dart.
Other solutions are possible, but inconvenient or difficult to implement. Thus, when choosing Dart for web development, you have to take one of these three frameworks or write something of your own.
Top reasons for our departure from Dart development
In the previous part, we gave a brief overview of the current state of the Dart language ecosystem, touching mainly on its frontend part. The time has come to approach one of the key problems, which at the time of this writing, unfortunately, has not been resolved: with all the will, it is impossible to choose a technical solution “for centuries.” The world of frontend development is constantly moving forward, developing, sometimes even faster than we would like. Web browsers are also evolving, adding more and more features and expanding API… Web frameworks, which, it would seem, by definition, are created in order to abstract from the underlying layers, too, are forced to react to this.
In addition to this, there are also “fashionable” trends, even in the very chaotic world of the frontend. Some time ago it was progressive rendering (React Fiber, Angular ivy). Now there is a tendency in the form of rejection of global state managers, for example, you can consider Effector… GraphQL, Server Side Rendering – you can find quite a lot of things that must be are supported in a modern web framework.
It becomes obvious that for a SaaS product that moves forward at the speed of a supersonic fighter, vitalso that the technical basis, the foundation of which it is composed, develops just as quickly.
And there are two constituent elements in this foundation:
The code your engineers write.
Code your engineers DO NOT write.
Modern development (especially on the front-end) is generously flavored with the use of third-party libraries and tools. Why, now you can launch a product on the market without writing a single line of code at all (the so-called no-code approach)! However, the code that you did not write is, on the one hand, the time that you saved, and on the other, the risk that you take on.
Development of a large product is always a difficult balance between writing your own solutions / reusing ready-made ones / interacting with developers of third-party frameworks. And the language and framework used, as one of the most extensive and pervasive parts of development, become its most vulnerable spot. In the old days, when products were distributed on disk and the concept of Continuous Delivery had not yet appeared, changing the language or framework could be critically expensive. Now, especially with the emergence of the concept micro frontends, this should not only not be a tragedy, but, on the contrary, serves as a healthy mechanism of evolutionary development.
With all of the above, we have to admit that we have come to the point where we have to revise our current tech stack as not meeting our requirements. Despite the fact that the Dart language and its ecosystem are moving forward (including thanks to the explosive growth in popularity of Flutter), and the Dart language is getting better and better (for example, with null safety) one ingredient is still missing – web framework… Yes, the language itself already has primitives that allow you to work with the DOM directly, but such development may be suitable for individual developers, and not for large teams.
By “lack of a web framework” we mean that none of the existing solutions for the Dart language has the four qualities necessary for a modern web framework:
Feature richness. Providing work with all (or most) of the possibilities that the modern web provides.
Development and addition of new features.
If we take a closer look at the existing frameworks for the Dart language, we will see that:
The de facto standard for web applications. It met almost all the requirements, but, unfortunately, the Google team shifted the priority of its development towards Flutter. This follows not only from twitter Tim Sneath (Dart & Flutter Manager):
But also from the more formal sources… You can also read the thread at Github… Yes, AngularDart is still in place, alive, and usable. But it lacks one of the key elements: “Development and addition of new features“.
Ported version of React for Dart. Unfortunately, the support of the community is not very large, and the project itself is developed mainly by Workiva.
Flutter for Web
It is on this framework that Google engineers are betting. And it is really moving forward at an explosive pace! But what is suitable for small companies or when porting a mobile application to the web, unfortunately, is not suitable for our tasks.
At the moment there are several Flutter Web related blockers for us. The main one is that it is impossible to embed a Flutter application inside the current web application. After all, unfortunately, Flutter cannot be wrapped in a web component. This greatly interferes with the concept of micro-frontend, the main idea of which is that we divide all the functionality into independent applications. These applications are deployed and developed by different teams and are loosely coupled with each other. If you want to know more, there is corresponding bug… The solution would be to wrap micro-frontends in an iframe, but this is fraught with a number of technical difficulties.
An important aspect is also related to the speed of the application: it is not yet entirely clear how Flutter will be able to cope, for example, with a table view. We’ll do this research when it becomes possible to embed a Flutter application inside another.
Thus, despite our love for Dart and the years that we have passed together, we decided to move towards changing our technical stack, since the main task of the company is to ensure the possibility of developing an application in 2 years and beyond, and with AngularDart we objectively we cannot guarantee this.
It’s important to note that we’re not saying goodbye: Dart will continue to be a big part of our development. But for new projects, we will now consider other possibilities. What kind?
And, to preserve the intrigue, exactly according to the canons of all serials, this is where we put an ellipsis. What will be our new stack, from what and how we chose, you will learn from the second part of this article. Subscribe to our social networks and follow the news!