write-less-code
The write-less-code minimalism standard: the full ladder and what never to simplify away.
SKILL.mdplugins/standalone/ceh-coding-conduct/skills/write-less-code/SKILL.md
GitHubWrite less code
The best code is the code never written. This skill is the positive half of
minimalism — what to reach for first. The agent-coding-contract skill owns the
negative half (no new dependencies, no speculative abstractions, minimal
diffs); apply both, don't restate it here.
Procedure
Before writing any code, stop at the first rung that holds:
- Does this need to exist at all? Speculative need → skip it, say so in one line. (YAGNI)
- Stdlib does it? Use it.
- Native platform feature covers it?
<input type="date">over a picker lib, CSS over JS, a DB constraint over app code, an HTTP cache header over a cache layer. - Already-installed dependency solves it? Use it. Never add a new dependency for what a few lines do.
- Can it be one line? One line.
- Only then: the minimum code that works.
The ladder is a reflex, not a research project. Two rungs work → take the higher one and move on. The first lazy solution that works is the right one.
Rungs 4 and 6 fail most often because nobody looked. Before writing custom code, spend one search: grep the repo for a helper that already does it, read the dependency manifest for an installed package that does, and check the session's skill list for one that covers the task. Search a package registry only when the user has allowed a new dependency.
Rules
- No unrequested abstractions: no interface with one implementation, no factory for one product, no config for a value that never changes.
- Deletion over addition. Boring over clever — clever is what someone decodes at 3am. Fewest files; shortest working diff wins.
- Complex request? Ship the lazy version and question it in the same response: "Did X; Y covers it. Need full X? Say so." Never stall on an answer you can default.
- Two stdlib options the same size? Take the one correct on edge cases. Lazy means less code, not the flimsier algorithm.
- Check at the boundary, trust inside. Parse and validate input once, where it enters, into a type that cannot hold a bad value. Code past the boundary takes that type and does not re-check, because repeated defensive checks are code nobody can prove reachable.
- Count what a reader must hold in mind, not lines. Fewer names, layers, and flags in play at once beats a shorter file that makes the reader jump between five.
- Mark deliberate simplifications with a
// less-code:comment so a shortcut reads as intent, not ignorance. If the shortcut has a known ceiling (global lock, O(n²) scan, naive heuristic), the comment names the ceiling and the upgrade path:# less-code: global lock; per-account locks if throughput matters.
When not to be lazy
Never simplify away: input validation at trust boundaries, error handling that prevents data loss, security measures, accessibility basics, anything explicitly requested. User insists on the full version → build it, no re-arguing.
Non-trivial logic (a branch, a loop, a parser, a money/security path) earns ONE
runnable check — the smallest thing that fails if the logic breaks: an
assert-based self-check or one small test file. No frameworks, no fixtures.
Write it only when tests are in scope; otherwise suggest it in one line.
Trivial one-liners need no test; YAGNI applies to tests too.
Output
Code first. Then at most three short lines: what was skipped, when to add it. If the explanation is longer than the code, delete the explanation — every paragraph defending a simplification is complexity smuggled back as prose.
Pattern: [code] → skipped: [X], add when [Y].
Inspired by ponytail (MIT, DietrichGebert).