Design: DIY vs. a Heavy Dependency
Before reaching for an existing single-purpose tool — especially one with a
GUI, a bundled runtime, an unaudited binary, or that only runs on one platform
— evaluate whether the underlying operation is simple and well-documented
enough to reimplement directly, in code that can be read start to finish.
This is not a mandate to always DIY. Most of the time the existing tool is
still the right call. But the evaluation should always happen before
defaulting to "just install the tool that does this."
When to Use This Skill
| Use this skill when… |
Skip when… |
| A task is about to install a single-purpose tool to perform one operation |
The dependency is a general-purpose runtime/library reused across the project |
| The "app" is a GUI wrapping a well-defined mechanical operation |
A single well-known CLI installable via mise/uv/brew covers it — don't reimplement curl |
| The tool is non-cross-platform, unmaintained, or an opaque bundled binary |
The tool encapsulates hard-to-verify complexity (crypto, hardware timing, safety-critical) |
| Auditing an existing dependency for removal |
No authoritative reference exists to verify a reimplementation against |
The Trigger
Run the evaluation whenever the tool about to be depended on is:
- Single-purpose — does exactly one narrow thing for this project, not a
general-purpose runtime/library reused elsewhere too.
- A GUI wrapping something mechanical — the "app" is a UI on top of a
well-defined operation ("point this at a file and click a button").
- Not cross-platform, or otherwise poorly maintained, one-off, or
distributed as an opaque bundled binary that can't easily be audited.
- Heavier than the job warrants — bundles a runtime (Electron, Qt,
PyInstaller) or drags in a chain of transient dependencies just to perform
one well-scoped operation.
The Decision
DIY is likely right when
- The underlying protocol/algorithm/format is documented, or has an
authoritative open-source reference implementation to verify against — not
something to be guessed at from scratch.
- The reimplementation is bounded — tens to a few hundred lines, not a
multi-week undertaking re-deriving something genuinely hard.
- What results is auditable: one file, or a small readable set, that a
future session (or the same person in six months) can read top to bottom and
trust, instead of a black-box binary.
- It removes a disproportionate dependency chain relative to the value (a
GUI app + its bundled runtime + a mount step, vs. one script + one well-known
library).
DIY is wrong when
- The tool encapsulates real, hard-to-verify complexity — cryptographic
correctness, hardware timing, safety-critical logic — where a subtle bug in a
reimplementation is a worse outcome than keeping the dependency.
- No authoritative reference exists to verify against; the result would be
unverified guesswork shipped with confidence it hasn't earned.
- The dependency is already cheap and well-audited — a single well-known
CLI installable per the Tool Installation Priority (mise → uv → bun →
cargo/go → brew).
- The existing tool is actively maintained and the switching cost (in time, or
in correctness risk) clearly exceeds the dependency it removes.
If DIYing: Verify Against an Authoritative Source
A reimplementation is only as good as its verification. Never trust a
from-scratch port of a protocol or algorithm on memory alone.
- Find an authoritative reference — the original implementation, a spec,
an RFC, or (for reverse-engineered protocols) two or more independent,
converging open-source implementations.
- Cross-check constants and structure directly from source, not from
memory or a summarized web result.
- Write a diff test. Run the new implementation and the reference
implementation's core logic side by side on the same inputs — including edge
cases and boundary conditions — and assert byte-for-byte equality. Don't
eyeball two implementations and declare them equivalent; make a script prove
it.
- Attribute and license correctly. Vendoring or closely porting someone
else's documented algorithm still carries their attribution and license
terms — a reimplementation that quietly drops credit isn't actually more
transparent than the binary it replaced.
Step 3 is the one most often skipped and the one that pays. In the worked
example below it caught a real behavioral divergence before it shipped.
Worked Example (2026-07, nintendo-switch-cfw)
A Switch CFW project depended on CrystalRCM.app — a mounted, unaudited macOS
GUI binary — to perform one operation: inject a fusée-gelée payload over USB
into a console in RCM mode. The exploit's memory layout and USB protocol are
fixed and well-documented (CVE-2018-6242), with byte-identical reference
implementations across multiple independent open-source forks going back to
2018. A textbook DIY candidate.
Replaced with a ~215-line, single-file, uv run-executable script (PEP 723
inline deps: just pyusb). Before trusting it:
- Cross-checked every constant and the full algorithm against two independent
forks' actual source (not a summary), plus the assembly source for the one
binary blob that had to stay vendored (a 124-byte relocator stub, verified
byte-identical across forks).
- Wrote a diff test against a verbatim port of the reference algorithm across
six cases (empty, tiny, a real downloaded payload, and the exact overflow
boundary) — caught one subtle behavioral divergence at the boundary case.
- Smoke-tested the live CLI path (arg parsing, error paths, USB device
enumeration) as far as possible without physical hardware.
Net: a mounted GUI app of unknown provenance replaced by one auditable script
plus pyusb/libusb — both well-known, independently useful libraries, not
another single-purpose black box.
Rationale
Single-purpose GUI tools accumulate silently. Each is individually "just one
dependency," but across a portfolio they add up to a pile of differently-built,
non-cross-platform, unaudited binaries with no shared conventions — the
opposite of the consistency such a portfolio otherwise optimizes for.
The fix isn't "never use existing tools." It's making the evaluation a habit:
before installing the app, ask whether the operation is simple and documented
enough to own directly, verify it properly if so, and fall back to the heavy
dependency when the evaluation says it's genuinely warranted.
Related
code-quality-plugin:code-dep-audit — auditing dependencies you already have
for vulnerabilities and staleness; this skill governs the prior question of
whether to take the dependency at all
agent-patterns-plugin:verify-before-plan — the same "check reality before
committing to an approach" instinct
- YAGNI (
~/.claude/rules/code-quality.md) — DIY only when the win is real;
don't reimplement speculatively, or for a tool that isn't actually being
removed
~/.claude/rules/verify-upstream-before-patching.md — go to the
authoritative source rather than working from memory
~/.claude/rules/offload-to-deterministic-substrate.md — the diff-test step
is that principle applied to correctness verification itself
1---2name: design-diy-vs-dependency3description: Evaluate a transparent DIY reimplementation before depending on a heavy single-purpose tool — GUI wrapper, bundled runtime, unaudited or non-cross-platform binary. Use when a task is about to install such a tool, or when auditing an existing dependency for removal.4---5
6# Design: DIY vs. a Heavy Dependency
7
8Before reaching for an existing single-purpose tool — especially one with a
9GUI, a bundled runtime, an unaudited binary, or that only runs on one platform
10— **evaluate whether the underlying operation is simple and well-documented
11enough to reimplement directly**, in code that can be read start to finish.
12
13This is **not** a mandate to always DIY. Most of the time the existing tool is
14still the right call. But the *evaluation* should always happen before
15defaulting to "just install the tool that does this."
16
17## When to Use This Skill
18
19| Use this skill when… | Skip when… |
20|---|---|
21| A task is about to install a single-purpose tool to perform one operation | The dependency is a general-purpose runtime/library reused across the project |
22| The "app" is a GUI wrapping a well-defined mechanical operation | A single well-known CLI installable via mise/uv/brew covers it — don't reimplement `curl` |
23| The tool is non-cross-platform, unmaintained, or an opaque bundled binary | The tool encapsulates hard-to-verify complexity (crypto, hardware timing, safety-critical) |
24| Auditing an existing dependency for removal | No authoritative reference exists to verify a reimplementation against |
25
26## The Trigger
27
28Run the evaluation whenever the tool about to be depended on is:
29
30- **Single-purpose** — does exactly one narrow thing for this project, not a
31 general-purpose runtime/library reused elsewhere too.
32- **A GUI wrapping something mechanical** — the "app" is a UI on top of a
33 well-defined operation ("point this at a file and click a button").
34- **Not cross-platform**, or otherwise poorly maintained, one-off, or
35 distributed as an opaque bundled binary that can't easily be audited.
36- **Heavier than the job warrants** — bundles a runtime (Electron, Qt,
37 PyInstaller) or drags in a chain of transient dependencies just to perform
38 one well-scoped operation.
39
40## The Decision
41
42### DIY is likely right when
43
44- The underlying protocol/algorithm/format is **documented, or has an
45 authoritative open-source reference implementation** to verify against — not
46 something to be guessed at from scratch.
47- The reimplementation is **bounded** — tens to a few hundred lines, not a
48 multi-week undertaking re-deriving something genuinely hard.
49- What results is **auditable**: one file, or a small readable set, that a
50 future session (or the same person in six months) can read top to bottom and
51 trust, instead of a black-box binary.
52- It removes a **disproportionate dependency chain** relative to the value (a
53 GUI app + its bundled runtime + a mount step, vs. one script + one well-known
54 library).
55
56### DIY is wrong when
57
58- The tool encapsulates **real, hard-to-verify complexity** — cryptographic
59 correctness, hardware timing, safety-critical logic — where a subtle bug in a
60 reimplementation is a worse outcome than keeping the dependency.
61- **No authoritative reference exists** to verify against; the result would be
62 unverified guesswork shipped with confidence it hasn't earned.
63- The dependency is already **cheap and well-audited** — a single well-known
64 CLI installable per the Tool Installation Priority (mise → uv → bun →
65 cargo/go → brew).
66- The existing tool is actively maintained and the switching cost (in time, or
67 in correctness risk) clearly exceeds the dependency it removes.
68
69## If DIYing: Verify Against an Authoritative Source
70
71A reimplementation is only as good as its verification. Never trust a
72from-scratch port of a protocol or algorithm on memory alone.
73
741. **Find an authoritative reference** — the original implementation, a spec,
75 an RFC, or (for reverse-engineered protocols) two or more independent,
76 converging open-source implementations.
772. **Cross-check constants and structure directly from source**, not from
78 memory or a summarized web result.
793. **Write a diff test.** Run the new implementation and the reference
80 implementation's core logic side by side on the same inputs — including edge
81 cases and boundary conditions — and assert byte-for-byte equality. Don't
82 eyeball two implementations and declare them equivalent; make a script prove
83 it.
844. **Attribute and license correctly.** Vendoring or closely porting someone
85 else's documented algorithm still carries their attribution and license
86 terms — a reimplementation that quietly drops credit isn't actually more
87 transparent than the binary it replaced.
88
89Step 3 is the one most often skipped and the one that pays. In the worked
90example below it caught a real behavioral divergence before it shipped.
91
92## Worked Example (2026-07, nintendo-switch-cfw)
93
94A Switch CFW project depended on `CrystalRCM.app` — a mounted, unaudited macOS
95GUI binary — to perform one operation: inject a fusée-gelée payload over USB
96into a console in RCM mode. The exploit's memory layout and USB protocol are
97fixed and well-documented (CVE-2018-6242), with byte-identical reference
98implementations across multiple independent open-source forks going back to
992018. A textbook DIY candidate.
100
101Replaced with a ~215-line, single-file, `uv run`-executable script (PEP 723
102inline deps: just `pyusb`). Before trusting it:
103
104- Cross-checked every constant and the full algorithm against two independent
105 forks' actual source (not a summary), plus the assembly source for the one
106 binary blob that had to stay vendored (a 124-byte relocator stub, verified
107 byte-identical across forks).
108- Wrote a diff test against a verbatim port of the reference algorithm across
109 six cases (empty, tiny, a real downloaded payload, and the exact overflow
110 boundary) — **caught one subtle behavioral divergence at the boundary case**.
111- Smoke-tested the live CLI path (arg parsing, error paths, USB device
112 enumeration) as far as possible without physical hardware.
113
114Net: a mounted GUI app of unknown provenance replaced by one auditable script
115plus `pyusb`/`libusb` — both well-known, independently useful libraries, not
116another single-purpose black box.
117
118## Rationale
119
120Single-purpose GUI tools accumulate silently. Each is individually "just one
121dependency," but across a portfolio they add up to a pile of differently-built,
122non-cross-platform, unaudited binaries with no shared conventions — the
123opposite of the consistency such a portfolio otherwise optimizes for.
124
125The fix isn't "never use existing tools." It's making the evaluation a habit:
126before installing the app, ask whether the operation is simple and documented
127enough to own directly, verify it properly if so, and fall back to the heavy
128dependency when the evaluation says it's genuinely warranted.
129
130## Related
131
132- `code-quality-plugin:code-dep-audit` — auditing dependencies you already have
133 for vulnerabilities and staleness; this skill governs the prior question of
134 whether to take the dependency at all
135- `agent-patterns-plugin:verify-before-plan` — the same "check reality before
136 committing to an approach" instinct
137- YAGNI (`~/.claude/rules/code-quality.md`) — DIY only when the win is real;
138 don't reimplement speculatively, or for a tool that isn't actually being
139 removed
140- `~/.claude/rules/verify-upstream-before-patching.md` — go to the
141 authoritative source rather than working from memory
142- `~/.claude/rules/offload-to-deterministic-substrate.md` — the diff-test step
143 is that principle applied to correctness verification itself