
André Luiz LunelliTL;DR Separate your frontend components into two clear groups: components/ │ ├── app/ →...
Separate your frontend components into two clear groups:
components/
│
├── app/ → // components that encapsulate business logic
│ ├── AppliesCoupons.vue
│ └── SearchUserInput.vue
│
└── ui/ → // purely visual components
├── Badge.vue
├── Button.vue
└── Input.vue
This fosters a clean architecture, and it works whether you're using Blade, Livewire, Vue, React, or anything else.
At some point, I noticed something was bothering me in my projects.
I was already using components everywhere. Buttons were components. Inputs were components. Modals were components.
Don't get me wrong, that part was good.
But I often found myself doing things like building a registration page where I had an input field that checked whether the email already existed in the database.
So I would create something like:
RegisterEmailInput.vue
Inside it, I'll add:
This would definitely work. But something felt off.
Was that really just an "input"? Or was it part of the application logic?
When everything lives inside the same components/ folder, you start losing clarity.
A Button.vue and a SearchUserInput.vue don’t belong to the same category of responsibility.
One is visual. The other represents domain behavior.
That’s when I made a structural change to the structure I use now:
components/
│
├── app/
│ ├── AppliesCoupons.vue
│ └── SearchUserInput.vue
│
└── ui/
├── Badge.vue
├── Button.vue
└── Input.vue
ui/
You could copy them to another project and they would still work.
app/
These components are not just UI.
They represent application logic.
This separation changes how you think.
Instead of asking:
“Where do I put this component?”
You start asking:
“Is this visual, or does it represent domain behavior?”
That question alone improves architectural clarity.
It also makes:
And the best part?
This approach works in: Laravel (Blade / Livewire), Vue, React or any other component-based frontend. Because this isn’t about framework.