The Rise of Cohesive Programming — Copy-paste Might be the Future of Frontend

"Separate your code" — that's been the mantra for years. Separate data layer from view layer. Separate logic from UI. Separate styles from markup. But looking at recent frontend development trends, we're moving in the completely opposite direction. What's going on here?

What is Cohesive Programming?

I've started calling this new trend "Cohesive Programming." In contrast to the traditional "separation of concerns," this approach increases cohesion by bringing related elements together in one place.

Data fetching, UI, logic, styling — traditionally, we separated these into different layers, but Cohesive Programming physically brings functionally related elements closer together. As a result, components become self-contained with fewer external dependencies.

This idea has been forming in my mind gradually. I've been involved in web and mobile app development since 2014, suffering through the transition from the jQuery glory days to React. Along the way, I've realized there's often a huge gap between "clean design" and "practical design."

The Limitations of "Clean Code"

For years, I was firmly in the camp advocating for clear separation of concerns. I was devoted to Clean Architecture, DRY principles, and SOLID. I'd lecture junior engineers with "You shouldn't put data fetching in the view layer!" and draw beautiful architecture diagrams with arrows flowing between neatly separated layers.

And then I was thrown into a high-pressure project with a mixed bag of engineers. First, I built the perfect architecture. And then...

Within weeks, my beautiful architecture collapsed. Developers were stepping on each other's toes, backend changes were breaking frontend code, and everyone was waiting for someone else. The problem wasn't that developers were writing "bad" code — it was that the "clean" architecture required excessive coordination.

Fragment Colocation

In large development organizations, coordination becomes a major challenge when many developers work simultaneously. A significant blocker for frontend engineers is the backend API. They need to wait for backend engineers to create REST APIs. Meanwhile, backend engineers are waiting for frontend engineers because they don't know what data the UI needs. This communication cost is extremely high.

One hint at a solution to this challenge is GraphQL. GraphQL is self-explanatory, allowing frontend engineers to write queries to fetch the data they need. By seeing what data is available, they can proceed with implementation without having to ask backend engineers.

Then there's the concept of "Fragment Colocation." Instead of managing React components and the data fetching layer separately, Fragment Colocation in GraphQL specifies queries directly in the component source code:

function UserProfile() {
  const { data } = useQuery(gql`
    query {
      user {
        name
        avatar
        friendCount
      }
    }
  `)

  return <div>{/* Display user data */}</div>
}

The basic idea of colocation is to place related functionality implementations physically close to each other (in the same file or directory). This means everything the component needs is nearby, and developers can complete most of their work in one place without jumping between multiple files or modules.

With this method, components become self-contained since the component and its data requirements are defined in the same place. Compared to traditional separated data fetching layers, there are fewer dependencies between components, making it easier for multiple developers to work in parallel.

The Spread of Cohesive Programming

I've noticed this cohesive pattern appearing everywhere:

TanStack Query: Embracing "Lazy" Code

TanStack Query (formerly React Query) allows writing API URLs directly in view components. This was considered bad practice just a few years ago!

Each component makes its own API calls, and the library magically deduplicates them. It's like telling developers, "Go ahead and write seemingly inefficient code, we'll make it work well."

Tailwind CSS: Copy-Pasteable CSS Templates

Remember when we used to mock "bad developers" for using inline styles? Well, Tailwind CSS basically turned that into a framework:

<!-- This would have gotten you fired in 2015 -->
<button
  class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
  Submit
</button>

The selling point? You can copy-paste components between projects and they just work. No need to understand project-specific CSS architecture.

shadcn/ui: The "Not a Library" Revolution

shadcn/ui takes this even further. It explicitly declares it's "not a library" and instead copies component source code directly into your project. Why? Because you'll inevitably need to customize components for any project. It's easier to copy the code than wait for a Pull-Request with specific customization properties to be merged.

The Inevitability of Distributed Development

These trends aren't happening in a vacuum. The rise of remote work and global development teams has fundamentally changed how we build software.

Imagine you're in San Francisco and your backend developer is in Bangalore. You need a new API endpoint. In the old world, you'd carefully coordinate, design the perfect interface together, and implement it.

In the real world? There's a 12-hour time difference. Every question results in a one-day delay. This is why companies adopt architectures like "microservices" that minimize dependencies between teams.

Fat ViewController: Revenge of the Fallen

Remember when "Fat ViewController" was the ultimate anti-pattern? It's making a comeback—but with a twist.

The old "Fat ViewController" was imperative spaghetti code. The new cohesive components are declarative and functional. React components include data fetching, styling, and business logic, but they don't create the maintenance nightmare they once did.

From Beautiful Code to Practical Code

These trends have humbled me. I used to evaluate code by its architectural beauty. Now I evaluate it by how easily 200 developers can work on it simultaneously without breaking each other's work.

Beautiful abstraction layers are useless if they create bottlenecks. Redundant but practical code that allows teams to work independently is often more valuable in real-world projects.

"duplication is far cheaper than the wrong abstraction"

For a very similar discussion, check out my other post: "Let's Stop Using the Merge-Branch Pattern"

Acceleration by AI

Here's where it gets really interesting—these trends perfectly align with how AI code assistants work. Tools like GitHub Copilot excel at generating copy-paste friendly code like Tailwind CSS classes. They're much better at writing self-contained components than understanding complex project architectures.

The same patterns that help distributed human teams also help AI integration. This is why web frontend development is likely to be automated first—modern patterns are AI-friendly by design.

What's Next?

Will mobile development follow the same path? Not immediately. iOS and Android development are still closely tied to vendor tools and patterns. Apple's ecosystem, in particular, prioritizes "the right way" over developer independence.

But it's coming. SwiftUI and Jetpack Compose are bringing declarative UI patterns to mobile. Flutter already incorporates many of these ideas. I predict mobile development will adopt these patterns within 2-3 years.

Is This Good or Bad?

My feelings about these changes have evolved from resistance to acceptance to enthusiasm. Yes, these patterns might feel wrong to someone trained in traditional software architecture. But they solve real-world problems that traditional architecture often doesn't address.

The question isn't "Is this clean code?" but "Does this help teams deliver value without bottlenecks?"

As a Japanese engineer, I initially struggled with this shift. Our culture values craftsmanship and precision. But I've learned that different scales of development require different approaches.

Reflections on Cohesive Programming

I've seen benefits when teams bring related code closer together, even when it crosses traditional boundaries. There's value in prioritizing independent development over perfect abstraction, and in choosing technologies that reduce dependencies between teams.

Sometimes, the most practical solution is to embrace patterns that work well with copy-paste development and to value working code that delivers results over architecturally perfect solutions.

The future of frontend isn't in perfect separation of concerns. It's in context-aware design that helps real teams build real products in a distributed world.

Are you seeing these trends in your work too? Let me know your thoughts! 👉️ @ryoheyc