In my experience rewrites typically start with senior devs (or tech leads who are not really leads but rather senior devs with better pay). The rewrite starts when devs are able to force/guilt/persuade the manager to do it.
And also in my experience rewrites rarely succeed. There are multitude of reasons but the best way to put it is that devs don't usually know what they are getting into (they only have part of the picture) and they are out of stamina somewhere in the middle of the project. They also never learned what caused the previous project to fail (they have too limited view to understand it) and so they tend to repeat the same mistakes.
One project I joined had lost its entire development team. New devs came and demanded rewrite. The manager allowed it. The rewrite failed (of course). The cause: the internal customer was very intrusive and they demanded to get creative control over every part of the development process including approving code reviews, etc. The lack of expected progress on the features the customer demanded only got the situation worse and got them more arguments and in the end higher management decided to kill the rewrite.
Again -- devs had only partial understanding of what caused the fail of the previous project. They looked at badly written code and surmised the previous developers to be incompetent. The reality was those guys were competent but were completely demotivated by inability to get anything done with the internal customer and so did not care about quality one iota.
My solution to rewrites is avoid at any cost and to only do rewrites under exceptional circumstances when it is absolutely clear that refactoring is pointless.
So what do I do?
1. When setting on the project to improve your system/codebase, it is important to think about your ability to finish the project. This is going to be dependant on willingness of your various stakeholders to pour money (or see a slowdown in feature development). The best way is to get a credit of trust early on and the best way to get this is by showing some early results that the stakeholders care about especially if it is something they wanted for a long time but could not get.
2. No results will be worth anything if you don't get some visibility. Put up metrics for everything that can be reasonably measured and the customer cares about -- reliability, performance, turnaround time for defects/changes, etc.
3. Those early results can be anything but when I come into a project I am trying to find out what are the biggest issues and I try to locate one where it is possible to get substantial improvement quickly. This might be something like fixing unreliable behaviour, performance or getting done a particular feature that was asked for for a long time. It is important to select carefully -- you are working on an alien codebase with a new team. The worst that can happen is you promise a lot and deliver nothing.
4. Once you get a credit of trust, you spend it on improving development efficiency. Overall, this is one thing that is most important to get done early but at least early on is completely invisible to stakeholders -- and so you need to use up a bit of your credit.
5. Development efficiency is highly dependant on the project. Automated build? Faster build times? Automated end to end functional testing? Being able to set up your private development environment quickly? Getting rid of some stupid hoops you have to get to modify the app or get your piece of code through the process? Refactoring a couple things that are causing a lot of additional work for every change? The key is to look at the actual process and understand what really is driving inefficiency -- as tech lead I always pair program with developers to get understanding of what the situation really is like.
5.1 On one project I noticed developers spent a lot of time on internal requests form customer that were nothing else than changes in configuration. I wrote couple modules and small UI to let the user self-service themselves and suddenly eliminated about 1/5th of development effort (with about a week of effort on my part). I also spent some time with the team to talk about importance of self service and how it helps reduce unplanned work that interrupts their development.
5.2 Pair programming is ABSOLUTELY best way to get to know your team and the team to get to know you. You want some respect as tech lead? No better way than to actually stick with them and show you can do stuff. This is going to be very important for you later.
6. At this time you should be thinking about improving the basic improvement process -- at the very least get your team to understand what is wrong and right and have retrospectives with the team to figure out what the problems are and how to fix them. You don't want to bog your team with full agile, but you want to start building it from the ground up by introducing basic improvement loop, transparency, openness, etc.
7. By improving development efficiency you create additional development throughput which you then spend on more improvements, but now those improvements should start providing visible results to stakeholders. Faster turnaround time on changes, more reliable and predictable deployments, more reliable and faster system, etc. Here you want to be tracking how much resources you spend on internal improvements (code refactorings, development tooling, etc.) vs things that the customer cares. It is important that the customer is always satisified because this is what gives you freedom to do whatever changes you want to make.
And if anybody wants it, I am always happy to help with a problematic project:)
One critical point I forgot to include is that cognitive load of your team members should be treated as a precious resource. Whatever happens, you need to make sure you don't waste this resource on unneeded stuff -- cognitive load more than anything else will determine how quickly stuff can be changed.
Remember, if you introduce anything people will need to take time to learn, adjust and then understand. You can also count of experience at least temporary slowdown.
So don't waste time things that only marginally help with development. You definitely don't want to switch your project from Java to Kotlin if your goal is to get something done quickly! (Yeah, I have seen this happen in real time -- new guy came to a project and "listened" to devs and switched project from Java to Kotlin with predictable outcome that he was fired half a year later after disappointing progress on actual work).
And also in my experience rewrites rarely succeed. There are multitude of reasons but the best way to put it is that devs don't usually know what they are getting into (they only have part of the picture) and they are out of stamina somewhere in the middle of the project. They also never learned what caused the previous project to fail (they have too limited view to understand it) and so they tend to repeat the same mistakes.
One project I joined had lost its entire development team. New devs came and demanded rewrite. The manager allowed it. The rewrite failed (of course). The cause: the internal customer was very intrusive and they demanded to get creative control over every part of the development process including approving code reviews, etc. The lack of expected progress on the features the customer demanded only got the situation worse and got them more arguments and in the end higher management decided to kill the rewrite.
Again -- devs had only partial understanding of what caused the fail of the previous project. They looked at badly written code and surmised the previous developers to be incompetent. The reality was those guys were competent but were completely demotivated by inability to get anything done with the internal customer and so did not care about quality one iota.
My solution to rewrites is avoid at any cost and to only do rewrites under exceptional circumstances when it is absolutely clear that refactoring is pointless.
So what do I do?
1. When setting on the project to improve your system/codebase, it is important to think about your ability to finish the project. This is going to be dependant on willingness of your various stakeholders to pour money (or see a slowdown in feature development). The best way is to get a credit of trust early on and the best way to get this is by showing some early results that the stakeholders care about especially if it is something they wanted for a long time but could not get.
2. No results will be worth anything if you don't get some visibility. Put up metrics for everything that can be reasonably measured and the customer cares about -- reliability, performance, turnaround time for defects/changes, etc.
3. Those early results can be anything but when I come into a project I am trying to find out what are the biggest issues and I try to locate one where it is possible to get substantial improvement quickly. This might be something like fixing unreliable behaviour, performance or getting done a particular feature that was asked for for a long time. It is important to select carefully -- you are working on an alien codebase with a new team. The worst that can happen is you promise a lot and deliver nothing.
4. Once you get a credit of trust, you spend it on improving development efficiency. Overall, this is one thing that is most important to get done early but at least early on is completely invisible to stakeholders -- and so you need to use up a bit of your credit.
5. Development efficiency is highly dependant on the project. Automated build? Faster build times? Automated end to end functional testing? Being able to set up your private development environment quickly? Getting rid of some stupid hoops you have to get to modify the app or get your piece of code through the process? Refactoring a couple things that are causing a lot of additional work for every change? The key is to look at the actual process and understand what really is driving inefficiency -- as tech lead I always pair program with developers to get understanding of what the situation really is like.
5.1 On one project I noticed developers spent a lot of time on internal requests form customer that were nothing else than changes in configuration. I wrote couple modules and small UI to let the user self-service themselves and suddenly eliminated about 1/5th of development effort (with about a week of effort on my part). I also spent some time with the team to talk about importance of self service and how it helps reduce unplanned work that interrupts their development.
5.2 Pair programming is ABSOLUTELY best way to get to know your team and the team to get to know you. You want some respect as tech lead? No better way than to actually stick with them and show you can do stuff. This is going to be very important for you later.
6. At this time you should be thinking about improving the basic improvement process -- at the very least get your team to understand what is wrong and right and have retrospectives with the team to figure out what the problems are and how to fix them. You don't want to bog your team with full agile, but you want to start building it from the ground up by introducing basic improvement loop, transparency, openness, etc.
7. By improving development efficiency you create additional development throughput which you then spend on more improvements, but now those improvements should start providing visible results to stakeholders. Faster turnaround time on changes, more reliable and predictable deployments, more reliable and faster system, etc. Here you want to be tracking how much resources you spend on internal improvements (code refactorings, development tooling, etc.) vs things that the customer cares. It is important that the customer is always satisified because this is what gives you freedom to do whatever changes you want to make.
And if anybody wants it, I am always happy to help with a problematic project:)