Every tool I've built started the same way: study the competition, catalog their features, build something similar. It felt like product research. It felt responsible.
Then I built a Laravel deployment tool, and something unexpected happened.
I needed to deploy an app using Laravel Nightwatch. Nightwatch runs a background agent via Supervisor, so naturally, I started designing a "Supervisor process manager" feature. The UI would ask for the command, the user, the process name, auto-restart settings, log paths — the full configuration panel. That's what the competition offered. That's what made sense on paper.
But then I stopped and asked a different question: What do I actually want to do?
I want to enable Nightwatch. That's it.
So I built a toggle. One switch. Flip it on, and everything — Supervisor config, installation, process management — happens behind the scenes. No questions asked.
I applied the same pattern to Laravel's scheduler: one toggle, cron job configured. Horizon: one toggle, queue monitoring running. Three features, each discovered the same way: I needed something, felt the friction, and realized the tool was asking me questions it already knew the answer to.
Competitor research teaches you to build features. Using your own tool teaches you to build use cases. Features are generic — they give users every option they might need. Use cases are specific — they collapse all that configuration into the one thing the user is actually trying to do. Pay attention to the moments when your own tool annoys you. That friction is your compass.
I didn't always think this way.
There's a moment every developer recognizes. You find a tool you admire — Laravel Forge, in my case — and you think: I should build something like this. So you study it. You catalog its features. You replicate its architecture. You copy its decisions.
And then something weird happens: the tool you build feels like a replica. It works. It has all the right features. But it doesn't feel like yours. You finish building, click through every screen, and it all works perfectly. And somehow that's the worst part.
With Forge, I copied the features, the expected usage, the architecture decisions, the mental model. All of it came from someone else's brain. Same thing happened when I tried building my own version of Fizzy — I was replicating their features, chasing their vision, without ever stopping to use the tool myself and discover what my vision for it could be. I was caught up in building without ever experiencing the usage.
The thing I kept missing: I have my own usage patterns. When I use a tool, I don't use it the way the designer imagined — I use it the way Iwork. And those patterns, those natural habits, are the raw material for better design decisions.
Here's why we keep doing it: building features someone else already designed is easy. You see a feature, you understand what it does, you build it. Done. Move to the next one.
What's hard is stopping. Stopping to ask: Is this architecture decision actually right for my tool? Is this flow helpful, or am I copying it because it exists?
When you're in building mode, you're blind. You're cranking out features, checking boxes. It feels productive. But you're not designing — you're replicating. And the whole time, you're not actually using the thing you're building. You're not feeling the friction. You're just erecting features on a foundation of someone else's assumptions.
There's a deeper reason for this. As developers, we're conditioned to operate in builder-only mode. For most of our careers, someone else has already made the design decisions. We get handed a spec, a ticket, a wireframe — and we build it. We don't question whether the decisions are right because that's not our job. We're like musicians who've spent years reading sheet music. When someone hands us a blank page, we don't know what to compose. So we find someone else's song and replay it.
That's the uncomfortable truth: competitor research is a crutch. It lets us avoid the harder work of thinking through design decisions ourselves.
That realization changed how I think about what to build.
There are two ways to decide what to build, and they produce different tools.
Feature mindset: What can this tool do?
When I looked at deploying Nightwatch through a feature mindset, the logic was sound: Nightwatch runs a background agent, background agents need Supervisor, therefore my tool needs a Supervisor manager. Let users configure the command, the user, the process name, auto-restart settings, log paths. Give them full control. That's what a server needs.
And it's not wrong. It's just not what anyone actually wants.
Use case mindset: What am I trying to accomplish?
I want to enable Nightwatch. That's it. The tool already knows my app, my server, my environment. It can infer every piece of data needed to run the agent. So why is it asking me?
That's the shift: a feature mindset asks users to provide the information. A use case mindset infers the information and collapses the entire flow into a single decision.
Think of it like a smart home. A feature mindset gives you an app to configure each lightbulb's brightness, color temperature, and schedule individually. A use case mindset gives you a switch that says "movie time" and dims everything to the right level. Both control the same lights. One makes you a technician. The other makes you a homeowner.
It's not about hiding complexity. It's about recognizing that when you're solving a specific problem, complexity has a shape — and that shape is much simpler than the generic version.
Here's what that looks like in practice.
The Nightwatch toggle is the clearest example. A feature mindset would ask you to configure:
- The command to run
- The path to the Artisan binary
- The process user
- The number of processes
- Stop wait seconds
- Stop signal
Six questions. Six blank fields staring at you. One correct answer.
The tool already knows it's a Laravel app. It already knows the Nightwatch command. So I built a toggle. One switch. Behind the scenes, it infers every configuration detail and sets up Supervisor automatically.
Same for Laravel's scheduler. The feature mindset builds a cron job manager. The use case mindset? A toggle that installs php artisan schedule:run to run every minute. You don't see the cron. You just decide: on or off.
Same for Horizon. Same unnecessary questions about Supervisor config. Same solution: one switch.
The pattern: the tool already knows everything it needs. The only decision the user should make is their intent — on or off. Everything else is noise.
After building three features the same way, I noticed a loop.
The process isn't complicated. It emerged organically from using my own tool, not from reading about product design. But looking back, there's a clear pattern:
Use the tool. Not as a builder testing features. As a user trying to get something done. Even if it's an ugly prototype.
Feel the friction. Where does it hurt? What question is the tool asking you that it could answer itself?
Ask: what am I actually trying to accomplish? Not "what feature should I build?" but "what outcome do I want?"
Build only what eliminates the pain. Not the abstract case. The specific, concrete thing that would make this moment less painful. Let pain points dictate the roadmap.
That's it. Use, hurt, think, build. Repeat.
The part most developers skip is step one. We jump straight to building because building feels productive. Using your own half-finished tool doesn't. You sit there clicking through broken flows, wincing at every rough edge, wanting to close the editor and go back to building. But that discomfort is exactly where the right abstractions live.
So stop building for a moment. Think about what you actually want to accomplish. How would you want the tool to work in an ideal world? Don't try to cover abstract or broad cases — cover the specific one in front of you.
I didn't discover this alone.
I'm not the only one building this way.
Fewer configuration panels. Fewer "manage your X" screens. More toggles. More switches. More tools that feel like they're reading your mind instead of interrogating you.
We need more opinionated tools. Tools that feel alive — built by someone who encounters the same friction you do, who got annoyed by the same unnecessary questions, who built the shortcut they wished existed.
Laravel is a good example. It's famously opinionated — it makes decisions for you so you can focus on building your app rather than configuring a framework. Eloquent, Artisan, the routing system — they all work a specific way because Taylor Otwell uses them. You can feel the maker's hand in the tool. Basecamp is another one: it serves a broad audience, but every design choice carries the signature of people who actually run projects in it.
This works because Laravel has strong conventions. Artisan lives in a predictable place. The scheduler command is always the same. When your framework gives you enough assumptions, you can infer the right defaults. When it doesn't — or when you serve multiple frameworks — you need the generic config panel. Forge needs generic tools because they serve many frameworks. My tool can afford toggles because it only serves one.
That's fine. Build for yourself first. Let the audience find you.
But there's a catch.
The Nightwatch toggle works because the tool only deploys Laravel. If I ever support other frameworks, that toggle becomes a problem. You can't infer defaults when you don't know the conventions.
Then there's the opposite problem. The more I use my own tool, the more natural it feels — which means the more blind I become to friction that a new user would hit immediately.
But there's another flavor of this that I've already experienced. I maintain Yclas — a classifieds platform — but I don't use it. I work on it, fix bugs, add features — yet I'm not the one running classifieds sites with it every day. I open the codebase and it feels like visiting a house I used to live in. Everything's familiar but nothing's mine anymore. I'm losing the ability to see where the friction is. The tool is drifting away from the user experience because I'm no longer living it.
This is the paradox: the same thing that makes your tool great — deep personal usage — is what makes it hardest to evaluate objectively. You stop seeing the rough edges because you've memorized the path around them. And when you stop using it altogether, you can't see the rough edges at all.
Dogfooding isn't something you do once. It's something you have to keep doing. The moment you switch from user to maintainer, your instincts start collecting dust.
The best abstractions don't come from studying what others have built. They come from paying attention to what annoys you.
Every toggle in my deployment tool exists because I got tired of answering questions my tool already knew the answer to. I found those abstractions by using my own tool and refusing to look away from the friction.
So find the place where your tool asks you something it should already know. That's your next feature. Use tools like Laravel and Basecamp and pay attention to where they make decisions for you — notice how different that feels. And if you're building your own tool, try the loop: use it as a user, feel the pain, build only what eliminates it. See what abstractions emerge.