Separation of Concerns

A design principle that says each part of a system should handle one job, and different jobs should be handled by different parts.


What is it?

Separation of concerns (often abbreviated SoC) is one of the oldest and most important ideas in software design. The computer scientist Edsger Dijkstra introduced the term in 1974, but the idea is far older — it’s essentially “divide and conquer” applied to complexity.

A concern is any distinct piece of functionality or responsibility. In a web application, displaying information to the user is one concern, processing business rules is another, and storing data is a third. Separation of concerns says these jobs should be handled by different, independent parts of the system, not tangled together in one big lump.

When concerns are properly separated, you can change how something looks without affecting how data is stored. You can swap out a database without rewriting the user interface. You can test one piece in isolation because it doesn’t depend on the internals of another piece. Each part becomes simpler to understand, easier to modify, and safer to hand to a different developer (or AI assistant) to work on.

When concerns are not separated, the system becomes fragile. Change one thing, and something seemingly unrelated breaks. This is the software equivalent of pulling one thread and watching the whole sweater unravel.

In plain terms

Separation of concerns is like a well-run kitchen. The person chopping vegetables doesn’t also manage the cash register. The dishwasher doesn’t decide what’s on the menu. Everyone has one clear job, and the kitchen runs smoothly because nobody steps on anyone else’s toes.


At a glance


How does it work?

Separation of concerns shows up at every level of software, from the smallest code file to the largest system design. Here are the most common levels.

1. Language-level separation

The most visible example: how web pages are built.

TechnologyConcernWhat it handles
HTMLStructureWhat’s on the page (headings, paragraphs, buttons)
CSSPresentationHow it looks (colours, spacing, fonts)
JavaScriptBehaviourWhat happens when you interact (clicks, animations, data fetching)

Each technology handles one aspect of the same page. You can completely redesign how a page looks (CSS) without touching what it contains (HTML) or how it behaves (JavaScript).

Think of it like...

A theatre production. The script (HTML) defines what’s said. The set design (CSS) defines how the stage looks. The director (JavaScript) decides what happens when — cues, lighting changes, curtain calls. Change the set design and the script stays the same.


2. Application-level separation

At a larger scale, entire layers of the application handle different concerns:

  • Frontend — everything the user sees and interacts with
  • Backend — business logic, validation, data processing
  • Database — persistent storage and retrieval of data
  • API — the contract between frontend and backend

Each layer can be developed and tested independently. A frontend developer doesn’t need to know how the database is structured — they only need to know what the API returns.

Concept to explore

See contracts-and-interfaces for how the boundaries between layers are defined and enforced.


3. Component-level separation

Inside each layer, individual components have their own concerns. A user interface might have:

  • A navigation component (handles moving between pages)
  • A search component (handles filtering and finding)
  • A card component (handles displaying a single item)

Each component manages its own state and rendering. The search component doesn’t need to know how the card component displays results — it just passes data down.

Concept to explore

See single-responsibility-principle for the code-level version of this idea: every function, class, or module should have one reason to change.


When separation breaks down

Violations of SoC are common and create real problems:

ViolationWhat went wrongWhy it hurts
A UI component directly queries the databasePresentation mixed with data accessCan’t change the database without rewriting the UI
Business rules duplicated in frontend and backendSame concern handled in two placesRules drift apart; one side says “allowed”, the other says “denied”
CSS styles embedded inside JavaScript logicPresentation mixed with behaviourDesigners can’t change the look without editing code logic
One function that validates input, processes data, AND saves to databaseThree concerns in one placeCan’t test any single step in isolation

Rule of thumb

If you describe what a piece of code does and you use the word “and” more than once, it probably handles too many concerns.


Why do we use it?

Key reasons

1. Maintainability. When each part has one job, finding and fixing problems is straightforward. You know exactly where to look when something breaks.

2. Independent development. Different people (or AI assistants) can work on different parts without stepping on each other. The frontend team doesn’t block the backend team.

3. Testability. A component with one concern can be tested in isolation. You don’t need a running database to test whether a button looks right.

4. Reusability. A well-separated component can be used in multiple places. A “card” component that only handles display can show products, articles, or user profiles — because it’s not tangled with product-specific logic.


When do we use it?

  • When building any system with more than one responsibility (which is nearly every system)
  • When multiple people will work on the same codebase
  • When you need to change one aspect of the system (e.g., the design) without risking another (e.g., the data layer)
  • When you want to test pieces independently without spinning up the entire application
  • When planning how to organise files and folders in a new project

Rule of thumb

Separation of concerns isn’t a sometimes-principle — it applies at every scale, from how you organise a single file to how you design a distributed system.


How can I think about it?

The hospital

A hospital is built on separation of concerns.

  • The emergency room handles urgent cases
  • The pharmacy manages medication
  • The radiology department takes and reads scans
  • The billing office handles finances

Each department has specialised staff, equipment, and procedures. A radiologist doesn’t prescribe medicine; a pharmacist doesn’t read X-rays. When the hospital upgrades its billing software, the emergency room keeps running without interruption.

If one person had to do triage, dispense medication, read scans, AND process invoices, the hospital would collapse under the complexity.

The newspaper

A newspaper separates concerns across its staff.

  • Reporters gather facts (data access)
  • Editors decide what’s newsworthy and check accuracy (business logic)
  • Layout designers decide how the page looks (presentation)
  • Printers produce the physical paper (delivery / infrastructure)

A reporter doesn’t choose the headline font. A layout designer doesn’t verify facts. Each role focuses on one concern, and the newspaper works because information flows through defined handoffs between roles — like data flowing through layers in software.


Concepts to explore next

ConceptWhat it coversStatus
single-responsibility-principleThe code-level version: one class/function, one reason to changestub
layered-architectureOrganising an entire app into horizontal layers by concernstub
contracts-and-interfacesHow separated parts agree on communication rulescomplete
abstraction-layersHiding complexity behind simple interfacesstub

Some of these cards don't exist yet

They’ll be created as the knowledge system grows. A broken link is a placeholder for future learning, not an error.


Check your understanding


Where this concept fits

Position in the knowledge graph

graph TD
    SD[Software Development] --> SA[Software Architecture]
    SA --> SoC[Separation of Concerns]
    SA --> ABS[Abstraction Layers]
    SA --> CI[Contracts and Interfaces]
    SA --> CSM[Client-Server Model]
    SoC --> SRP[Single Responsibility Principle]
    SoC --> LA[Layered Architecture]
    style SoC fill:#4a9ede,color:#fff

Related concepts:

  • contracts-and-interfaces — contracts enforce the boundaries that separation creates; they define how separated parts communicate
  • abstraction-layers — a mechanism for achieving separation vertically, hiding each layer’s complexity from the one above
  • frontend and backend — the most common example of application-level separation in web development

Further reading

Resources