design-principles
Skill7 starsChanged 3 months agoMITView on GitHub
General object-oriented design principles for TypeScript projects that are NOT part of SOLID or the Gang of Four patterns — coupling and cohesion (incl. connascence), DRY, YAGNI, KISS, separation of concerns, encapsulation / information hiding, Tell Don't Ask, Law of Demeter, composition over inheritance, program-to-an-interface, Command–Query Separation, Principle of Least Astonishment, and fail-fast. Use when designing or refactoring modules, reviewing code for coupling/duplication/leaky-abstraction smells, deciding whether an abstraction earns its keep, or answering "is this good design / which principle applies" questions that SOLID and GoF do not cover.
24 other projects use a version of this.
Adopted by
Most recently taken up by
- twglhk/gamedev-agent-skillstheir own version, first seen Nov 8, 2026
- stigmer/stigmertheir own version, first seen Nov 8, 2026
- dirien/yet-another-agent-harnesstheir own version, first seen Nov 8, 2026
- omidnw/my-skillstheir own version, first seen Nov 3, 2026
- skrrt-sh/skillstheir own version, first seen Nov 1, 2026
- shangyiy/life-kittheir own version, first seen Nov 1, 2026
Used with
Projects with it also use test-driven-development.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
OpenAISkilltest-driven-development
Use when implementing any feature or bugfix, before writing implementation code
Also in 3 projects that use this
Other versions24 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 24
- launchapp-dev/animus-cli★ 39same name
- dirien/yet-another-agent-harness★ 19same name
- HermeticOrmus/design-mastery-claude-code★ 18same name
- ovargas/virtual-team★ 14same name
- shangyiy/life-kit★ 10same name
- stigmer/stigmer★ 9same name
- shualippe/design-principles-skill★ 8same name
- madeinlowcode/skills-claude-code★ 7same name
- Nirusan/claude-config★ 7same name
- jlengrand/my-skills★ 4same name
14 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository12 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- agent-teamsSkill
- bdd-specsSkill
- githubSkill
- gof-patternsSkill
- onboardSkill
- postgres-dbaSkill
- security-webSkill
- solid-principlesSkill
- sqlite-devSkill
- typescript-best-practicesSkill
- user-storiesSkill
The file
We split this skill into the rules it gives an agent
1 rule. 0 are common, 1 is distinctive, and 0 are very specific to this project.
0
Common
Most of the 21 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 96
Connascence is the practical coupling metric: Prefer connascence of *name* (shared identifier) over connascence of *type*, and both over …
“Common” is measured: kept by at least 6 in 10 of the 21 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Design Principles in TypeScript (beyond SOLID & GoF)
The design heuristics that predate and underpin SOLID: how to measure and reduce coupling, maximize cohesion, avoid premature/false abstraction, and keep objects in charge of their own data — adapted to idiomatic TypeScript.
🎯 Why: Design for Change
The goal of writing software is to be able to change it safely. Coupling is the cost of the next change; cohesion is its locality. Tell-Don't-Ask, Demeter, encapsulation, composition-over-inheritance — all of these exist to shrink the blast radius of an edit. DRY and YAGNI cut both ways: too little abstraction and a change ripples; too much and the seam is in the wrong place. Pick the abstraction that makes the next diff small.
Scope — how this differs from the other two skills
solid-principlesowns SRP, OCP, LSP, ISP, DIP. This skill does not re-explain those. Where a principle here is adjacent (Separation of Concerns ≈ SRP at the architecture level; Program-to-an-Interface ≈ DIP/ISP), the reference file states the distinction and defers tosolid-principles.gof-patternsowns the 23 named patterns. This skill explains the forces (coupling, cohesion, Tell-Don't-Ask) that motivate those patterns but never re-documents a pattern. "Composition over inheritance" here is the general principle; the patterns that apply it (Strategy, Decorator) live ingof-patterns.
How to use this skill
- Match the symptom in the decision guide to a principle.
- Open
references/principles.mdfor that principle's full before/after TypeScript example and its "when this is over-engineering" note. - Apply the smallest change that removes real pain. These are heuristics that trade off against each other (DRY vs. coupling, YAGNI vs. extensibility) — resolve the conflict in favor of the code that is cheapest to change now.
Reference file
references/principles.md— all principles with intent, a smell, a bad example, a refactor, TypeScript-specific notes, and when not to apply.
The principles
| Principle | One-line intent |
| Coupling (loose vs. tight) | Minimize what one module must know about another; measure it with connascence. |
| Cohesion | Group things that change together and are used together. |
| DRY | Every piece of knowledge has one authoritative representation. |
| YAGNI | Don't build it until a real requirement demands it. |
| KISS | Prefer the simplest design that works; complexity must be earned. |
| Separation of Concerns | Distinct concerns live in distinct, swappable layers/modules. |
| Encapsulation / Information Hiding | Hide representation; expose intent through behavior. |
| Tell, Don't Ask | Send objects commands; don't pull their state out to decide for them. |
| Law of Demeter | Talk only to immediate collaborators; don't navigate object graphs. |
| Composition over Inheritance | Assemble behavior from parts; reserve inheritance for true substitutability. |
| Program to an Interface | Depend on a role/contract, not a concrete class. |
| Command–Query Separation | A method either changes state or returns a value — not both. |
| Principle of Least Astonishment | Behavior should match the name and the caller's reasonable expectation. |
| Fail Fast | Reject invalid state at the boundary, loudly, before it propagates. |
Decision guide — symptom → principle
| You notice… | Apply |
| Changing module A forces edits in B, C, D | Reduce Coupling (find the connascence) |
| A file groups unrelated helpers used by different callers | Improve Cohesion |
| The same business rule is encoded in three places | DRY |
| Two code paths look identical today but model different concepts | Stop applying DRY — see false-DRY note |
| An abstraction/config exists "for the future" with one caller | YAGNI |
| A clever generic/metaprogramming layer nobody can explain | KISS |
| HTTP, business rules, and SQL interleaved in one function | Separation of Concerns |
| Callers read an object's fields then mutate them back | Tell, Don't Ask / Encapsulation |
a.getB().getC().doThing() train wrecks | Law of Demeter |
| A subclass inherits methods it must disable | Composition over Inheritance |
Business logic news a concrete client / imports an SDK directly | Program to an Interface (then see solid-principles DIP) |
| A getter mutates, or a "save" returns the thing it saved | Command–Query Separation |
A function named getUser also creates one as a side effect | Principle of Least Astonishment |
| Invalid data is detected three layers deep, far from its source | Fail Fast |
TypeScript-specific guidance
- Connascence is the practical coupling metric. Prefer connascence of name (shared identifier) over connascence of type, and both over connascence of position (argument order) — replace positional params with an options object. Keep stronger forms (meaning, algorithm, timing) local to one module. See the Coupling section.
readonly,#private, and accessor methods enforce encapsulation. Use#field(true runtime privacy) over theprivatekeyword when callers must not reach in; exposereadonlyviews instead of mutable arrays/objects.- A narrow function type is an interface. "Program to an interface"
rarely needs a
class implements;type Notify = (e: Event) => voiddecouples just as well with less ceremony. as const+ discriminated unions make illegal states unrepresentable — the strongest form of Fail Fast (compile-time instead of runtime).- Tell-Don't-Ask conflicts with rich domain models exposed to React. UI often legitimately needs to ask (render state). Apply Tell-Don't-Ask to domain/service code; let view models be data bags.
- DRY is about knowledge, not characters. Two functions with identical bodies that encode different decisions should stay separate; coupling them to save lines creates a change-amplifier. Rule of Three before extracting.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

