If you went to a coding bootcamp or read a software engineering book in the last 10 years, you were taught a golden rule: Separation of Concerns (SoC).
They told you:
- HTML is for Structure.
- CSS is for Style.
- JavaScript is for Logic.
- Never mix them.
For years, we dutifully split our code into Button.js, Button.css, and ButtonController.js. We felt clean. We felt organized.
But lately, I’ve noticed a shift. The best developers I know are doing the exact opposite. They are merging styles into markup (Tailwind), putting database queries inside UI components (RSC), and writing logic right on the HTML element (htmx).
Are they writing bad code? No. They have just realized that Separation of Concerns is often a lie we tell ourselves to feel organized, when in reality, we are just creating Separation of Files.
The Trap: The "Clean" Bedroom
Imagine you are cleaning your bedroom (your codebase).
Shallow Knowledge says: "Organization means putting similar items together."
- You put all your left socks in one drawer.
- You put all your right socks in another drawer across the room.
- You put your shoes in the attic.
It looks clean. All the "Left Socks" are strictly separated from the "Shoes."
But now, try to get dressed (build a feature). You have to run to the drawer, then the other drawer, then the attic, just to put on your feet.
This is what traditional "Separation of Concerns" does to your code:
// ❌ The "Clean" Way (Separation of Files)
// 1. structure.html
<button id="submit-btn" class="btn-primary">Submit</button>
// 2. styles.css
.btn-primary { background: blue; color: white; }
// 3. controller.js
document.getElementById('submit-btn').addEventListener('click', () => {
// 4. api.js
submitForm();
});
To understand what this button does, you have to open four different files. You have separated the technologies, but you have scattered the feature.
The Deep Concept: Locality of Behavior (LoB)
Carson Gross (creator of htmx) coined a term that is redefining modern architecture: Locality of Behavior.
"The behavior of a unit of code should be as obvious as possible by looking only at that unit of code."
Deep Knowledge understands that true maintainability isn't about separating JS from CSS; it's about separating Feature A from Feature B.
If I want to delete the "Submit Button" feature, I shouldn't have to hunt down a dangling CSS class in one file and an orphaned event listener in another. I should be able to delete one block and be done.
The "Messy" Solution that is Actually Cleaner
This is why tools like Tailwind CSS and React won. They embrace Locality of Behavior.
Look at this "messy" React component:
// ✅ The "Locality of Behavior" Way
export function SubmitButton() {
// Logic is right here
const handleSubmit = async () => {
await db.users.create({ ... });
};
return (
<button
// Styles are right here (Tailwind)
className="bg-blue-500 text-white py-2 px-4 rounded"
// Trigger is right here
onClick={handleSubmit}
>
Submit
</button>
);
}
Shallow Developers look at this and scream: "You're mixing database logic, styles, and markup! It's chaos!"
Senior Developers look at this and sigh in relief: "Thank god. Everything I need to know about the Submit Button is in one place."
The Mental Model: The Toolkit
Stop thinking about your code as a Grocery Store (all fruit in aisle 1, all meat in aisle 5).
Start thinking about your code as a Toolkit.
If you are fixing a sink, you want a "Plumbing Kit" that has a wrench, tape, and a washer together. You don't want to walk to the "Wrench Room" and then the "Tape Room."
- Separation of Concerns: Optimizes for writing code (it feels organized when you create it).
- Locality of Behavior: Optimizes for reading and deleting code (it is easier to maintain).
Conclusion
The industry is swinging back. We realized that separating files by "file extension" (.js, .css, .html) was a mistake.
The future of software engineering (whether it's React Server Components, htmx, or Vue) is about Colocation.
Don't be afraid to put your CSS classes in your HTML. Don't be afraid to put your SQL query near your button.
If it changes together, it should live together.
Top comments (0)