Code Quality
Principles
| Principle |
Rule |
| SRP |
One reason to change per function/class |
| DRY |
Extract after 2+ duplicates, not before |
| YAGNI |
Solve today's problem, not tomorrow's hypothetical |
| Composition > Inheritance |
Prefer protocols/interfaces |
| Explicit > Implicit |
Clarity beats cleverness |
| Favor Uniformity |
One way to do each thing (test framework, build tool, deploy method). Migrate quickly + add automatic checks to prevent reversion. Easier to (re-)learn, maintain, and hand off |
| Follow Ecosystem Patterns |
Go all-in on chosen framework's philosophy and idioms. Codify deviations into team policy / coding agent prompts. Fewer surprises for newcomers |
| External Configuration |
Enable external config for components; follow ecosystem patterns (pydantic-settings, Spring @ConfigurationProperties, env vars). Easily reconfigured across environments and tests |
Working vs Production-Ready
| Working |
Production-Ready |
| Happy path works |
Error paths handled |
| Manual testing |
Automated tests |
| Hardcoded config |
Externalized config |
- Distinguish explicitly when delivering: "This works but needs X before production"
- Propose scope cuts explicitly — never implement them silently
Code Smells Checklist
Naming
- Booleans:
is/has/can/should prefix
- Functions: verb prefix (
get, create, handle, fetch)
- Descriptive names; avoid abbreviations unless obvious
Functions
- Single responsibility, <30 lines
- Max 3 parameters; use parameter object beyond that
- Minimize side effects
- Extract complex conditionals into named functions
Complexity
- Max 2 levels nesting; use early returns
- Replace conditional chains with lookup maps/polymorphism
Make Invalid States Unrepresentable
- Use generics / type hints to catch issues at compile-time / static analysis (Python
list[str], Java List<String>, TS Array<string>)
- Use specialized types where invalid inputs are unrepresentable (pydantic
BaseModel with dict[str, str] over raw str, typed keys over string constants)
- No
any in TypeScript (use unknown); no force unwraps in Swift (unless provably safe)
- Use
Optional / Option for null safety -- never return bare None/null when absence is possible
- Validate early at boundaries, convert to constrained types, pass constrained types downstream
- Leverage utility types:
Pick, Omit, Partial, NonNullable
- Priority: compile-time > static analysis > runtime for catching errors
Anti-Patterns
Code
- Premature abstraction -- wait for 2+ concrete implementations
- God objects -- split by responsibility
- Magic values -- use named constants
- Swallowed exceptions -- handle meaningfully or propagate
- Commented-out code -- delete it, git has history
Process
- Large PRs -- keep small and focused
- Skipping tests -- costs more later
- Vague commits -- use
fix: prevent null pointer in user lookup
- TODOs without context -- include why, when, ticket:
// TODO(#123): handle rate limiting
Style Defaults
| Rule |
Value |
| Indentation |
2 spaces (no tabs) |
| Line endings |
LF (Unix) |
| Final newline |
Always |
| Line length |
80-100 soft limit |
| File size |
Under 300 lines |
| Test location |
Colocated (foo.ts + foo.test.ts) or parallel (src/ + tests/) |
Naming conventions: JS/TS/Swift = camelCase, Python/Rust/Go = snake_case, Types = PascalCase, Constants = SCREAMING_SNAKE_CASE
Style Guides by Language
| Language |
Style Guide |
| Python |
Google Python Style Guide |
| JavaScript/TypeScript |
Google JS + TS Style Guides |
| Go |
Google Go Style Guide |
| Bash |
Google Shell Style Guide |
| Rust |
Rust Style Guide |
| C#/.NET |
Microsoft C# Coding Conventions |
See each language skill for detailed naming and practice rules.
Import order (separated by blank lines): 1. Standard library, 2. Third-party, 3. Local modules
Lint Priority Triage
| Priority |
Examples |
When to Fix |
| High |
Type errors blocking build, security vulns, runtime errors |
Immediately |
| Medium |
Missing type annotations, unused vars, style violations |
Before commit |
| Low |
Formatting inconsistencies, comment improvements |
When convenient |
Safe auto-fixes: prettier --write ., eslint --fix .
Manual fixes needed: type annotations, logic errors, missing error handling, accessibility
Refactoring Decision Framework
- Early returns over nested conditionals
- Parameter objects when >3 params
- Lookup maps over conditional chains
- Extract function when a block needs a comment to explain intent
- Typed errors over generic catch-all
// Early return pattern — flatten nested conditionals
function processOrder(order: Order): Result {
if (!order.items.length) return Result.empty();
if (!order.payment) return Result.error('No payment');
if (order.total <= 0) return Result.error('Invalid total');
return Result.ok(checkout(order));
}
Performance (Profile First)
React/Next.js: React.memo, useMemo, code splitting, virtual scrolling
Database: Index frequently queried fields, batch queries (N+1), pagination
API: SWR/React Query caching, debounce/throttle, parallel requests
Bundle: Tree-shake, dynamic imports, route-level code splitting
Dead Code Removal
- Unused imports, unreachable code, unused variables
- Run
tsc --noEmit and check lint warnings
Measurement Tools
| Layer |
Tools |
| Frontend |
Chrome DevTools, Lighthouse CI, React Profiler, Bundle Analyzer |
| Backend |
Node.js profiler, DB query analyzer, APM (DataDog/New Relic), k6/Artillery |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: code-quality-43description: Use when checking code quality, reviewing code smells, assessing code health, writing clean code, or applying style conventions. Do NOT use for PR review workflow or giving/receiving feedback (use code-review-patterns).4---56# Code Quality78## Principles910| Principle | Rule |11|-----------|------|12| SRP | One reason to change per function/class |13| DRY | Extract after 2+ duplicates, not before |14| YAGNI | Solve today's problem, not tomorrow's hypothetical |15| Composition > Inheritance | Prefer protocols/interfaces |16| Explicit > Implicit | Clarity beats cleverness |17| Favor Uniformity | One way to do each thing (test framework, build tool, deploy method). Migrate quickly + add automatic checks to prevent reversion. Easier to (re-)learn, maintain, and hand off |18| Follow Ecosystem Patterns | Go all-in on chosen framework's philosophy and idioms. Codify deviations into team policy / coding agent prompts. Fewer surprises for newcomers |19| External Configuration | Enable external config for components; follow ecosystem patterns (pydantic-settings, Spring `@ConfigurationProperties`, env vars). Easily reconfigured across environments and tests |2021## Working vs Production-Ready2223| Working | Production-Ready |24|---|---|25| Happy path works | Error paths handled |26| Manual testing | Automated tests |27| Hardcoded config | Externalized config |2829- Distinguish explicitly when delivering: "This works but needs X before production"30- Propose scope cuts explicitly — never implement them silently3132## Code Smells Checklist3334**Naming**35- Booleans: `is`/`has`/`can`/`should` prefix36- Functions: verb prefix (`get`, `create`, `handle`, `fetch`)37- Descriptive names; avoid abbreviations unless obvious3839**Functions**40- Single responsibility, <30 lines41- Max 3 parameters; use parameter object beyond that42- Minimize side effects43- Extract complex conditionals into named functions4445**Complexity**46- Max 2 levels nesting; use early returns47- Replace conditional chains with lookup maps/polymorphism4849**Make Invalid States Unrepresentable**50- Use generics / type hints to catch issues at compile-time / static analysis (Python `list[str]`, Java `List<String>`, TS `Array<string>`)51- Use specialized types where invalid inputs are unrepresentable (pydantic `BaseModel` with `dict[str, str]` over raw `str`, typed keys over string constants)52- No `any` in TypeScript (use `unknown`); no force unwraps in Swift (unless provably safe)53- Use `Optional` / `Option` for null safety -- never return bare `None`/`null` when absence is possible54- Validate early at boundaries, convert to constrained types, pass constrained types downstream55- Leverage utility types: `Pick`, `Omit`, `Partial`, `NonNullable`56- Priority: **compile-time > static analysis > runtime** for catching errors5758## Anti-Patterns5960**Code**61- **Premature abstraction** -- wait for 2+ concrete implementations62- **God objects** -- split by responsibility63- **Magic values** -- use named constants64- **Swallowed exceptions** -- handle meaningfully or propagate65- **Commented-out code** -- delete it, git has history6667**Process**68- **Large PRs** -- keep small and focused69- **Skipping tests** -- costs more later70- **Vague commits** -- use `fix: prevent null pointer in user lookup`71- **TODOs without context** -- include why, when, ticket: `// TODO(#123): handle rate limiting`7273## Style Defaults7475| Rule | Value |76|------|-------|77| Indentation | 2 spaces (no tabs) |78| Line endings | LF (Unix) |79| Final newline | Always |80| Line length | 80-100 soft limit |81| File size | Under 300 lines |82| Test location | Colocated (`foo.ts` + `foo.test.ts`) or parallel (`src/` + `tests/`) |8384**Naming conventions:** JS/TS/Swift = `camelCase`, Python/Rust/Go = `snake_case`, Types = `PascalCase`, Constants = `SCREAMING_SNAKE_CASE`8586### Style Guides by Language8788| Language | Style Guide |89|----------|-------------|90| Python | Google Python Style Guide |91| JavaScript/TypeScript | Google JS + TS Style Guides |92| Go | Google Go Style Guide |93| Bash | Google Shell Style Guide |94| Rust | Rust Style Guide |95| C#/.NET | Microsoft C# Coding Conventions |9697See each language skill for detailed naming and practice rules.9899**Import order** (separated by blank lines): 1. Standard library, 2. Third-party, 3. Local modules100101## Lint Priority Triage102103| Priority | Examples | When to Fix |104|----------|----------|-------------|105| High | Type errors blocking build, security vulns, runtime errors | Immediately |106| Medium | Missing type annotations, unused vars, style violations | Before commit |107| Low | Formatting inconsistencies, comment improvements | When convenient |108109**Safe auto-fixes:** `prettier --write .`, `eslint --fix .`110**Manual fixes needed:** type annotations, logic errors, missing error handling, accessibility111112## Refactoring Decision Framework113114- **Early returns** over nested conditionals115- **Parameter objects** when >3 params116- **Lookup maps** over conditional chains117- **Extract function** when a block needs a comment to explain intent118- **Typed errors** over generic catch-all119120```typescript121// Early return pattern — flatten nested conditionals122function processOrder(order: Order): Result {123 if (!order.items.length) return Result.empty();124 if (!order.payment) return Result.error('No payment');125 if (order.total <= 0) return Result.error('Invalid total');126127 return Result.ok(checkout(order));128}129```130131## Performance (Profile First)132133**React/Next.js**: `React.memo`, `useMemo`, code splitting, virtual scrolling134**Database**: Index frequently queried fields, batch queries (N+1), pagination135**API**: SWR/React Query caching, debounce/throttle, parallel requests136**Bundle**: Tree-shake, dynamic imports, route-level code splitting137138## Dead Code Removal139140- Unused imports, unreachable code, unused variables141- Run `tsc --noEmit` and check lint warnings142143## Measurement Tools144145| Layer | Tools |146|-------|-------|147| Frontend | Chrome DevTools, Lighthouse CI, React Profiler, Bundle Analyzer |148| Backend | Node.js profiler, DB query analyzer, APM (DataDog/New Relic), k6/Artillery |149150---151> Converted and distributed by [TomeVault](https://tomevault.io/claim/jlaws) — claim your Tome and manage your conversions.152<!-- tomevault:4.0:skill_md:2026-04-13 -->