antipattern-czar: The Linter That Refuses to Hide Your Errors
A Bun-powered TypeScript tool that turns swallowed exceptions, weak logging, and brittle string matching into reliability policy.
- antipattern-czar treats error handling as a governance problem, so critical files can be held to a stricter standard than the rest of the tree.
- Its central trick is not just blocking bad patterns, but reclassifying exceptions as approved overrides so the team keeps a record of every deliberate break.
- The repo chooses Bun, TypeScript, and regex because the job is narrow, fast, and easy to extend, not because it wants to replace parser-based linters.
- The project matters most as a policy layer for humans and AI assistants, which makes reliability rules executable instead of aspirational.
The project is not trying to catch every bug. It is trying to stop invisible ones.
antipattern-czar is not a style cop. It is a reliability gate that treats swallowed exceptions, partial logs, and brittle string matching as evidence that failure is being hidden instead of handled. Most linters ask whether code is tidy. This one asks whether the next person will still be able to see what broke.
That difference matters in systems where the worst bugs are not crashes. They are the errors that turn into success-shaped output, because the exception was narrowed too early, the log lost the object, or the code guessed at an error message with a string match. The repo's whole posture is built around refusing that kind of comfort.
Why it was built this way
The backstory is plain enough in the repo's own material: a long debugging session caused by a broad try-catch made the author decide that vague error handling is not just messy, it is expensive. That kind of pain creates doctrine. Once you have lost hours to a missing stack trace or an overconfident catch block, the desire to make failure visible stops sounding ideological and starts sounding practical.
That is why the tone is so strict. The tool is not saying all exceptions are bad. It is saying that some contexts deserve less forgiveness, especially when the code path is critical and the team has already paid for being generous once.
How the czar decides what to flag
The engine lives in a single TypeScript file, detect-antipatterns.ts, and it follows a simple sequence. It merges .antipatternrc.json with DEFAULT_CONFIG, walks the tree recursively with findFilesRecursive, skips known directories, then applies a set of RegExp checks for the anti-patterns the author cares about most.
Those checks are deliberately opinionated. The scanner looks for things like partial error logging, where only error.message gets reported, and error string matching, where code tries to infer meaning from text instead of inspecting the error itself. Most importantly, criticalPaths raise the stakes. A catch-and-continue in a sensitive file is not just another warning. It becomes a harder failure, unless the developer has explicitly documented an APPROVED_OVERRIDE.
Why regex, Bun, and a single-file core are the point
The architecture is tiny on purpose. Bun gives the project fast startup and a direct CLI path, so there is no build step to babysit. A single-file core keeps the logic easy to inspect, easy to copy into other workflows, and easy for contributors to extend without learning a parser framework first.
Regex is the biggest tradeoff, and it is also the point. This is not trying to prove semantic correctness across a whole language grammar. It is trying to catch a narrow set of reliability smells quickly, with enough structure to support policy. For that job, speed and approachability beat AST ceremony.
The other important detail is the .claude/commands material. That turns the repo into something AI-operable, not just human-operable. The checks are not only a script a developer can run. They are also instructions an assistant can follow, which is a small but telling sign of where dev tooling is going.
What it beats, and what it does not try to be
| Approach | Strength | Where antipattern-czar differs |
|---|---|---|
| ESLint-style linting | Broad coverage for general correctness and style rules. | This repo is narrower and more forceful about failure visibility, especially on critical paths. |
| AST-based custom analysis | High precision and deep syntax awareness. | This repo trades parser complexity for faster iteration and simpler rule authoring. |
| Grep or ad hoc scripts | Very quick to write for one-off checks. | This repo packages the checks into a repeatable policy layer with documented overrides. |
| antipattern-czar | Opinionated enforcement of error-handling discipline. | It is not trying to lint everything. It is trying to make hidden failure hard to ship. |
That comparison matters because it keeps the project in scale. It is not an ESLint replacement, and it is not pretending to be. Its value is sharper: it encodes one team's definition of unacceptable error handling, then makes that definition cheap to run and hard to ignore.
What this says about the next generation of dev tools
The most interesting thing about antipattern-czar is how little machinery it needs to exert real policy power. A small CLI, a single analysis file, a handful of regex rules, and a clear override path are enough to turn a preference into an enforceable standard. That is a strong pattern for modern teams, especially when the cost of a mistake is not syntax but silence.
The deeper shift is that the tool is written for both people and assistants. Humans get a fast check on reliability habits. AI agents get a rulebook they can follow when editing code. That combination points toward a future where the best internal tools do not just detect problems. They encode the team's actual tolerance for risk.