First of all, do not write code. Try to avoid writing code at all. Write code only when it's absolutely essential. Especially for startups. This is necessary to stay fast. Every line of code written is a line code that will have to be tested, read ten times, released, refactored, fixed, and eventually deleted. If you have to write code then keep it simple. Prefer readability over concise or clever syntax. Don’t do premature optimization. Do not over-predict how the code will evolve and hence do not put in every code design pattern you know.
Once you have the code, you will have to refactor it. Refactor often and keep them small. Do not refactor a big feature or the entire code base. Do it in steps. Imagine an eventual shape of what the code should look like, then open small PRs that will convert the code to how it should be. This is true for medium to large companies. For very small companies, you can afford huge PRs and big changes to move and fail fast.
Be wary of rewrites. Rewrites are often triggered and proposed by people who are lazy to spend time understanding existing code. I have seen rewrites go wrong and eventually end up in a new messed-up form. Very often people underestimate what the code already does. There are many business use cases that are being handled in all the details that make the code difficult to follow. Which doesn’t need to be true always but sometimes it’s unavoidable. Heroic rewrites are very often a waste of time. As leaders, we need to discourage heroic rewrites, monstrous PRs, and radical technology choices. As engineers, we need to stop doing such acts. There are situations when those make sense. For example, your codebase is in COBOL and you want to move towards modern language because finding COBOL resources is getting harder. Even in that case, try to replace the existing system slowly. One feature at a time.
Rewrites are quite normal when a new senior guy comes in and he doesn’t want to spend time understanding the existing system. Also to show that they are “doing” something they propose to redo the entire thing and toss in a couple of microservices. After a couple of years, the situation is pretty much the same. This might not be true in the case when some old system was written by a trashy engineering team in which case it becomes near necessary to replace it. All I am saying is to give a benefit of doubt to the existing system and understand it completely before you think about a rewrite.
Do everything in iterations. Code in iterations. Ship in iterations. Refactor in iterations. Improve in iterations. Make small changes that add up over time. Use feature flags if necessary. This will have a drastic impact on the mental health of your team and yourself. Probably not so good for the ego of a new CTO.
As Naval Ravikant said, 10000 iterations, not 10000 hours.