Coupling, Decoupling, and Cohesion
Source: Dev.to
Cohesion – “Keep related things together”
Cohesion describes how well the code inside a file, function, or module belongs together.
- High cohesion – everything inside does one clear job.
- Low cohesion – a random mix of unrelated stuff.
Analogy
Imagine your kitchen drawer:
- Low cohesion – a messy junk drawer with spoons, batteries, tape, old receipts, and a phone charger all mixed together. Finding anything takes forever.
- High cohesion – a well‑organized drawer where cooking tools are in one place, cleaning supplies in another. Easy to find, easy to use.

JavaScript example – low cohesion (avoid this)
// utils.js – does everything (bad!)
function calculateTotal(price, tax) {
return price + tax;
}
function sendEmail(to, message) {
console.log(`Email sent to ${to}`);
}
function getUserAge(birthYear) {
return new Date().getFullYear() - birthYear;
}
function saveToLocalStorage(key, value) {
localStorage.setItem(key, value);
}
This file does math, emailing, age calculation, and storage. Hard to understand, hard to test, hard to fix.
High cohesion (better)
// priceCalculator.js
export function calculateTotal(price, taxRate) {
const tax = price * taxRate;
return price + tax;
}
export function applyDiscount(total, percent) {
return total * (1 - percent / 100);
}
One file = one job (price math). Clean and focused.
Coupling – “How much do modules know about each other?”
Coupling measures how connected two pieces of code are, i.e., how much one part depends on the internals of another.
- High / tight coupling – modules are glued together.
- Low / loose coupling – modules talk nicely but don’t know too much about each other.
Analogy
Lego bricks vs super‑glued blocks:
- Lego bricks snap together easily and can be pulled apart to rebuild (low coupling).
- Super‑glue makes every brick permanently attached; changing one piece breaks the whole thing (high coupling).
Visual – good vs. bad coupling

- Left: everything connected to everything → hard to change.
- Right: small groups connected only when needed → easy to work with.
JavaScript example – tight coupling (bad)
// userService.js
class UserService {
getUser(id) {
// Directly knows it's using localStorage (tight!)
const data = localStorage.getItem(`user_${id}`);
return JSON.parse(data);
}
saveUser(user) {
localStorage.setItem(`user_${user.id}`, JSON.stringify(user));
}
}
This code is glued to localStorage. If you later want to switch to a server or IndexedDB, you must change this file and every place that uses UserService.
Loose coupling (good) – using dependency injection
// storage.js (interface‑like)
export class LocalStorageService {
get(key) { return JSON.parse(localStorage.getItem(key)); }
set(key, value) { localStorage.setItem(key, JSON.stringify(value)); }
}
// userService.js
export class UserService {
constructor(storageService) {
this.storage = storageService; // just uses the interface
}
getUser(id) {
return this.storage.get(`user_${id}`);
}
saveUser(user) {
this.storage.set(`user_${user.id}`, user);
}
}
// Usage
const storage = new LocalStorageService();
const userService = new UserService(storage);
Now UserService doesn’t care how storage works. You can easily swap it for:
class ApiStorageService {
async get(key) { /* fetch from API */ }
async set(key, value) { /* send to API */ }
}
This is decoupling – removing the strong glue between parts.
Decoupling – The Action of Making Coupling Loose
Decoupling means actively reducing how much modules depend on each other’s details.
Common ways in JavaScript:
- Use function parameters instead of global variables.
- Pass dependencies (dependency injection).
- Use interfaces / simple objects instead of concrete classes.
- Use events / callbacks instead of direct calls.
- Separate files by responsibility.
Why Should You Care?
Good cohesion + low coupling = your code is like Lego:
- Easy to understand – one file = one clear idea.
- Easy to change – swap one piece without breaking others.
- Easy to test – test small parts in isolation.
- Easy for teams – different people can work on different pieces.
- Easy to grow – add new features without chaos.
Bad cohesion + high coupling = your code is like a house of cards made of super‑glue:
- A tiny change can break many parts.
- The system becomes fragile, hard to maintain, and difficult to extend.
Places
- Hard to test
- New developers get scared
- Bugs hide everywhere
Quick Rule to Remember
Aim for:
- High cohesion inside each module (one job per file/function)
- Low coupling between modules (talk through simple contracts, not internals)
Next time you write JavaScript, ask yourself:
- “Does this function/file do one main thing?” → Cohesion
- “Does it know too much about other parts?” → Coupling
Keep practicing these ideas – your future self (and teammates) will love you for it!