Elegant Code
Elegant code = Correctness + Clarity + Minimal complexity + Natural efficiency + Easy change.
Not "shortest" or "cleverest." The solution that makes readers think: "Of course. That's simple, right, and hard to mess up."
Optimization Priority (in order)
- Correctness & safety — does what it claims, handles edge cases
- Clarity of intent — reader answers "what/why/how" from code itself
- Simplicity — minimal concepts that still solve the problem
- Changeability — modifications are localized and low-risk
- Efficiency — good algorithms; performance from good design, not micro-optimizations
Elegant vs "Smart" Code
| Elegant |
Smart/Clever |
| Clarity & solution |
Cleverness & brevity |
| Humans first |
Machine first (humans decode) |
| Low complexity |
High complexity |
| Easy to debug/change |
Fragile and opaque |
| "Of course!" |
"Wait… how?" |
The Workflow
Use this sequence when writing or refactoring:
1. Clarify the problem
- Define inputs, outputs, invariants, constraints, failure modes
- Identify postconditions (what must be true after)
- List edge cases and "gotchas"
2. Choose simplest correct approach
- Pick simplest algorithm/data structure meeting constraints
- Prefer fewer concepts over more layers
- If adding abstraction, state what complexity it removes
3. Design shape before details
- Outline modules/functions and responsibilities
- Decide boundaries: pure logic vs side effects (I/O, database, network)
4. Write readable-by-default code
- Clear names, small units, straightforward control flow
- Make "happy path" obvious; handle errors intentionally
5. Add guardrails
- Validation, assertions (where appropriate), tests
- Define invalid input handling
6. Refine (remove, simplify, clarify)
- Remove duplication, tighten interfaces, reduce nesting
- Each unit should read like a single thought
7. Verify against reality
- Run tests; benchmark if performance matters
- Confirm behavior matches original problem statement
Core Rules
Rule 1 — Preserve intent above everything
Reader must answer: What does this do? Why? What constraints? What can go wrong?
- Comments explain why, tradeoffs, constraints—not what code does
- If you need comments to explain what, the code is unclear
Rule 2 — Minimize concepts, not lines
Keep distinct "ideas" (types, abstractions, layers, config knobs) minimal.
- Prefer one good function over a mini-framework
- No "future-proofing" without concrete known need
- If abstraction adds indirection without removing complexity, remove it
Rule 3 — Common case simple; edge cases explicit
- Happy path easy to follow
- Edge cases via early returns, guard clauses, explicit validation
- Avoid deep nesting hiding the main story
Rule 4 — Small, cohesive units
- One primary responsibility per function/module/class
- Group related logic; separate unrelated concerns
- If name needs "and" (parseAndSave), it's doing too much
Rule 5 — Explicit data flow over hidden state
- Data through parameters and return values, not globals/singletons/mutable shared state
- If you can't test without elaborate setup, hidden context exists
- If call order matters, make it explicit
Rule 6 — DRY knowledge, not syntax
- Unify if two places must change together
- Allow small obvious repetition if abstraction is harder to read
- Duplicate code sometimes cheaper than leaky abstraction
Rule 7 — Right algorithmic shape
- Choose algorithms/data structures appropriate to constraints
- Prefer clarity unless profiling demands complexity
- Prefer asymptotic wins over micro-optimizations
Rule 8 — Make invalid states unrepresentable
- Represent domain constraints in types/structures so illegal combinations are impossible
- Validate at boundaries, convert to trusted internal representations
Rule 9 — Local reasoning
- Understand a unit without chasing definitions across codebase
- Small interfaces, directness over indirection
- Configuration close to usage or centralized with clear naming
Rule 10 — Idiomatic but readable
- Follow language/project conventions
- Don't use obscure tricks only experts recognize
- If idiom is compact but unclear, choose clearer form
Micro-Rules
Naming
- DO: Names encode intent and domain meaning, not mechanics
- DO: Concrete nouns/verbs:
calculate_total, is_valid, parse_header
- AVOID: Vague names:
data, process, handle, doThing, tmp, manager
- DO: One concept → one term (consistent vocabulary)
Functions
- Short enough for working memory
- Inputs/outputs obvious and stable
- Side effects clear from name or context
- Favor pure functions for core logic
- I/O at edges ("functional core, imperative shell")
Control Flow
- Avoid deep nesting; use guard clauses
- Early exits for invalid conditions
- Straightforward over clever
Error Handling
- Decide: recover, retry, fallback, or fail fast—then implement consistently
- Errors carry enough context to debug
- Validate at boundaries
- Never swallow errors silently
Dependencies
- Depend on stable interfaces, not unstable internals
- Minimal and purposeful dependencies
- Inject dependencies where it improves testability
Self-Review Checklist
Before finalizing code, verify:
Refactor Decision Rules
Refactor if:
- Function/module cannot be summarized in one sentence
- Must read twice to trust it
- One change requires edits in many unrelated places
- Bugs cluster in same area repeatedly
- Keep adding special cases ("just one more flag")
Avoid refactoring if:
- No tests and behavior unclear (add tests first)
- Code stable and rarely changed, improvements purely aesthetic
- Near deadline and risk is high (smallest safe improvements only)
Detailed References
- Measuring elegance: See references/scorecard.md for the elegance scorecard, objective metrics, and improvement checklist
- Anti-patterns: See references/anti-patterns.md for what kills elegance and "smart code" smells
- Continuous improvement: See references/continuous-improvement.md for the Continuous Elegance Loop and practices
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: elegant-code3description: Language-agnostic rulebook for producing, reviewing, and improving elegant code. Use when writing new code, refactoring existing code, reviewing code quality, or when user asks for "elegant", "clean", "maintainable", or "well-structured" code. Applies to any programming language or framework. Use when this capability is needed.4---56# Elegant Code78Elegant code = **Correctness + Clarity + Minimal complexity + Natural efficiency + Easy change.**910Not "shortest" or "cleverest." The solution that makes readers think: *"Of course. That's simple, right, and hard to mess up."*1112## Optimization Priority (in order)13141. **Correctness & safety** — does what it claims, handles edge cases152. **Clarity of intent** — reader answers "what/why/how" from code itself163. **Simplicity** — minimal concepts that still solve the problem174. **Changeability** — modifications are localized and low-risk185. **Efficiency** — good algorithms; performance from good design, not micro-optimizations1920## Elegant vs "Smart" Code2122| Elegant | Smart/Clever |23|---------|--------------|24| Clarity & solution | Cleverness & brevity |25| Humans first | Machine first (humans decode) |26| Low complexity | High complexity |27| Easy to debug/change | Fragile and opaque |28| "Of course!" | "Wait… how?" |2930## The Workflow3132Use this sequence when writing or refactoring:3334### 1. Clarify the problem35- Define inputs, outputs, invariants, constraints, failure modes36- Identify postconditions (what must be true after)37- List edge cases and "gotchas"3839### 2. Choose simplest correct approach40- Pick simplest algorithm/data structure meeting constraints41- Prefer fewer concepts over more layers42- If adding abstraction, state what complexity it removes4344### 3. Design shape before details45- Outline modules/functions and responsibilities46- Decide boundaries: pure logic vs side effects (I/O, database, network)4748### 4. Write readable-by-default code49- Clear names, small units, straightforward control flow50- Make "happy path" obvious; handle errors intentionally5152### 5. Add guardrails53- Validation, assertions (where appropriate), tests54- Define invalid input handling5556### 6. Refine (remove, simplify, clarify)57- Remove duplication, tighten interfaces, reduce nesting58- Each unit should read like a single thought5960### 7. Verify against reality61- Run tests; benchmark if performance matters62- Confirm behavior matches original problem statement6364## Core Rules6566### Rule 1 — Preserve intent above everything6768Reader must answer: What does this do? Why? What constraints? What can go wrong?6970- Comments explain **why**, tradeoffs, constraints—not what code does71- If you need comments to explain *what*, the code is unclear7273### Rule 2 — Minimize concepts, not lines7475Keep distinct "ideas" (types, abstractions, layers, config knobs) minimal.7677- Prefer one good function over a mini-framework78- No "future-proofing" without concrete known need79- If abstraction adds indirection without removing complexity, remove it8081### Rule 3 — Common case simple; edge cases explicit8283- Happy path easy to follow84- Edge cases via early returns, guard clauses, explicit validation85- Avoid deep nesting hiding the main story8687### Rule 4 — Small, cohesive units8889- One primary responsibility per function/module/class90- Group related logic; separate unrelated concerns91- If name needs "and" (parseAndSave), it's doing too much9293### Rule 5 — Explicit data flow over hidden state9495- Data through parameters and return values, not globals/singletons/mutable shared state96- If you can't test without elaborate setup, hidden context exists97- If call order matters, make it explicit9899### Rule 6 — DRY knowledge, not syntax100101- Unify if two places must change together102- Allow small obvious repetition if abstraction is harder to read103- Duplicate code sometimes cheaper than leaky abstraction104105### Rule 7 — Right algorithmic shape106107- Choose algorithms/data structures appropriate to constraints108- Prefer clarity unless profiling demands complexity109- Prefer asymptotic wins over micro-optimizations110111### Rule 8 — Make invalid states unrepresentable112113- Represent domain constraints in types/structures so illegal combinations are impossible114- Validate at boundaries, convert to trusted internal representations115116### Rule 9 — Local reasoning117118- Understand a unit without chasing definitions across codebase119- Small interfaces, directness over indirection120- Configuration close to usage or centralized with clear naming121122### Rule 10 — Idiomatic but readable123124- Follow language/project conventions125- Don't use obscure tricks only experts recognize126- If idiom is compact but unclear, choose clearer form127128## Micro-Rules129130### Naming131- **DO**: Names encode intent and domain meaning, not mechanics132- **DO**: Concrete nouns/verbs: `calculate_total`, `is_valid`, `parse_header`133- **AVOID**: Vague names: `data`, `process`, `handle`, `doThing`, `tmp`, `manager`134- **DO**: One concept → one term (consistent vocabulary)135136### Functions137- Short enough for working memory138- Inputs/outputs obvious and stable139- Side effects clear from name or context140- Favor pure functions for core logic141- I/O at edges ("functional core, imperative shell")142143### Control Flow144- Avoid deep nesting; use guard clauses145- Early exits for invalid conditions146- Straightforward over clever147148### Error Handling149- Decide: recover, retry, fallback, or fail fast—then implement consistently150- Errors carry enough context to debug151- Validate at boundaries152- Never swallow errors silently153154### Dependencies155- Depend on stable interfaces, not unstable internals156- Minimal and purposeful dependencies157- Inject dependencies where it improves testability158159## Self-Review Checklist160161Before finalizing code, verify:162163- [ ] **Correctness**: Meets requirements; edge cases handled; failures intentional164- [ ] **Clarity**: Names meaningful; reads top-to-bottom; minimal mental jumps165- [ ] **Simplicity**: No unnecessary abstractions; minimal moving parts166- [ ] **Cohesion**: Each unit has one job; responsibilities not mixed167- [ ] **Coupling**: Dependencies minimal; interfaces small and stable168- [ ] **Data flow**: Inputs/outputs explicit; minimal hidden state169- [ ] **Error handling**: Consistent strategy; errors include context170- [ ] **Efficiency**: Algorithm/data structures fit constraints; no obvious waste171- [ ] **Consistency**: Patterns match codebase norms172- [ ] **Testability**: Core logic testable easily; tests exist for tricky parts173174## Refactor Decision Rules175176**Refactor if:**177- Function/module cannot be summarized in one sentence178- Must read twice to trust it179- One change requires edits in many unrelated places180- Bugs cluster in same area repeatedly181- Keep adding special cases ("just one more flag")182183**Avoid refactoring if:**184- No tests and behavior unclear (add tests first)185- Code stable and rarely changed, improvements purely aesthetic186- Near deadline and risk is high (smallest safe improvements only)187188## Detailed References189190- **Measuring elegance**: See [references/scorecard.md](references/scorecard.md) for the elegance scorecard, objective metrics, and improvement checklist191- **Anti-patterns**: See [references/anti-patterns.md](references/anti-patterns.md) for what kills elegance and "smart code" smells192- **Continuous improvement**: See [references/continuous-improvement.md](references/continuous-improvement.md) for the Continuous Elegance Loop and practices193194---195> Converted and distributed by [TomeVault](https://tomevault.io/claim/oleksandrkucherenko) — claim your Tome and manage your conversions.196<!-- tomevault:4.0:skill_md:2026-04-11 -->