While working at a startup, one may face the desire to completely rewrite its code. Such a situation may occur in the projects that have already released an MVP and received investments. They have successfully operated on the market for some time, and have clients or active users. Having overcome the major challenges, the team is likely to consider rewriting the application from scratch.
We also have the experience in completely refactoring our startup project. In this article, we are going to tell you how we did it, what results we achieved, what challenges we faced and what conclusions we made. You will also learn about the peculiarities of startup workflow, and how to avoid having to rewrite your code.
Rewriting a startup
Why does the team want to rewrite the code of the project? In order to understand this, let’s think about what makes a startup distinct from any other type of business.
The key peculiarities of a startup
- Exploration of new market
Exploring a new market is an ambitious project. Generally, they want to improve or automate some particular area of the business, to solve a challenge nobody has tackled before.
- Rapid development from scratch
The product is developed from scratch. Although there is no legacy code, the tight deadlines make the team work in a chaotic way, and add new features without paying proper attention to structuring and documenting the code.
- Limited budget
In addition to the limited time resources, startups have a limited budget. Generally, their money comes from the investments they have attracted or the funds of founders and cofounders.
The challenges of a startup
The startup operates in a new market with rapidly changing demands, and to challenge the competition, the product should meet them. Clients and investors request new features, competitors release them, and in order to stay competitive, the startup has to demonstrate progress. Since it is impossible to foresee the trends of tomorrow, it is difficult to create and follow a good strategy. Lack of planning and frequently changing requirements blur the final goal, and can lead to creating a completely different product.
In addition to limited time, startups usually do not have enough money to implement technical features in an optimal way, to buy the best hardware, or to hire the best developers. The team may have to design fast and clumsy solutions that are likely to cause further difficulties with maintenance and scaling of the application. Yet, these quick solutions work, and sometimes they are the only way for the startups to keep up with the market.
As it was mentioned above, startups are exploring a new market and dealing with new problems. They are likely to encounter technical issues nobody has faced before, and they need to solve them in a timely manner. Meanwhile, since the challenge is unexplored, it may be unclear whether the issue can be solved at the present stage.
All the aforementioned points lead to challenges in the organization of the workflow. Tight deadlines in combination with unstructured requirements add chaos to the working process and lead quickly to the inaccurate development of new features. These factors cause difficulties in the further development and maintenance of the application.
The common problems with a startup’s codebase
- Lack of documentation
Work on a startup project is handled under tight deadlines. Sometimes this way of organizing the workflow leaves no time for proper code documentation. This is likely to cause difficulties with further maintenance of the application: the developers will have to spend more time understanding the ideas of the authors.
- Technical debt
Since funds and time are limited, the team may have to reduce some of their expenses: to buy cheaper servers, to implement features in a quicker and less optimal way, etc. These factors and poor documentation cause technical debt – the amount of necessary work that was postponed. Unless the debt is repaid in the near future, the maintenance and further development of the product will be more difficult and time-consuming.
- Lack of logic
The startup team has to deal with a rapidly changing market and constantly add new features to the application. Not all of them fit into the initial architecture, and this leads to seeking alternative solutions that may be not optimal. Duct tape solutions and poor documentation make the code look illogical in the eyes of the new developers working on the project.
Why rewrite a startup?
Having considered the key features and challenges of a startup, we can summarize why developers may want to rewrite a startup. The most common reasons for this are as follows:
- to improve the quality and readability of the code
- to simplify the further maintenance of the application
- to improve the architecture
- to substitute the duct tape solutions with elegant ones
Our experience of completely rewriting our software
While working on one of our startup projects, we faced the necessity of making the significant changes in its codebase. Having discussed the situation with our client, we agreed to rewrite the code from scratch and started the process.
The reasons for rewriting
- Change of business logic
Having seen a positive reaction from users, our client decided to keep on developing the product as a more universal platform. However, the architecture was not designed to function in this way, and was not able to handle these types of tasks.
- Out-of-date architecture
In order to maintain the interest of the users, the team had to keep on developing the product by adding new features. Not all of them were possible to implement in the current architecture. In addition, the current architecture was likely to cause difficulties with further maintenance and scaling of the application.
- Technical debt
Due to the limited time and budget, some of the solutions were not reliable enough to handle further tasks. In addition, the technical debt prevented the team from the efficient maintenance of the existing product and developing new features. To make a long story short, it had to be repaid in the nearest future.
- Better solutions
Since the product was dealing with a new market, the team has faced the new technical challenges. The solutions that we found were viable, yet they were not perfect. In the process of working, we expanded our knowledge and invented more elegant and efficient ways to solve those challenges and repay the technical debt.
Defining the stack of tasks
Before starting the actual work, we outlined the scope of the work we are to perform. This helped us to organize the working process in a more efficient way that had positive impact on the quality of the end product. Our major tasks were:
- To integrate the new business logic of the application in its architecture
- To unite the structure of the project in order to create a general system and not to spend time on finding a way to introduce each minor change
- To split the monolithic application into the back-end and front-end parts for the developers to work independently
- To remove the gems and libraries that did not fit the new architecture in order to make the code clean and to improve the performance of the product
Having defined the exact tasks, we started the work. We completely rewrote the front-end part of the application on Vue.js instead of jQuery.
We also changed our approach to the backend structure and started using callable objects. In addition to that, we decided to fully use the namespaces in Rails. This helped us to structure the controllers and services, and to unite the application into an integrated system.
Some of the libraries and gems we used did not fully fit into the app’s architecture, thus affecting its performance. We decided to cease using these elements and to write our own solutions instead. This turned out to be simpler and more efficient than trying to fit the already created packages into the architecture.
However, we added two new libraries: Dry Validation and Sorcery for validation and authentication. We also introduced ElasticSearch for handling complex search queries.
Having started the work on refactoring, we decided to move our repositories from Github to Gitlab. The latter provides a more convenient process of pipeline settings and gives the possibility of automatic project construction, testing and deployment on the server. We also use Gitlab task tracking for managing the project.
What were the results?
Our work resulted in improving the architecture and the quality of the code. It became more readable, logical and structured.
The work of the app became faster, it was able to support the features requested by our client and to handle more load. The improved codebase has simplified the application’s maintenance and implementation of new features.
The challenges we faced
Although the rewrite had a positive impact on the application’s performance, we faced several challenges while working on it. In particular, we had difficulties introducing the new technologies and compiling them with the architecture.
While designing the complicated system, we faced a situation where some of the sub-systems were not documented initially. When it came to their implementation, the developers had different visions of the features and their realization.
Additionally, there were challenges with integrating the features designed for specific customers in the new architecture. While doing this, one should pay close attention to planning the workflow and documenting the code. Otherwise, the changing market and new requirements will lead to chaotic development, and the team will face the same old problems.
The conclusions we made
Not all startups can survive a period of rewriting their existing code. The market changes rapidly, competitors create new products and add new features thus attracting users. We have succeeded, and the new version of our project helps us to develop it faster and more efficiently. We had the possibility of completing the same tasks a second time, and we managed to create better solutions. We currently deal with more elegant code.
Yet, it would be wiser to avoid rewriting by paying attention to the organization of workflow. If you are a part of a startup, it is impossible to predict anything. That is why risk management is a key point of a successful startup. The strategy, plans and deadlines should be flexible, they should take into account the possible challenges and delays.
What should you know before rewriting a startup
A software rewrite is a risky decision. Before making it, the startup team should consider the possible pros and cons and think of alternative solutions.
One of the main factors defining whether it is worth rewriting a startup is the stage of its development.
The startup lifecycle
A brief outline of the concept in order to define the viability of an idea. The prototype should just represent the idea in a comprehensive way – the accuracy and elegance of the code do not actually matter at this stage.
Creating a usable product in order to attract the first users and investment. At this stage, development from scratch is a must. While the prototype is just to outline the idea, the MVP should implement it in the best way – otherwise, the project will not be interesting for potential users.
Development and maintenance of the fully-featured product aimed at attracting users and generating return on investment. It is still possible to start the development from scratch – in case of the recent release of the MVP.
If a fully-featured product operates on the market for quite a long time and has a large amount of users, completely rewriting it is likely to be a bad idea. First of all, the team will surely experience technical difficulties with the transition of user data to a different platform. Secondly, the user audience is unlikely to stay loyal to a product that does not demonstrate visible progress. Therefore, we recommend considering other ways of code refactoring.
Rewrite or refactor the code – what to choose?
We all know that developers do not like working with legacy code, and this is what refactoring is. They like writing their own code, implementing new features from scratch. Yet, in the majority of cases refactoring is a better idea.
Refactoring is what your project needs
If your project has gathered a big technical debt, its code looks messy, and there are plenty of duct tape solutions, a rewrite is not a cure-all solution.
All the aforementioned problems indicate organizational issues. There are problems with strategy, and they cannot be solved by rewriting everything from scratch. If the team just starts writing the new clean code, they are likely to encounter the same difficulties in the future: illogical development and tight deadlines will make them apply duct-tape solutions, neglect the documentation, etc.
In this case, the best way out is to refactor the major parts of the application and to dedicate more effort to optimizing the working process.
It is time to rewrite everything
Generally, the rewrite is an optimal solution for an old project with outdated legacy code. It gives the team the opportunity to fully change the technological stack and to apply the best practices of development.
Rewriting from scratch is the best option if the business logic of the application has changed significantly, and the old architecture is no longer capable of handling its work. This was exactly our situation – that is why we preferred a rewrite to refactoring.
How to avoid rewriting a problematic startup?
As we have already mentioned, the main problem of startup projects is lack of strategic approach, and this cannot be solved by a new codebase. The changes should concern the deep aspects of development instead of solving the immediate problems. The following things will improve the quality of your work.
- Maintaining the good quality of the code
Introducing some routine practices will prevent the further rapid growth of technical debt, reduce the number of duct-tape solutions and make the working process more convenient.
- Documenting the code
Paying attention to the documentation will improve the understanding of how the product works and simplify further maintenance.
- Depreciation charges
Both hardware and software will become outdated one of these days. You should be ready for the necessity of substituting the hardware or changing some parts of your code.
What can we do right now?
The best time to start paying more attention to the quality of the code is now. The following things will become your first steps to optimization:
- Inspecting your code with RubyCritic
It is a gem designed to control the quality of your code. It will define the weak points of the codebase for you to refactor them right now or to make a to-do note for the future.
- Holding a review session
In order to simplify the work of developers, you can hold a meeting in order to discuss the workflow and to define what exactly is wrong with your current processes, why the technical debt keeps growing and how you can fix it.
- Test coverage
Covering the code with autotests will detect bugs at an early stage. To find out more about software testing, feel free to consult our recent article.
The rewrite of an application does not guarantee future success and an increasing number of users. Moreover, if you do not pay enough attention to the optimization of the development process, the project is likely to face the same difficulties again: technical debt, duct-tape solutions and chaotic development.
Before making the decision to rewrite the startup from scratch, you should remember that a successful project does not consist of singular solutions of complicated tasks. The project’s success is measured by the team’s performance in everyday routine work.