Coupling First
Pick the architecture with the weaker coupling.
Layers, patterns, frameworks: pick any two architectures and the better one is the one where the parts can change without dragging each other along. Coupling is the metric. Everything else is proxy.
Opinion
I've watched architects argue layers vs hexagonal vs onion vs Clean for entire afternoons and walk away exactly where they started. The argument is unwinnable as posed because none of them are the metric. They are all proxies for managing coupling, and the actual metric is the thing nobody bothered to measure.
Connascence is the case-file vocabulary because it gives the conversation rungs. “This service has too much coupling” is a vibe; “this service has Connascence of Position across an HTTP boundary, which would be a positional argument list across a network” is a refactoring instruction. Page-Jones gave the ladder in 19923“Comparing Techniques by Means of Encapsulation and Connascence,” CACM 35(9), Sep 1992, pp. 147–151. The original journal paper. Nine forms of coupling, three properties for grading severity. and Mark Richards and Neal Ford built the modern microservice frame on top of it: an architecture quantum is, definitionally, a unit of synchronous connascence.5Fundamentals of Software Architecture (O'Reilly, 2020), Ch. 3 “Modularity.” Defines an architecture quantum as a unit of synchronous connascence — the cleanest definition of a microservice in print. The vocabulary turned out to be load-bearing for a generation that never read the original.
Read the rule of locality literally. The same coupling that is fine inside one file is a disaster across module boundaries; across services, it is the architecture quantum reasserting itself, and the result is a distributed monolith. Static beats dynamic, name beats type, type beats meaning: the ladder is the refactoring direction. Pair it with A2 Three-Tier Hoisting for the import-direction rule and A6 Bounded Contexts for the model boundary, and the case file writes itself.
Copy a note and link
Grab this short comment and drop it into a PR comment or an LLM chat to prompt the right change.
Pick the architecture with the weaker coupling. Read every diff through Page-Jones's connascence ladder: static beats dynamic, name beats type, type beats meaning. The same coupling that is fine inside one file is a distributed monolith across services. Climb down the ladder where you can. /tenet/coupling-first/A7
AI eyes only
Rule: when two designs satisfy the requirement, pick the one with weaker connascence. Lower connascence beats convention.
Reject: choosing the design with stronger coupling because it ships the next test faster. Reject: distributing connascence-of-meaning or connascence-of-position across a network or process boundary.
Generate: name the connascence type when proposing a refactor (CoN, CoT, CoM, CoP, CoA, CoE, CoV, CoI). Choose the option that climbs the ladder downward.
Diagnostic: state the strongest connascence between the two units in one sentence. If you cannot name it, you do not understand the coupling and must not ship the change.
Why?
- Connascence gives a code review a vocabulary with rungs. “Tightly coupled” is a vibe; “Connascence of Position across an HTTP boundary” is a refactoring instruction.
- The Rule of Locality absorbs cohesion. Strong connascence inside one boundary is the definition of high cohesion; the same connascence between two services is the definition of a distributed monolith. One taxonomy, both jobs.
- Static beats dynamic. Even the strongest static rung is weaker than the weakest dynamic rung. That is why types, named identifiers and explicit signatures are the cheapest possible coupling, not bureaucratic overhead.
- Most named architectural patterns are coupling-management techniques in disguise. Strategy decouples policy from algorithm; Adapter decouples interface from implementation; Hexagonal decouples domain from I/O. Naming the coupling names the pattern.
- Mark Richards and Neal Ford's architecture quantum — a unit of synchronous connascence — gives the cleanest microservice definition in print. If two pieces of code are connascent across the network, they are not two services.
- Coupling is measurable. Robert C. Martin's instability metric
I = Ce / (Ca + Ce), John Lakos's CCD/ACD physical-design metrics, and eslint'simport/no-restricted-pathsall read the dependency graph directly. The case file does not have to be philosophy. - Pairs with A6 Bounded Contexts. The boundary is where the connascence rule of locality bites — cross-context imports are the smell, an Anti-Corruption Layer is the fix. The two tenets compose; neither is enough on its own.
- Coding agents are blind to coupling without a vocabulary. Put the connascence ladder in AGENTS.md and the model can name CoP, CoM, CoV in code review and propose the refactor that climbs down. Without the rungs, the agent treats coupling as a binary the way 2010 StackOverflow did.
Origins
The principle is older than most acronyms. Larry Constantine introduced coupling and cohesion together at the 1968 National Symposium on Modular Programming, formalised in Stevens, Myers and Constantine's 1974 IBM Systems Journal paper “Structured Design”.1“Structured Design,” IBM Systems Journal 13(2), 1974, pp. 115–139. The first published statement of the coupling/cohesion hierarchy. Six rungs of coupling, seven rungs of cohesion, ranked weakest to strongest. Six rungs of coupling, seven rungs of cohesion: a single ranked taxonomy that told you which decompositions were better and which were worse. David Parnas's 1972 “On the Criteria To Be Used in Decomposing Systems into Modules” supplied the reasoning behind the taxonomy — modules earn their boundary by hiding a design decision, and the cost of getting that wrong is paid in coupling.2“On the Criteria To Be Used in Decomposing Systems into Modules,” CACM 15(12), Dec 1972, pp. 1053–1058. Information hiding as the criterion that explains why some couplings cost more than others.
Meilir Page-Jones replaced the 1974 hierarchy with a sharper one in 1992. His paper “Comparing Techniques by Means of Encapsulation and Connascence” (CACM) introduced connascence: nine forms of coupling, graded along three properties — strength, locality, degree.3“Comparing Techniques by Means of Encapsulation and Connascence,” CACM 35(9), Sep 1992, pp. 147–151. The original journal paper. Nine forms of coupling, three properties for grading severity. The book-length treatment in What Every Programmer Should Know About Object-Oriented Design (Dorset House, 1996) gave us the load-bearing rule that has survived every paradigm shift since: even the strongest form of static connascence is weaker than the weakest form of dynamic connascence.4What Every Programmer Should Know About Object-Oriented Design (Dorset House, 1996), Ch. 6. The book-length treatment, including the load-bearing rule that even the strongest static connascence is weaker than the weakest dynamic connascence. Static beats dynamic. Type-system beats runtime. Compile-time visibility is the cheapest possible coupling.
The modern frame is Mark Richards and Neal Ford's Fundamentals of Software Architecture (2020), where Page-Jones's taxonomy is rebuilt around the concept of an architecture quantum — a unit of synchronous connascence.5Fundamentals of Software Architecture (O'Reilly, 2020), Ch. 3 “Modularity.” Defines an architecture quantum as a unit of synchronous connascence — the cleanest definition of a microservice in print. If two pieces of code are connascent across a network boundary, they are not separate services; they are one service in two deployments. Vlad Khononov's Balancing Coupling in Software Design (2024) goes further: he stitches connascence to Constantine's 1974 hierarchy and adds his own Integration Strength model on top.6Balancing Coupling in Software Design (Addison-Wesley, 2024). Stitches Page-Jones connascence to the Constantine 1974 hierarchy and adds the Integration Strength model on top. Three primary sources, fifty years apart, all telling the same story: pick the architecture with the weaker coupling, and use a vocabulary that lets you tell which is which.
Robert C. Martin's instability metric (1994) is the package-level companion: I = Ce / (Ca + Ce), computed off the dependency graph, telling you which way the arrows ought to point.7“OO Design Quality Metrics: An Analysis of Dependencies” (1994). Defines afferent (Ca), efferent (Ce) and the instability metric I = Ce / (Ca + Ce). Coupling has been measurable for thirty years. John Lakos's Large-Scale C++ Software Design (1996) added CCD, ACD, and a whole physical-design metric set used to grade the levelisation of a package graph. Coupling has been measurable for thirty years; the canon's contribution is to insist it is the metric that actually matters.
Quotes
Even the strongest form of static connascence is weaker than the weakest form of dynamic connascence.
We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.
An architecture quantum is an independently deployable artifact with high functional cohesion, high static coupling, and synchronous dynamic coupling.
Connascence feels more like a book exercise and is difficult to apply during the regular flow of test-driven development.
Evidence
Twenty external sources, ranked by author authority. The first five are the canon; expand to see the rest, including the qualifiers and the named opposers. Each links out to its primary source.
- 01The first published statement of the coupling/cohesion hierarchy. Coupling first as a design criterion is in print here.
- 02Modules earn their boundary by hiding a design decision. The reasoning behind why some couplings cost more than others.
- 03Original journal paper introducing connascence — nine forms of coupling, three properties for grading severity, three rules of refactoring.
- 04Book-length treatment. Carries the load-bearing claim: even the strongest static connascence is weaker than the weakest dynamic connascence.
- 05Defines an architecture quantum as a unit of synchronous connascence. The modern microservice frame built on the 1992 taxonomy.
Sixteen sources across the supports, qualifiers and opposers. Stevens, Myers & Constantine 1974, Parnas 1972, Page-Jones 1992 and 1996, and Richards & Ford 2020 are the spine. The qualifiers further down carry the metric-vs-vocabulary tension; the opposers carry the steelman the reply has to address. The honest argument is between the formalists and the pragmatists, not between the supporters and the sceptics.
Examples
// Before: CoP across two modules. Argument order is the contract.export function recordHedgehogSighting( lat: number, lng: number, weightG: number, lengthCm: number, observerId: string, observedAt: Date, microchipId: string) { /* persist */ }// app/api/sightings/route.tsrecordHedgehogSighting(b.lat, b.lng, b.weightG, b.lengthCm, b.observerId, new Date(), b.chip);// scripts/import-historical-sightings.tsrecordHedgehogSighting(row[2], row[3], row[5], row[6], "legacy-import", row[1], row[0]);
// After: CoN, locally contained. The names are the contract.export type HedgehogSightingInput = { lat: number; lng: number; weightG: number; lengthCm: number; observerId: string; observedAt: Date; microchipId: string;}export function recordHedgehogSighting(input: HedgehogSightingInput) { /* persist */ }// app/api/sightings/route.tsrecordHedgehogSighting({ ...b, observedAt: new Date() });// scripts/import-historical-sightings.tsrecordHedgehogSighting(fromCsvRow(row));
Enforcement
Apply these rules in eslint.config.mjs. The full enforcement across every tenet lives on the implementation page.
| Rule | Tool | Catches |
|---|---|---|
| import/no-cycle | eslint-plugin-import | import cycles in the dependency graph. Cycles are the architecture-quantum smell — connascence has crossed a boundary it should not have. |
| import/no-restricted-paths | eslint-plugin-import | imports that violate the rule of locality — a context reaching across a boundary it should be talking to via an Anti-Corruption Layer. |
| max-params | typescript-eslint | long positional argument lists. Connascence of Position; weaken to Connascence of Name with a parameter object. |
| sonarjs/no-identical-functions | eslint-plugin-sonarjs | functions with identical bodies. Connascence of Algorithm — two callers must agree on the same implementation. |
| sonarjs/no-duplicate-string | eslint-plugin-sonarjs | magic literals shared by multiple call sites. Connascence of Meaning; weaken to Connascence of Name with a constant. |
| @typescript-eslint/no-magic-numbers | typescript-eslint | untyped numeric literals appearing inline. Magic numbers are the original Connascence of Meaning at file scope. |
| dependency-cruiser forbidden rules | dependency-cruiser | package-graph violations as a CI step. Outputs the instability metric per module so you can see the I = Ce / (Ca + Ce) values directly. |
eslint.config.mjsconfiguration snippet
import tseslint from 'typescript-eslint';
import importPlugin from 'eslint-plugin-import';
import sonarjs from 'eslint-plugin-sonarjs';
export default tseslint.config({
files: ['**/*.{ts,tsx}'],
plugins: { import: importPlugin, sonarjs },
rules: {
'import/no-cycle': ['error', { maxDepth: 10 }],
'import/no-restricted-paths': ['error', {
zones: [
{
target: './src/lib',
from: './src/app',
message: 'Cross-context import — coupling rule of locality violated.',
},
],
}],
'max-params': ['error', 3],
'sonarjs/no-identical-functions': 'error',
'sonarjs/no-duplicate-string': ['error', { threshold: 5 }],
'@typescript-eslint/no-magic-numbers': ['warn', {
ignore: [-1, 0, 1, 2],
ignoreEnums: true,
ignoreTypeIndexes: true,
}],
}
});AI rules
.cursor/rules/a7-coupling-first.mdc---
description: Prickles A7 — Coupling First
globs: "**/*.{ts,tsx,js,jsx,py,java,php}"
alwaysApply: false
---
## Prickles A7 — Coupling First
Pick the architecture with the weaker coupling. Layers, patterns, frameworks are all proxies; the metric is coupling.
Read every diff through Page-Jones's connascence ladder. Static beats dynamic. Name beats type. Type beats meaning. Position is the smell that wants to become a parameter object.
Apply the rule of locality literally. The same coupling that is fine inside one file is a disaster across module boundaries; across services it is a distributed monolith.
Refuse a refactor that climbs the ladder upward — toward dynamic, away from static — without an explicit reason that the work cannot be done another way.Repo layout, CI, and ESLint wiring for these paths live on /implementation — not repeated on every tenet.
Counter-argument
The strongest steelman is Kevin Rutherford's.8“What happened to Connascence?” Habitable Code, 2024. Honest retrospective: connascence felt like a book exercise during TDD-paced practice; “Explicit vs Implicit Coupling” survived because the team could remember it. Rutherford coached connascence for years and watched it lose ground to plain English in TDD-paced practice. His 2024 retrospective is candid: the nine-rung Latin felt like a book exercise; Explicit vs Implicit Coupling survived because the team could actually use it during a refactor. The implication for “Coupling First” is sharp. The slogan is fine, the case-file vocabulary is academic, and the academic vocabulary underperformed in the place it was supposed to do its work. If the rung labels never make it out of the dossier and into the diff, the ladder may as well not exist.
Counter-argument retort
Cohesion is the obvious counter, and the answer is: connascence absorbs it. The Rule of Locality — one of Page-Jones's three grading properties — is the cohesion argument restated in coupling vocabulary. Strong connascence inside one boundary is what cohesion looks like; the same connascence between two services is the thing that ruins your week. Pick the coupling, set the boundary, and you have done both jobs at once.
Kevin Rutherford's 2024 retrospective “What happened to Connascence?” is the honest pushback worth reading.8“What happened to Connascence?” Habitable Code, 2024. Honest retrospective: connascence felt like a book exercise during TDD-paced practice; “Explicit vs Implicit Coupling” survived because the team could remember it. Rutherford coached connascence for a decade and watched it lose ground to plain English — Explicit vs Implicit Coupling — because nobody could remember the Latin in the heat of a TDD cycle. His point lands. The fix is not to drop the taxonomy but to use the slogan up top and the taxonomy in the case file: read “coupling first” like a working developer reading “test first”, then climb the ladder when you need to name the rung.
The other reasonable objection is “coupling is one of many architectural metrics, not the only one.” Performance, security, observability are real concerns with their own first principles. Granted. The honest weakening: most named architectural patterns are coupling-management techniques in disguise. Strategy decouples policy from algorithm; Adapter decouples interface from implementation; Hexagonal decouples domain from I/O. The patterns book is a coupling textbook with the binding done in different colours.9Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994). Read the Consequences section of each pattern as a coupling trade-off table — Strategy decouples policy from algorithm, Adapter decouples interface from implementation, Observer decouples emitter from listener. When two architectures look comparable, pick the one with the weaker coupling and you will be right more often than the toss of a coin would predict. That is what makes this tenet a tenet.
The practical move is the one A2 Three-Tier Hoistingalready applied: when reasonable patterns disagree, the tie-breaker is the connascence ladder. Static beats dynamic, name beats type, type beats meaning. The tenet's reply to every “but…” is the same: name the form, name the locality, name the degree, then choose.
Notes
- [1]Stevens, Myers & Constantine — “Structured Design,” IBM Systems Journal 13(2), 1974, pp. 115–139. The first published statement of the coupling/cohesion hierarchy. Six rungs of coupling, seven rungs of cohesion, ranked weakest to strongest.
- [2]David L. Parnas — “On the Criteria To Be Used in Decomposing Systems into Modules,” CACM 15(12), Dec 1972, pp. 1053–1058. Information hiding as the criterion that explains why some couplings cost more than others.
- [3]Meilir Page-Jones — “Comparing Techniques by Means of Encapsulation and Connascence,” CACM 35(9), Sep 1992, pp. 147–151. The original journal paper. Nine forms of coupling, three properties for grading severity.