I agree that the poster likely focused too much on it, but it's definitely not something you can ignore completely with the assumption you'll always have extra time later to go back and fix things.
1. the degree to which the code can be trusted to operate correctly and in a fault-tolerant way (i.e. “yeah that API endpoint will give you a 5xx about 2% of the time, sorry about that, just retry!”)
2. the degree to which the code optimally models the problem it’s solving, as well as how flexible it is as priors/needs change in the future and whether optimal languages/frameworks/patterns are used to solve the problem expressively.
The former has obvious customer implications — if your webapp craps out every ~20min of usage, or your API silently drops data when it can’t persist something to a data store, that’s bad, you will lose customers (and you deserve to!). Conversely, lacking in the latter could slow you down as you iterate, but you’re just as likely to not need to touch that code for a while if you’re off building new views/features/what-have-you.
I think the “don’t worry about code quality” folks are generally trying to beat it into technical founders/builders’ heads that the thing they’re building is ultimately being judged as a product, not as an engineering project... but that doesn’t mean that reliability and performance aren’t part of what may make your product valuable.
If you have an accounting app for instance, if it crashes every once in a while users will accept that. If it calculates your taxes incorrectly leading to an IRS audit, that is unacceptable and an existential threat to your company.
In that scenario UI could be messy but your tax crunching code has to be the cleanest and best tested code you can write.
It's counter intuitive that high code quality is appropriate once a startup has found some kind of product market fit, but is wholly inappropriate until then. It's a very jarring thing to tech people but to people who really understand business it's very obvious or natural.
One place dealt with Rube Goldberg code forever because most of the people who thought it needed to be fixed left. People conflate “if the code didn’t start that way then we wouldn’t have a product and thus we wouldn’t be having this conversation” with “there’s a good reason for the code to continue being that way”
But there are a lot code quality decisions where increasing quality costs more time. (at least in the short run)
Code consistency - When you write one module one way and a another dev writes it another. Do you rewrite one of the modules for consistency?
Doing the "Right" thing - When there is a better solution and a faster solution that is maybe less maintainable. Which solution do you pick?
Corrections - You wrote some code while learning a new library/technology/api and find that you used it poorly. Do you go back and clean this up?
Code Reviews - How nit picky are you? How good is good enough? If a dev writes out a large feature and you don't like the way he did it do you ask him to fix it?
Database Mistakes - as you learn about and build out your app you realize you made the wrong choice with some database modeling, do you fix it or write unnecessarily complex SQL to fix paper over it?
Analyze or fix CSS - A button looks weird, you're not sure why the css is causing it to render funny. Do you do a deep dive finding the root cause or do you just jam some inline css in there?
One mistake I made is introducing a complex state management solution early on (NGRX); it had many benefits for code quality and overall FE architecture, but it also introduced additional layers, which required more code here and there for all details.
Entities that we get back are stored separately, then put together through selectors when they're needed on a screen. And all that jazz does take time & energy.
The net result is data consistency across components/screens (which is great), separation of concerns and clean code (cool), but at the code of slower development.
Even though, as I'm writing this, I also think about the alternative. Not having it means having less structure, maybe more issues to fix everywhere due to the lack of consistency, etc. It's not a choice that I can weigh easily, even now. I knew the tech already, used it in production before, and it still wasn't easy after all. Details details ^^
> The net result is data consistency across components/screens (which is great)
You probably don't need to be told this, but... how badly was the data really going to drift during a session? If a user notices that part of the UI is stale, they just hit reload, not a big deal. This could be improved later.
I had just delivered & supported an enterprise front-end framework (https://stark.nbb.be/) for which we HAD to help fix issues with state management.
But of course, I just looked at it from the wrong point of view... The point of view of a technical guy, and not the one of a founder.
I'm learning.. ;-)
Fwiw - I can relate to the authors mindset after having spent a lifetime working in "enterprise software". As a team lead / lead engineer you're often judged on code quality metrics (did you clear code scans, security scans, code coverage scans, etc.). I'd have gone down the exact same rabbit hole as him.
It does indeed create a very different way of approaching things. The pressure is simply not the same at all.
I guess that's one of the big lessons for me so far; experience in large enterprises is not comparable to working on a small startup project without funding.
May sound stupid, but it took me time to integrate the idea :)
So many people here are chiming in with this idea that any time not spent shitting out sales is time wasted for a startup company.
What?
Please don’t take advice like this as dogma and throw the baby out with the bath water. Yes, don’t waste time like OP did, but you’re allowed to use your judgement to at least lay down some of the train tracks before you slam the throttle on the fully loaded train to 100%.
And no, I don’t advocate bike shedding on “code quality” for months before touching anything that matters. I still very much value prototyping ideas to inform MVPs, it’s an amazing workflow when you cut out the friction to get to the meat of an idea! And then by all means, get to the path of least resistance where you can sell it ASAP. But along the way you’re going to encounter friction, and you’re going to see where process is actually needed. LISTEN to these “impulses”, just do it carefully and only when the need is VERY clear.
Do not consciously sabotage all engineering efforts because a large number of people on HN told you to otherwise your startup would fail. Turns out, like everything else in life, that there isn’t some magic formula to success here— that the day is only won by the ones who build high rises on landfill.
Yeah it is. I've never seen any startup or project fail due to code quality.
Mind sharing your experience? How many dev months had you guys been writing code before code quality became an issue? And why was it so hard to fix?
One might look at these companies and say that they are "successful" because they employ people, and some might even sell in the 7-figure range. But looking closely, each of the employees at the company could be more successful working for another company, where they don't spend their time firefighting, and instead focus on up-leveling their experience.
If devs are spending time “up-leveling their experience”, that just indicates that it’s a pretty slow-paced field where that time can be traded. It doesn’t mean anything about the business itself.
Maybe you never heard about it, but it was the leading social network before MySpace then Facebook.
It was unable to scale, and as a consequence suffered bad performances and downtime and eventually all the users moved to more recent SN.
MySpace also had similar problems, their main app was an crappy ColdFusion app that they struggled to update to add features or fix bugs.
Facebook on the other hand, was far better technically and it's probably why they won the social network war.
MySpace was sold to News Corporation for millions, it definitely didn't fail as a startup. There's a point where code quality becomes important, I don't think anyone's denying that, but it's after you've got traction and product-market fit.
(That was linked from http://highscalability.com/blog/2007/11/13/friendster-lost-l... but I had to fix the link, since it went to apps.ycombinator.com which must have been the HN URL at the time. Maybe dang can update DNS to make those old links redirect? Everything after the host was still correct.)
Code quality here is more messy code, code that work now but doesn't abstract, ugly variables names like x..
Things that may even make your performance better now but harder/impossible to scale later.
I thought that those would help us further down the road, and I was right, but the issue was more about the time/effort it took me to get there, eventually.
I wouldn't say that code quality doesn't matter, but I certainly should've made more tradeoffs on that front. It was just really hard to judge.
With my background (enterprise frameworks, mostly), quality almost always needed to be top notch, because our deliverables were the basis for many other developments. I guess this created a bias in my way of looking at code quality? :p
I.e. I'd suggest looking at the constraints the entirely opposite way around than "weren't ready to invest the required time/energy" - in this equation, you can (and must) change the "requirements" for time/energy, as the time/energy available for the project is your core limitation that you should treat (in the short run) as out of your control, especially as it concerns the time/energy of others before funding. From the classic project management tradeoffs, this is a "limited budget - adjust scope to match" scenario, not "fixed scope - let's see what the budget will be" one.
And if that feedback was negative then you would have been able to move on to the next thing sooner.
And if that feedback had been positive it would have provided a lot of motivation for your co-founders.
Maybe. But it helps if the person writing the code has a habit of Quality.
That takes many years. When that level is reached, the person basically can't write bad code.
Early on, code Quality takes extra time. Down the road, once it becomes habit, then it is just "how it goes." No extra effort at all.
But design Quality, in my experience, is even more important. This applies to both architecture and UX.
Again, programmers with a great deal of experience will deliver in this arena, as well.
"We are what we repeatedly do. Excellence, then, is not an act, but a habit."
I wrote the BAOBAB server[0] as a "dissertation." It was an exercise to "retrain" my ship software Discipline.
Now, two years later, I'm using it in a brand-new application project. It's working amazingly well.
[0] https://riftvalleysoftware.com/work/open-source-projects/#ba...
I've seen products release to early, and it can sometimes be painful. But releasing too late can be an existential threat to your company.
What you need to build is the minimum product that can steal sustainable amounts of market share from competitors, but that product itself won't be an MVP.
The minimally viable solution will differ depending on the product and market.
If you're entering an entirely green market that is just dying for a solution, a ramshackle MVP held together by cardboard and string might be appropriate.
If you're entering a crowded market, you'll be competing on product or price and what's minimally viable will be somewhat different.
We only tend to hear about the former as that's generally where the biggest opportunities exist, so it's more exciting and makes better reading material. However, if you've 'outsourced' your product market fit to the competition and your aim isn't to be first, but the best, your MVP will necessarily be of higher quality.
Building a really refined product that outclasses on features or experience just isn’t the common usage of MVP. It requires dramatically different framing, strategy. Sloppy code and quick iteration don’t make sense.
In reality “viable” does all the work, it’s definition literally means whatever works best, so it’s almost just a poor term to use in the first place as it basically can stretch to mean anything.
Also the risks aren't symmetrical. If you take an MVP approach and find out an MVP doesn't work you can always build a bigger badder product, you're out a little bit of time(relatively). If however you build out a big bad product and find out you don't have product market fit. You're much more screwed.
Another reason this advice is useful, is because new founders who are more likely to rely on advice and rules of thumb over their own experience are far less capable of solving an un-mvp-able ideas simply because they'll have far less access to the capital required to build a big bad product.
I use air quotes for easy and hard since obviously they are not the words I'm looking for, but I can't find better ones. All(?) problems are difficult to solve in some way.
Anyways, this is almost off-topic, not really fitted for a pragmatic thread such as this one :)
If you have a known market like nuclear fusion and your biggest challenge is going to be how do I scale nuclear fusion, and how do I raise money from the DoD than mvp/lean startup and 99% of the advice on this site aren't applicable.
Tesla, Google, and just so many huge companies absolutely aren’t good fits for it. It’s a limiting framework at this point as people seem to have oversubscribed to the philosophy and turned it into religion.
[1] https://www.npr.org/2020/11/06/932199300/dropbox-drew-housto...
MVPs are good if you're solving a niche problem in a niche industry. But if your competitors are Slack and Zoom, you're going to have a hard time launching with a barebones approach.
(I know bits of their "origin story" but am in no way familiar with their early product or whether that feature was around from the beginning)
I would say yes, @mentions make a chat product like slack minimally viable. It is a baseline expectation of a modern chat solution to be able to ping others by name.
However, the minimally viable form of the @mention feature is where you stop. Skip all things that are not “the @mentioned user received a notification when I send the message”
If you disagree with me, please explain why. I don’t at all believe that a Slack MVP that is nothing more than a WebRTC chat demo would be a sellable MVP in 2020. MVP and prototyping seems to be very conflated.
But wow does this guy not understand an MVP or what matters for a startup.
> I became more and more “aggressive” about reducing the scope and focusing on the essentials
You should do this day one before you write a line of code. There should be nothing you can cut from your MVP. For the first two months of my last MVP to edit data you sent an e-mail to a dev who wrote a sql script that edited it for you. We still added 3k MRR each month. For every feature you should ask "What would happen if I cut this out?" if the answer is anything but "It literally wouldn't work for any individual who could conceivably use this product (with a broad definition of conceivable) then the answer is cut it. Is it a differentiator? cut it. Does your product suck without it? cut it.
You can always trade time for features, but you can never trade features for time.
> Maybe I obsess too much about code quality
The answer is YES YOU DO! Code quality doesn't matter. It really doesn't matter. What killed your first three startups? Was it code quality? Or was it was not getting out a product fast enough, not iterating quickly enough, and not finding product market fit fast enough. This experience is typical.
If the code quality on your MVP doesn't physically disgust you, you're probably focusing on code quality too much.