From dominiks-skills
Reference document encoding the owner's coding philosophy. Loaded by other skills as a shared source of truth — not invoked directly. Covers think-first, no-duplication, functional bias, clean architecture, file focus, test quality, accessibility, error design, access-control design.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dominiks-skills:coding-principlesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Applies to every file touched, regardless of which skill is active.
Applies to every file touched, regardless of which skill is active.
Before writing a line of code:
Produce a short mental model first. Don't write first and think later.
If a pattern appears in more than one place, it belongs somewhere shared. Search before adding.
Extend; don't copy.
Prefer functions that take input, return output, touch nothing else. Side effects (HTTP, navigation, toasts, mutations) live in event handlers, useEffect with explicit deps, or mutation onSuccess/onError — never mixed into rendering or pure transforms. In Rust, propagate Result<T, E> with ?; avoid hidden global state and unwrap.
Each file has one clear job.
Frontend layers: types → service (HTTP only) → hooks (data + state) → components (rendering + events) → pages (composition). Pages don't contain business logic; hooks don't import UI libraries; components don't call the API service directly.
Backend layers: DTO (shapes + validation) → model (DB queries as impl methods, no HTTP) → handler (auth → validate → model → respond, thin) → service (cross-cutting: audit, webhooks, notifications). All SQL lives in impl Model. Services are called by handlers, never models.
A file is too large when you scroll to remember what's in it, two unrelated concerns share it, or a change in one area requires understanding the whole file.
Rough signals (not hard limits): React component >250 lines, page >400, hook >150, handler file >500, model file >300. Split by extracting sub-components, dedicated hooks, or sub-resource files.
Never add AI attribution to commits, PRs, issues, comments, or file headers. The owner ships the code.
Every behavior change is implemented with Pocock's red-green-refactor in vertical slices: one test → minimal impl → repeat. Never write all tests first. See the tdd skill.
Tests model real-life user scenarios, not implementation internals.
userEvent over fireEvent — real interaction sequences.Before writing a test, ask in order:
Output: a test plan table before writing any test code.
Every user-visible string goes through the project's i18n layer. Search the existing locale file for an existing key before adding a new one. Use nested namespacing (e.g. moderation.actions.ban, not ban_button_text). Don't translate literally — think native-speaker phrasing. Never hardcode user-visible English in markup.
Hard gate for every frontend change.
<button>, <nav>, <main>, <section>, <dialog> — not <div onClick>. Every <img> has a meaningful alt (or alt="" if decorative). Headings follow logical hierarchy.role, aria-label, keyboard handlers. Live regions for dynamic updates.outline: none without a replacement.getByRole, getByLabelText. If a test can't find an element by role, the element isn't accessible.Errors are a product feature.
type.Every user-facing feature includes an access-control design.
can_moderate, can_publish), not ad-hoc role checks.ERR_<DOMAIN>_<CAUSE>. Each maps to an i18n key.Design for the end user, not the developer.
prefers-reduced-motion.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub dominikdorfstetter/skills