🇬🇧🇺🇸 The dev experience matters
As a technical person whose daily job is to build by either implementing new features or fixing some annoying bug, I have to dig through (my or others) code every day.
With small exceptions, mornings look the same: prepare a warm cup of tea, power on my laptop. Then after I open every application that I need (email, Slack, Spotify) I open my IDE and a terminal. Then I open ClickUp to pick up the next task, start the project locally, create new branches and start writing code.
At past companies, I have seen a terrible trend: the programming experience was abysmal and was very low on the priority list.
Resources used and shared between developers that shouldn't be shared, such as databases, projects that when needed to be re-configured, you'd have to ask your colleagues to pass you some configuration file, place it in the exact spot, copy resources through various channels (most commonly on slack), etc.
Just awful.
If your laptop ran into a problem and you'd have to do the whole development setup again, you'd already know you will not finish your task in time for the deadline.
You'd have to spend at least a full day searching for configurations, connecting to cloud services, trying to setup everything from scratch to have the project working again. But more than often, you'd forget a certain step, and there would be no warning. Only some weird error pops up after some expensive and slow script runs.
Each extra step a developer has to do to configure and start the project adds to the frustration, especially if these steps are not documented and they have to get the instructions by word of mouth from other colleagues.
I know because I have been there, frustrated and secretly wishing for a magical command that would just do all that mundane work for me, since all those steps could be easily automated.
When I became the CTO of Vuuh, I wanted to tackle this kind of problem right off the bat: allow my team to be as productive as possible and don't worry about installing anything. I wanted to achieve a work flow that would allow them to start their days with just one command, and the next second to be able to write the code they want.
At Vuuh, we employ a certain set of good practices that help us move fast without breaking stuff, and be as productive as we can be.
Continuous integration and deployment
We make heavy use of this methodology: for each piece of code, we automate the test suites so we catch any error before it reaches our live systems.
After we merge the code, we can jump right into the next task, because we automated all the next steps: a Gitlab pipeline runs afterwards to build and pack the project into a docker image, and then automatically deploy it to our staging environment.
This way, we don't have to spend time deploying anything manually and we can focus on writing code.
Use containers for everything
I am big fan of containers and Docker in particular because it makes the development experience very smooth.
With Docker, we are able to treat the local development as disposable. Working on the backend and doing some bad migration locally will not mess up your day. You just nuke the database and start with a fresh one from scratch, with a snapshot of the database configuration exactly the same as it is on the staging environment.
By packing all the services we use (caches, frontend services, backend services, databases) in individual Docker images and orchestrating them locally with docker-compose, we save a lot of development time. All the configurations required by our services are decoupled from the code itself ( following the 12-factor specification on configs ), allowing us to run locally exact copies of the staging or production environments when needed.
Internal tooling is a must
There are a lot of processes that need to run from time to time and there is no way around them. Developers need to start the projects every day, I need from time to time to update the development data snapshots to match the latest schema from our live services, tests need to be run with different commands depending on the language and the framework used, etc.
The commands for a certain action need to be remembered by each person that needs to perform it. Sometimes these commands need to change because we update our configurations, tooling, frameworks, etc. and then we have to communicate these changes to the rest of the team.
By building our own development tooling, we managed to abstract away all the moving parts of the development process and speed up all these repetitive processes.
By having a simple start-projects
command that bootstraps all the required steps for running the projects, we are always sure we run the same setup. By having the same development data management commands, I know that no matter what, people will not end up working on invalid data because when needed, they can just run it and receive perfectly valid and up to date data.
Many teams consider investing time in custom tooling a waste of time, but they could not be further from the truth. Even though the initial time investment is non-negligible, it will always pay off long-term. If you spend a few hours developing such a tool but manage to save your teammates 10 minutes of work and waiting every day, you just saved 42 (assuming there are ~262 working days per year) wasted hours per year per person.
But the real gains are much bigger, because more than often, by automatizing cumbersome tasks, you'll manage so save way more than 10 minutes per day per person, to not mention the improvement of morale (most software developers take pride in their work and draw their satisfaction from completing work that matters, not mundane repetitive work. Some would even get disrespected if you'd have them doing mundane work all the time. I know I would).
Up to date development data
When developing a complex system with a lot of configurable sub-systems, a massive challenge is data you use. For each sub-system, you have to create their configuration in such a way that it would work as you need. Having realistic looking data in your development environment will help you catch real-life bugs during development and will make you feel like you're actually working on a real application, not some "Lorem ipsum" filled wall of meaningless blocks.
At Vuuh, I made it a priority to have at all times real-looking data for our development environment.
This is especially useful when you work with complicated data pipelines and complex product data. Because of it, we manage to catch a lot of bugs before opening a merge request, spot the information that "doesn't look right" and don't waste time re-configuring every sub-system every time.
When we want, we load all the necessary configuration and data in our databases, and we are ready to go. It takes less than a few minutes to receive a massive set of real-looking data to mess around with.
Another advantage is that it allows everybody to explore our app without fear of breaking anything or bringing the system in an inconsistent state when making changes.
Conclusion
For any tech company, it is a good investment to put some work in some internal tools that saves a few minutes of work for everybody each day.
The most expensive resource are programmers' nerves, and you don't want to poke them. The job as a software engineer is hard enough as it is, and if you can invest a few hours and energy in making your teammates lives easier, it will pay big dividends down the line.
It is essential for a tech person in a leadership position to identify the areas where the most time is wasted or where the biggest friction appears for their teammates and improve on them, and allow them to work on the things that matter.