I ship tools for businesses and learn about coding and product in public.
Here you’ll get:
- short explainers (for the vibe coders out there)
- what I’m building, breaking, and fixing
- notes on turning messy ideas into real workflows
What concept still confuses you?
@mougrine It's a good starting point. You would probably get way more from implementing complete projects and then diving deeper into the single concepts.
Ask AI for guidance, pick the project that interests you most and build it without AI. Building makes all the difference.
@SchoppingHauer The answer is implicit in the vibe coder's attitude: no. Most of them see the money, responsibility be damned.
As soon as the manure hits the fan, they plan to bounce. But reality isn't that simple.
People saying “everyone will just prompt their way to working software” have something to sell you.
Tool vendors need ARR, influencers need engagement and consultants need a new fear cycle.
This hype, however, is a terrible model for how software actually gets built and kept alive.
Most business owners (and most people in general) don’t have the time, the willpower, or the interest to learn how to use AI well enough to produce anything of value.
Not because they’re dumb, they just have a business to run (and a life to live).
Learning how to specify systems, constrain models, review diffs, and own failure modes is still work. Prompting is not free competence.
If you let an LLM handle "everything", you get a bunch of long strings that happen to compile sometimes.
That’s where the real cost shows up.
Software engineering isn't writing the first version. The majority of the lifecycle is change, debugging, integration, ops, security, and explaining decisions to future maintainers.
Fred Brooks already told us there is no silver bullet for the essential complexity of software. The hard part is the harmony of ideas, not the typing.
If nobody gets the system, the system is not "done". It’s just a liability with a deploy button.
We all know the quote: "debugging is twice as hard as writing the code in the first place".
If you ship the cleverest thing you don't understand, you're already well past your ability to fix it when it breaks. By definition.
And this goes for the LLM that generated that mess in the first place. It's technical debt on steroids.
As @martinfowler pointed out, debt can be strategic when you understand what you’re borrowing. Blind LLM output is like to taking out loans in a language you can’t even read.
And rewrites? the big rewrite is often where companies go to die. "We don’t understand this anymore, let’s start over" is usually a major management failure. With AI you can now generate an unmaintainable codebase 10x faster.
“But the model will maintain it.”
Maybe for narrow, well-tested tools. But models don’t know why the weird edge case exists, and reality is made up primarily of special circumstances.
AI collapses the feeling of ease, it does nothing for the all too real complexity.
In general, all tools that increase output without increasing comprehension just move the cliff closer.
None of this means AI is useless. Used by the right people it’s a force multiplier.
The boring prediction is the accurate one:
- People who already understand systems will ship more.
- People who don’t will ship slop, then invoices for rewrites.
- “Everyone will prompt their apps into existence” remains a sales narrative, not a description of businesses that have to survive contact with reality.
If your software comes from vibes, you have a hostage situation, and eventually neither the model nor a very expensive human engineer can free you.
You structure or you drown.
Before writing a single line of code (or letting AI do it for you), learn to build clear models on paper.
I remember the first time I coded a "Connect 4" clone in JS. It was horrible, because I had started coding right away.
Now I begin with a question: what's the smallest conceptual unit I can think of?
In the case of this game, it's a single spot on the grid. Then I build from there:
- Spot: smallest unit, starts empty then hosts a token.
- Board: the collection of all the possible spots.
- Flow: the rules of the game.
- Screen: all that's shown to the players.
Everything is in a one way dependency relation, nothing leaks from one to the other except what's necessary to know. This is separation of concerns.
There are infinite ways to organize a project, but starting with one that's clearly established, makes the coding very easy.
It's a complex and vital skill.
Agree?
@malahhhc Don't buy into the hype, learning backend development properly is a long journey.
Go deeper: choose a project that you like (AI can help here), and build it (without AI). Do not rush, instead grind every important concept you discover. You'll be way more valuable.
90% of software development is maintenance.
Less code is always better than more, and, even better than that, is removing code.
Simplicity is the ultimate sofistication, and It needs thought, not slop.
You are a genius until you run out of tokens.
Claude code is facing an outage right now, and it made me think of this meme, and of all the cuck vibe coders.
Nothing against them personally, I just find it funny and true.
What's the point of building something that makes no sense to you?
Money? You'll probably lose way more from customers' complaints.
Pride? Your image will crumble under the slight scrutiny, leaving you worse off than before.
Time? You'll lose more of it at the first bug, and you'll still learn nothing.
I personally use AI, to provide boilerplate and help with understanding. And I still feel imposter syndrome on the daily, so I truly try to analyze each choice.
There's pleasure in writing code, just like in any other hard craft. I believe it comes from tackling something difficult and coming out of the other side better for it.
Am I alone in this?
@anusha_panwar It is interesting, and it makes a lot of sense: a single function works with different objects at runtime.
Good to see that vibe coding isn't all that's left ahah
A class is a blueprint.
You create an object and it gets a copy of the structure the class defines. Inheritance is usually fixed at creation: the object is an instance of that type.
JavaScript does something different.
Objects inherit by linking to another object, their prototype. When you ask for a property, JS looks on the object first. If it doesn't find it, it walks that link, then the next one, then the next...
Behavior isn’t stamped onto the instance, it’s shared and resolved later.
Look at the image and ask yourself: what actually happens when you call rex.speak()?
1. Is speak on rex? No.
2. Check Dog.prototype. Yes, use that.
rex only owns name. The methods live on the prototype objects it points to.
So:
Classical: the type builds the object and inheritance is mostly a creation-time relationship.
JavaScript: the object stays thin and inheritance is a live lookup chain through other objects.
Classes in modern JS are syntax over this same system. Underneath, it’s still prototypes and links, not blueprints and copies.
You know nothing.
Your knowledge is probably much shallower than you think. This goes for me too.
Many times I discovered myself lacking in a domain that I thought I knew deeply, and AI abstractions make this issue all the more problematic.
Real, prolonged effort is the key.
I decided to go back to reading books/docs for most of my learning, and implementing every single concept in my own way. I don't think I'll go back anytime soon.
What resources do you use to understand deeply?
If you have viable alternatives please comment, I'd like to know.
@KevinNaughtonJr Miopic take. Coding is a craft, not a passive activity. How can a human engineer improve his level 1 and level 3 without going (over and over again, with a lot of mistakes) through level 2?
button.addEventListener("click", handleClick());
Where's the mistake?
It looks reasonable, “Run handleClick when the button is clicked.”
But the real flow is:
1. handleClick() runs as soon as the page loads
2. addEventListener receives whatever handleClick returned
3. the user clicks later, and nothing happens
You don’t call handleClick (the parentheses), you hand it over.
You give the browser the function itself, so it can call it later, not its return value.
A function in JS can be stored, returned it, passed.
This is the whole idea of a callback: you give a function as an argument to another element.
Most callback confusion is not advanced async theory. It’s this:
function is the instruction.
function() is you executing the instruction right now.
Once that clicks, map, timers, and half the docs pages make sense.
Ownership brings money, but comes with enormous responsibilities. Working for someone else takes many of those away, but your potential is capped.
Which poison do you pick?
Sell first, build second.
Yes, but how?
Everybody knows that money should be a professional dev's first priority, but few have a real checklist. So, here's mine:
- A sale is the only feedback
It's great to get lost in the creation process. A compiler, however, only tells you if your project works, not its value.
The moment you ask somebody to pay you, you find out the truth in one second, not after six months of building. Do it first.
- Don't find problems, find budgets
The world is full of problems, not all of them are worth solving. When talking to a client, ask them one question:
"What action did you already take to fix this issue?"
Look for proof of spending, not proof of pain. If they say they hired somebody, paid for a horrible tool or had an assistant take care of it, you are onto something.
- Sell it before it exists
Once you found the right problem, promise that your solution will be ready in a week (or whatever short time you see fit for the tool). If you don't deliver, they don't pay.
The point here is that you should remove any friction that still exists.
IMPORTANT: this estimation requires you to be a proper developer, not a vibe coder. I'm not saying you should scam people. Do this only if you are truly competent.
- Test for signals
One paying client is a good start, but not enough to build a business.
If you are paid by at least 3 clients to solve the same problem and you reach 15k MRR for that tool, you should go all in.
What do you think?
A closure is a function that remembers the world it was born into. Sounds poetic, but that's just the JS reality.
Look at the image.
makeCounter() takes a character, ch, and returns a brand-new function.
That inner function doesn’t take ch as an argument, however it can use it.
So when you write:
const countSs = makeCounter("S");
you get back a function specialized for counting the char "S".
Later:
countSs("MISSISSIPPI");
Returns 4.
makeCounter() has already finished. Its local variables should be gone, but "S" is still there, locked inside countSs().
That retained environment is the closure.
If you wanted, you could make dedicated counters for any other letter (M, I, P, ...) without overcomplicating your code.
It is also used for:
- Hiding internal variables
- Capturing the specific values for event handlers
- Empowering factory functions
One mental model:
A closure carries a private backpack of variables from the place it was created.
countSs() is walking around with "S" in its backpack.
Juggling a bunch of live eels.
That’s what being a new dev at a startup feels like.
But at least you get to pick your eels: closing clients, reading docs, shipping something that actually works. New challenges all the time, and it’s on you to tackle the right ones, because everybody else is busy too.
I love it, but it’s also a lot.
A few things that actually helped:
1. Understand the why, not just the how
I was used to building alone. A startup is a system, usually a small one, which is exactly why your work counts. Get curious about the choices: stack, customers, money. The why is where you improve judgement.
2. Write things down for your future self
One note per discovery: what it is, why we use it, one quirk.When it shows up again (and it will), you’re not starting from zero.
(You can even start an X account just for that…)
3. Learn in public inside the team
Don’t wait until you “fully get it.” Ask, then try. Make a ton of controlled mistakes, take the feedback, and do it again. Momentum beats perfection every day of the week (twice on sunday).
4. Respect other people’s time
Don’t ask passive questions. Try your own solutions first, then bring them to the 10x engineer next to you (every startup has at least one). Better questions mean better mentorship, which builds trust faster.
5. Accept confusion
If everything feels clear, you’re probably not close to the real work yet. Dig deeper, ask for more ownership and get lost on purpose. That’s how you grow.
The secret isn’t knowing everything.
It’s getting good at getting good.
If you’re a new dev in a startup right now:
What’s your tip?
Drop it below. Someone else probably needs it