Here's a story you will relate to if you're a software engineer choosing to build projects to get better at your craft. You see a new technology, you come up with a side project to build, read the docs and code away, fast forward a few hours or days, it's up and running on localhost in all its might, you ctrl+c, close your editor, and never look back. If you resonated with this, I've got some news for you. Unless the project was for pure tech exploration, and not making you a better engineer, you have missed out on some substantial benefits of coding after work hours.
In production, almost no software is written once, and run forever (even the mars rovers have gone through software upgrades!). If the goal is to write better code for the real world, why do we choose to write code in a sandboxed environment where all remains unchanged. I too, have made this mistake for the longest time.
During my first year of learning software engineering I managed to make multiple applications that were never deployed and never iterated upon, the one's I did deploy, were built all in one go, and then put on digital ocean, no CI no CD, straight code up on the cloud forever(ish). Writing code like this, I really began to wonder why everything felt like an overkill, why the architecture of the application didn't seem to matter, why programming against abstractions didn't feel right. Soon I realized these projects had lost their value in making me a better engineer because real world engineers do not work on make believe projects that will never have changes in requirements, never have new features, never go through refactoring.
My understanding of well written software is flexibility and simplicity. Writing code that does the job for now without paralyzing future decisions. How can one become better at their craft if they do not practice right? Swing a bat 1000 hours the wrong way and you have an inefficient swing by default. By programming spaghetti code that is rigid and inextensible for hours at a time I could see myself becoming the guy who can hack things together but never engineer them well, of course this way I would be carrying this habit into the companies I would work for. So I fixed this issue my changing my mindset.
What I figured to provide maximum value for me is treating work outside of work as legitimate work. My own mini startup for every project I want. What do I mean by a mini startup? I mean replicating what I have seen in professional settings: linting, testing, deployment pipelines, creating PR's instead of working straight on master, creating an MVP and incrementally adding features, and planning out my own little sprints and epics.
By incrementally adding features I force myself to defer actions and keeping my code simple for the time being, by enforcing testing I am making my codebase ready for refactoring and changes when (*"when" not if) I run into design hurdles that will require refactoring. I am now able to understand extensible yet simple code first hand, I am able to write code in a more consistent manner enforced with linting and formatting, well tested code means I am now free to make changes without fear of unexpected changes. These were benefits I was clearly missing out in my previous projects, and I have found substantially helpful when coding during my office hours as well. Hence making me (in my eyes) a better programmer than I was previously.
Every line of code we write reflects our mindset, especially when it is publicly available. Messy spaghetti code you wrote for a react application should not be the reflection but from a look at your GitHub that is exactly what it might seem like. That being said, I do have a few GitHub repositories I am absolutely ashamed of, I cannot for the life of me add more features without everything breaking apart.
I feel much better and confident about pushing repositories on GitHub fro people to see when I have implemented the above said practices because it reflects a better software engineer than what some of my older repositories do, had I not made the switch this change would be harder to see. If you guys happen to have suggestions that have worked well for you, drop them in the comments below :)
Summary:
- Treat personal projects as professionally as you can
- Implement practices for your codebase, e.g. linting and formatting
- Test because you will need to refactor as you go.
- Deploy early to simulate the real world.
- Release features in iteration, this forces your software to go through an evolutionary cycle without things feeling like an overkill. This forces you to write extensible code, or face the pain of project wide refactoring for every feature.