I learned a few lessons while being a CTO at Datananas (the SaaS startup I founded in 2014) during 7 years, some of them the hard way by doing mistakes. Here's a summary of what I learned
1. Less is more
The Occam razor's law of software development is that the simplest implementations are always the more robust ones. It's always tempting to build complex systems, but it is less maintainable. Developers love to try new tools and implement complicated architectures.
As a CTO you must fight against complexity. Each library or tool you add is something more that your team needs to master. Each line of code added is a line that might create new bugs, and fewer code means fewer bugs.
Also, don't write abstract code because you might need it elsewhere later. Write only what you need, and because you probably can't predict all cases yet.
Monorepositories saves you a lot of time. This can add a bit of complexity in your CI/CD but is definitely worth it for many reasons :
- You have all you code in one place, and can incorporate your changes in only one Pull request (back, front, app, ...)
- It's easier to share code and maintain compatibility
- You can test your entire codebase together
Even Google does it, and for good reasons, but I will develop them in another article.
3. Redoing from scratch
At one point it will be very tempting to throw everything away and start again. Don't forget that if it took 6 months to code, it will take at least 6 months to do it again, and probably more if you want to do it better.
Most problems can be fixed so you should take this decision very seriously.
4. Quality control
Here are some things you need to implement to ensure a high level of qualify control.
- Block your
masterbranches so no one can push to them
- Implement a strict code linter to keep code style consistent and without errors
- Implement code coverage
- Block merging Pull Requests without reviews, that have linter errors or are lowering the coverage
- Keep a Changelog: you should be able to easily know which changes were in production at any time
- Code is documented
Everytime you can automate a verification you should do it (in your CI/CD pipeline for example)
5. Peer reviews
Every change in the code should be reviewed.
As a CTO, you should review ALL Pull Requests until you have too many developers. Then you can think of delegating some reviews to lead developers because you simply don't have time to handle them all. Before that, this should be a top priority for you.
6. No spec no code
No code should be written without planning. All developers should spend some time writing technical specifications of the implementation they plan to do.
You need to review and validate this with them. If it's a big project, you need to split it in parts and you will review these along the way. You don't want your developers to spend a month on a shitty implementation.
7. Hire less
More developers does not mean faster development because hiring developers adds complexity. I'd rather have 1 very good developer in my team, than 4 average developers.
Be very cautious with hiring interns or junior developers.
8. How to interview
As a startup CTO, you could spend you whole time in interviews as it can be very time-consuming. You need to build a process that will allow you not to spend hours with all candidates but quickly
What I often did is asking technical questions in Joel Spolsky's style to know very quickly the level of the candidate. If you know the candidate does not meet your requirements, end the interview even if is after 10 minutes by explaining the reason and giving advice on where to improve.
9. Care about your team's working conditions
Developers need quiet working conditions. No one should be allowed to interrupt developers. If you need something use Slack. It is proven that when interrupted, developers need at least 15 minutes to get back in the zone. Give them all a free Spotify account. For 10$/month that is a very good investment.
If it is not possible, you should allow remote work. I was a bit reticent at first, but if you have good developers and you review their work it will be fine. And if you are not as hot and well funded as other startups, this can be a serious advantage for hiring good developers.
If you built a MVP, maybe you did not write tests for it, and this is a good thing, because you don't want to spend time writing tests on a software that has not reach product-market fit yet, and will maybe be thrown away. And writting tests takes at least 2 times longer to implement a feature
However, you should compensate not having automatic tests, by having a manual tester. You should have a tester in your team sooner than you think. Don't underestimate the power of manual testing.
As your product grow, you will need to write tests, because testers cannot retest everything all the time. This will also help you make sure you don't break the core features of your software. Each time you solve a bug you should add a test.
The holy grail is having end-to-end tests with real data for you whole software, but it takes a lot of time to implement. In the meantime, test big changes manually with a written list of features to check.
I would say roughtly :
- MVP / pre-revenue : test everything manually
- Once you have revenue, write unit tests and keep testing manually
- Over 15k MRR, it's worth spending time on E2E tests
11. Always keep priorities in order
Priorities should always be :
- Fixing bugs
- Reviewing code
- Writing new code
You will notice that the most important thing are also the less fun to do.
A lot of teams start with writing new code, then review other's code and fix bugs when there is nothing else to do (and there is always new features to write in startups).
It is very important to communicate if the rest of the company They must know what is being developed, and when things are released. I kept a changelog, and published it to Slack everytime something is going to production.