Ask HN: How to finish last 30% of a side project?
I'm building a small project for myself, a web page editor. There's a frontend framework, an editor, and a backend. The first few months of the project went great and I was a blitz of productivity. Now there's only a few features left I want to build, yet writing the tests for these and going back and forth on different decisions has killed all productivity and drive within me.
I have tests but changing existing behaviors feels exhausting. Even a small refactor, even with good tests in place, feels exhausting and I just don't want to pick this up anymore.
Part of it feels like I've tried to do too much at once instead of building piece by piece, but even building piece by piece doesn't work because at some point you realize a new feature requires you to revisit the architecture of a prior decision, and that just puts me off from ever picking it up again.
I'm tired, I'm exhausted, I want to finish, but this is a recurring problem for every project I start. It just feels like I'm unable to ever find a way to wrap things up and I'm always working in a spiraling circle instead of the meme about drawing a wolf with some circles, add some details, etc.
Is there a book or article one recommends? It feels like I never learned how to code properly, even though I've been coding professionally over 10 years.
An open Ask HN community consultation from 2024 where @HowToFinishP convened hundreds of developers and bootstrappers to share real experiences, hard numbers, and tactics.
Hundreds of active indie hackers contributed case studies, pricing heuristics, and pitfalls to avoid when moonlighting on side projects.
The articles that are most relevant are probably ones from YC itself, along with ancillary material on startup woes, pitfalls, etc. Among the advice is how to validate ideas, is how to maintain momentum, knowing when to ship, when to wringing your hands and stop adding features, etc. Obviously geared towards startups and businesses but also applicable to projects.
The pieces of advice that I try and follow (and often fail at following) are:
* Commit to completing projects, not time. I'm bad at estimating time and putting time limits stresses me out. I prefer to work towards a goal rather than a time limit.
* Be vicious about removing features that are superfluous to the main project in order for it to ship. "Nice to have" features can be added later. A mediocre project that ships and can be improved later is better than a perfect project that never ships.
* Get some space. Getting a little burnt out is easy to do and almost inevitable. Even taking a day or week away sometimes recharges my batteries. The hopelessness I feel about the amount of effort required to complete seems less daunting once I've recharged. This is even better if it ships because the daunting extra "nice to have" features, refactoring or complete architecture overhaul seem less daunting when I'm rested and recharged.
* Don't get into "all or nothing" elements. Break up large projects into smaller manageable pieces as much as possible. Insofar as is possible, have smaller "shippable" elements that contribute to the larger project so that progress is apparent and, in the tragic event that the big project doesn't ship, there are smaller gains that have been done in its wake. Large projects also tend to shift during development so having smaller "wins" helps both with morale and provides tools to help shift course more easily.
* Don't be daunted by work. Rewriting parts of the architecture or even the whole thing might seem depressing but its a lot easier the second time around as the first attempt is exploring the ideas. A project with a clear specification is a lot easier to write than one where the specification is being written through trial and error. Elements of the project can also be used to accelerate the re-architecture/rewrite. Pixar famously scrapped many of their movies because they didn't work, only to rewrite it to be much better but they were able to re-use a lot of work and get back to the same point much faster the second time around. If what's had can be shipped, ship it, but in the case that it does need a rewrite, this often seems much more daunting than it is.
* Isolate complexity. Sometimes architectural elements need to be ugly for a variety of reasons (lack of knowledge about the domain, experimentation, exploration, effeciency, etc.). Beatiful code and proper abstraction is its own form of optimization and one should not prematurely optimize. Instead, give up the idea of writing beautiful code and let the code be ugly. The interface must be clean (or API, or resulting data) so that it can compose with the rest of the system and so that the ugliness doesn't infect other parts of the archicture, but the element itself need not be pretty.
* Make 'todo' lists. A minor hack but one that helps me a lot. There are different todo lists for different scopes. One big todo list for long reaching broad and underspecified goals ("epics" in agile language?) and smaller todo lists for day-to-day elements (fixing bugs, making functions, developing UI elements, etc.). The day-to-day todo also helps with morale as tangible progress can be seen as the items on the list get crossed off each day (I think PG is the original person I heard this from).
Completing projects is hard work. There's no real hack that will get you through it. To make sure you're in a position to do hard work, make sure the basics of the Maslow hierarchy are taken care of (food, sleep, cleanliness, shelter, money, social relationships, etc.).
The above list are what helps me complete projects but the overall one is that I'm of the mentality that it's a slog and that I should be prepared for it.
[0] https://youtu.be/CBYhVcO4WgI?si=5iMC6crzmPM3xfGe
I work on games as a hobby. Each game takes around 2 years or so to finish, which means I need to be able to sustain PRODUCTIVE development over a long time and resume paused development (for when life gets in the way of the hobby or I just need a break).
Here's my tips (based solely on my own experience, but maybe some of them will be useful to others):
1. Make a plan to decide what is in scope, what you want to make (at least for now). This plan can be revised, but you want to stick to it unless you have a very good reason to change. Avoid scope creep. (One way I manage this is to set goals. If I exceed my goals' deadlines, I can afford a bit of creep. Otherwise, I stick to the plan.)
1b. DESIGN your systems up front. You want to be adding modules to a well-architected system, rather than chipping away in the dark hoping a sane structure takes form by luck or genius.
2. From the outset, break the project into a series of medium-sized, high-level chunks. In my case, this is things like "create level 1", "complete weapon model 1", "create player gameplay code". Generally, I avoid moving off a chunk until it is completed, and each chunk is broken down into subtasks.
2b. Find a SIMPLE way to track these chunks and tasks. I use Trello, but don't use anything fancy lest the tool become its own side project (I speak from experience...).
3. Try to make some progress most days (unless I'm on a prolonged break). When I'm really not in the mood, I'll settle for just 25 minutes work (and often when you've done the 25, you'll find you're able to do more).
4. While you want a plan, and you want to design things before you implement them, especially architectural aspects, don't worry about being perfect. Get things done. You will be able to fix problems later. This is especially wise to remember if you're stuck – just get something that works there, and maybe tomorrow you'll figure a way to refactor or do it better, or maybe you'll even find that what you had was actually sufficiently decent.
5. Don't feel bad about taking prolonged breaks. For creative projects, this really refuels the tank, but I imagine it'll be useful for any significantly complex project. Absence makes the heart grow fond.
These things work for me at least!
It's been well said here already but side projects can be so different. Some are for learning, some are for trying out certain approaches, and some are really to find out if it's a good day to go to a park.
While it's good to "finish" something, maybe there's an earlier start line, or finishing point you can release, and continue to add to? Sometimes launching can be it's own feedback loop, if you were going to put in.
If it's a side project, unless you're learning testing, do you want to skip some of that? Might just be overdoing it in terms of novelty per feature.
Depending on the personal project, I sometimes will only do tests on the most complex or sensitive parts first. If I can't fetch data from a database by this point...
On the other hand if it was for something professional in the future, maybe I'd want to pay more attention to it.
The fun with personal projects is you don't have to do everything right, you can do it all wrong, because it's up to you and for you.
If it's a side project for others, sometimes the simpler approach with a boring tech can be surprisingly sturdy.
I rewrote something last week, and when deciding to do it in JS or Python, I shrugged and picked python because it could play with something else I was going to try out later. If I thought about it another way I'm sure I could have done it in JS too. Luckily the technologies can often call each other.
In any event, I try to find good stopping points so it's easier to pick up, or start what I can easily finish in one sitting, and maybe thinking about the next step before I walk away to come back to that.
What worked for me is a change in perspective and how to mentally track progress. If you're thinking of the development being 95% done the remaining work is going to be a slog. OTOH if you look at the remaining items as a burn down list and ignore whatever the percentage completed may be, then progress feels more apparent. Going from 11 to 10 items feels better than going from 96.4% to 96.9%. You also have to change your sights to a farther goalpost. Instead of thinking that completing development is the target, think that completing development unlocks the next phase which is sharing the work broadly and interacting, getting feedback, making a landing page for exposure. It's a whole new area to explore a new 0% to 30%. Similarly change from a developer/devops hat to more infrastructure/ops one, etc. Enjoy the journey--and don't think about how slow the last y% is compared to the first X% (that really only means your percentile estimates are way off).
The last thing was that I learned to polish the chores. For 'the fun of it' I completed a side-project with landing page, posted to Product Hunt, and even automated setting up a new customer and billing. I never did much sales/marketing for it, but to this day I have an automated monthly Paypal payment of $0.02 to myself to show that everything's still working as it should. I'm glad to have done it once to know it's all there to copy/paste if I need it for something I really do want to put the effort into marketing.
I've been in a similar place. Here's what I found helped:
1. Hiatus from the project. A few days minimum; more likely weeks or months. Doing other things with my life clears my thoughts, recharges my motivation, and sometimes provides new experiences that spark inspiration.
2. Add this to the top of my todo list: Break my components into smaller pieces. This would ideally be listed as several distinct steps, so it doesn't become an overwhelming monolith of its own. It's important because having smaller components tends to make development changes smaller as well, and therefore more approachable. I'm more likely to sit down and work on a project when I know I can make progress with just a handful of work, rather than a truckload at a time.
3. Be willing to walk away. Sometimes a project turns out to be a lot more work than expected, or an easier solution presents itself, or the original problem ceases to exist, or I discover a good reason to rebuild from scratch, or something comes up in my life that I feel is a better use of my time. It's never time wasted, because I have undoubtedly learned things and expanded my toolkit regardless of reaching the finish line I originally imagined. Realizing that this is normal and perfectly fine takes the burden of obligation off my shoulders, and leaves me in a good state of mind for the next project. (And I can always come back to it if I change my mind later.)