coding-principles
This Claude Code skill provides language-agnostic principles for writing maintainable, readable, and high-quality code across any programming language. It covers core philosophy like prioritizing maintainability over speed and simplicity first, along with practical guidance on code quality, function design, parameter management, and refactoring strategies. Use this skill when implementing new features, refactoring existing code, or conducting code reviews to ensure consistency with established best practices.
git clone --depth 1 https://github.com/shinpr/claude-code-workflows /tmp/coding-principles && cp -r /tmp/coding-principles/dev-workflows-fullstack/skills/coding-principles ~/.claude/skills/coding-principlesSKILL.md
# Language-Agnostic Coding Principles ## Core Philosophy 1. **Maintainability over Speed**: Prioritize long-term code health over initial development velocity 2. **Simplicity First**: Choose the simplest solution that meets requirements (YAGNI principle) 3. **Design Convergence**: Deliver the current required outcome with the least new design surface. Selecting persistent state, public or cross-boundary contracts, behavioral modes, reusable abstractions, or component splits carries enough surface to justify the full convergence process first. 4. **Explicit over Implicit**: Make intentions clear through code structure and naming 5. **Delete over Comment**: Remove unused code instead of commenting it out ## Code Quality ### Continuous Improvement - Refactor related code inside the accepted outcome and governing boundaries when it reduces the change's risk or maintenance cost - Improve code structure incrementally - Keep the codebase lean and focused - Delete code proven obsolete by the requested change after checking its callers; report uncertain or out-of-scope cleanup separately ### Readability - Use meaningful, descriptive names drawn from the problem domain - Use full words in names; abbreviations are acceptable only when widely recognized in the domain - Use descriptive names; single-letter names are acceptable only for loop counters or well-known conventions (i, j, x, y) - Extract magic numbers and strings into named constants - Keep code self-documenting where possible ## Function Design ### Parameter Management - Group related positional parameters into an object, struct, or dictionary when call-site clarity or coordinated evolution requires it. Retain positional parameters when their order is conventional and the call remains clear, or an external/public signature requires them - Preserve external/public signatures unless their migration is part of the accepted outcome or governing artifact ### Single Responsibility - Each function should do one thing well - Extract a function when independently changing responsibilities or obscured control flow make the current unit harder to understand, verify, or reuse; retain a cohesive domain flow when extraction would create artificial coupling - Extract complex logic into separate, well-named functions - Functions should have a single level of abstraction ### Function Organization - Pure functions when possible (no side effects) - Separate data transformation from side effects - Use early returns to reduce nesting - Use early returns or extraction when nesting obscures state transitions or decision ownership; retain nested structure when it maps the domain decision more clearly ## Error Handling ### Error Management Principles - **Always handle errors**: Log with context or propagate explicitly - **Log appropriately**: Include context for debugging - **Protect sensitive data**: Mask or exclude passwords, tokens, PII from logs - **Fail fast**: Detect and report errors as early as possible ### Error Propagation - Use language-appropriate error handling mechanisms - Propagate errors to appropriate handling levels - Provide meaningful error messages - Include error context when re-throwing ## Dependency Management ### Loose Coupling via Parameterized Dependencies - Inject external dependencies as parameters (constructor injection for classes, function parameters for procedural/functional code) - Depend on abstractions, not concrete implementations - Minimize inter-module dependencies - Facilitate testing through mockable dependencies ## Reference Representativeness ### Verifying References Before Adoption When adopting patterns, APIs, or dependencies from existing code: - **IF** a reference sample covers only nearby files → **THEN** confirm the pattern is representative by checking relevant repository usage before adopting - **IF** multiple approaches coexist in the repository → **THEN** identify the majority pattern and make a deliberate choice — selecting whichever is nearest is insufficient - **IF** adopting an external dependency (library, plugin, SDK) → **THEN** verify repository-wide usage and compatibility evidence; when that evidence cannot determine the required version, record the unresolved version decision and the evidence needed to settle it - **IF** following an existing pattern → **THEN** state the reason for following it when an alternative exists (e.g., consistency with surrounding code, avoiding breaking changes, pending coordinated update) ### Principle Nearby code is a starting point for investigation, not a sufficient basis for adoption. Verify that what you reference is representative of the repository's conventions and current best practices before using it as a model. ## Performance Considerations ### Optimization Approach - **Measure first**: Profile before optimizing - **Focus on algorithms**: Algorithmic complexity > micro-optimizations - **Use appropriate data structures**: Choose based on access patterns - **Resource management**: Handle memory, connections, and files properly ### When to Optimize - After identifying actual bottlenecks through profiling - When performance issues are measurable - Optimize only after measurable bottlenecks are identified, not during initial development ## Code Organization ### Structural Principles - **Group related functionality**: Keep related code together - **Separate concerns**: Domain logic, data access, presentation - **Consistent naming**: Follow project conventions - **Module cohesion**: High cohesion within modules, low coupling between ### File Organization - One primary responsibility per file - Logical grouping of related functions/classes - Clear folder structure reflecting architecture - Split a file when it contains independently changing responsibilities or creates material navigation, coupling, or verification cost; retain a cohesive file when splitting would add avoidable coupling or navigation cost ## Commenting Principles ### Default: cod
Generates integration/E2E test skeletons from Design Doc ACs using ROI-based selection and journey-based E2E reservation. Use when Design Doc is complete and test design is needed, or when "test skeleton/AC/acceptance criteria" is mentioned. Behavior-first approach for minimal tests with maximum coverage.
Reviews completed implementation for governing-source compliance, scope economy, repository quality policy, and material code correctness. Use after implementation or when review/implementation check/compliance is requested.
Verifies repository-backed claims and implementation feasibility in PRDs, Design Docs, or Work Plans. Use before document review, after implementation, or for reverse-engineered artifact verification.
Collects compact repository evidence for scope confirmation, technical option selection, complete design, and verification. Use before Design Doc creation when repository facts can change scope, reuse, contracts, cost, or proof.
Detects conflicts across multiple Design Docs and provides structured reports. Use when multiple Design Docs exist, or when "consistency/conflict/sync/between documents" is mentioned. Focuses on detection and reporting only, no modifications.
Reviews one document or one ADR batch against governing requirements, repository evidence, and the needs of its next consumer. Use before user approval or when document consistency and completeness need verification.
Reviews changed integration and E2E tests against skeletons, proof obligations, or explicit prompt claims. Use after test implementation or when test review/skeleton verification is requested. Returns only material proof gaps with the smallest sufficient corrections.
Comprehensively collects problem-related information and creates evidence matrix. Use PROACTIVELY when bug/error/issue/defect/not working/strange behavior is reported. Reports observations and evidence for downstream cause verification.