---
title: "How to Set Up Claude Code Project Rules for Consistent Code Quality"
url: https://ishchuk.eu/blog/set-up-claude-code-project-rules-for-consistent-code-quality
published: 2026-09-03T18:00:00.000Z
updated: 2026-09-03T16:03:29.355Z
tags: [claude-code, code-quality, hooks, linting, developer-tools, context-engineering, ai-coding]
---

# How to Set Up Claude Code Project Rules for Consistent Code Quality

The single biggest quality lever in Claude Code is not the model. It is the configuration layer you build around it. By mid-2026, AI generates roughly 41% to 50% of all committed code. But that speed has come with a cost: code block duplication has surged 81%, refactoring activity has dropped 70%, and 45% of AI-generated code contains known security vulnerabilities. The teams shipping clean, maintainable code with Claude Code are not the ones with the best prompts — they are the ones with the best project rules.

Project rules in Claude Code span three layers: advisory instructions in CLAUDE.md and `.claude/rules/`, deterministic enforcement through hooks in `settings.json`, and permission guardrails that control what the agent can touch. Each layer serves a distinct purpose, and together they form a system that makes quality the default rather than the exception.

## Why Project Rules Matter: The 2026 Data

The numbers from GitClear's Maintainability Gap research (June 2026) paint a stark picture. Analyzing 623 million code changes from 2023 through 2026, GitClear found:

- Code block duplication is up 81% since the AI coding boom began
- Refactoring — the primary indicator of healthy code maintenance — is down 70% from 2022 levels
- Long-term legacy maintenance has dropped 74%
- Code churn (lines added and then modified or deleted within two weeks) has doubled from a pre-AI baseline of ~3.3% to ~7.1% in 2025
- Within-commit copy/paste is up 41%, meaning AI agents are pasting duplicated blocks rather than extracting shared abstractions

Veracode's 2026 GenAI Code Security Report found that 44% of AI code generation tasks introduced a known security vulnerability. The average security pass rate across models is 56% — barely changed from 55% in their first report. Syntactic fluency has improved dramatically, but security performance has stayed flat.

The critical insight: these outcomes are not inherent to AI. They are the result of running AI coding agents without project rules. Teams that invest in CLAUDE.md and rules files see 40-60% fewer revision cycles on AI-generated code, according to 2026 analysis by Groovy Web. Developers with proper project context complete tasks up to 55% faster, per GitHub's research on AI-assisted coding productivity.

## Layer 1: CLAUDE.md — The Advisory Foundation

CLAUDE.md is the highest-impact file in your Claude Code setup. It lives at your project root and is read at the start of every session. Without it, every session starts from zero — Claude has no idea about your naming conventions, banned libraries, architecture boundaries, or testing standards.

Keep CLAUDE.md under 200 lines. It should contain always-true facts about your project, not task instructions:

- **Tech stack and framework versions** — Next.js 15, Supabase, Stripe, Tailwind CSS v4
- **Architecture summary** — directory structure and where different types of code live
- **Coding rules** — strict TypeScript, server components by default, Result pattern for errors, no default exports except pages
- **Commands** — dev, test, build, lint commands Claude should know
- **Banned patterns** — no `any` types, no hardcoded API keys, no `console.log` in production code

A common mistake is treating CLAUDE.md like a human onboarding guide. Claude does not need to know how to install your project if it is already running. Focus on how to write the code, not how to use the app. Put installation instructions in your README, not in CLAUDE.md.

Use `@` imports to keep CLAUDE.md short while referencing detailed rules elsewhere. A line like `@docs/api-conventions.md` tells Claude to load that file when relevant, keeping your root file focused and your context window clean.

## Layer 2: .claude/rules/ — Path-Scoped Standards

The `.claude/rules/` directory is where modular, domain-specific coding standards live. This solves the monolithic CLAUDE.md problem — instead of cramming every rule into one file, you distribute instructions across targeted files that Claude loads only when working on matching paths.

Each rule file can include a `paths` frontmatter that controls when it loads:

- A rule with `paths: ["src/api/**/*.ts"]` loads only when Claude modifies files in your API directory
- A rule with `paths: ["**/*.test.ts"]` loads only when working on test files
- Rules without `paths` frontmatter load for every session, acting as always-on project memory

This path-scoped loading is critical for token efficiency. When Claude is styling a React component, it does not need your database migration patterns in context. When it is writing an API route, it does not need your CSS naming conventions. Path targeting keeps context focused and rule adherence high.

Recommended rule files for a TypeScript project:

- `.claude/rules/typescript.md` — type safety rules, banned patterns, import ordering
- `.claude/rules/api-routes.md` — API route patterns, error handling, auth middleware
- `.claude/rules/database.md` — migration conventions, query patterns, schema rules
- `.claude/rules/testing.md` — test framework, co-location, coverage thresholds
- `.claude/rules/components.md` — component patterns, styling, accessibility requirements

## Layer 3: Hooks — Deterministic Quality Gates

CLAUDE.md and rules files are advisory — they guide the model, but the model can still ignore them, especially deep in long sessions. Hooks are different. They are deterministic shell scripts that fire at specific lifecycle points and cannot be skipped.

Configure hooks in the `hooks` field of `.claude/settings.json`, at the same level as `permissions`. The three events that matter most for code quality:

**PreToolUse** fires before any tool executes. It is the only hook that can block a tool call. Exit code 2 combined with `{"permissionDecision": "deny"}` in stdout JSON completely stops execution. Use this to intercept destructive commands before they run — `rm -rf`, `git reset --hard`, `DROP TABLE`, or any command your team should never execute automatically.

**PostToolUse** fires after a tool succeeds. This is where automatic formatting and linting happen. When Claude writes or edits a file, a PostToolUse hook matched to `Edit|Write` can run Prettier, ESLint with `--fix`, or TypeScript type checking immediately. If linting fails, the error is sent back to Claude, which fixes the issue and rewrites the file. This creates a tight feedback loop that eliminates the "fix the linting errors" follow-up conversation entirely.

**Stop** fires when Claude finishes its response. Use this for end-of-turn validation — running the full test suite, checking for leftover `console.log` statements, or verifying that all modified files pass your quality gates before the task is considered done.

## A Production Configuration

Here is a battle-tested setup for a TypeScript project. The goal: Claude can work autonomously within safe boundaries, code is always formatted, and destructive operations are impossible.

**`.claude/settings.json` hooks configuration:**

- **PreToolUse matcher "Bash"** — runs a guard script that checks for destructive commands. If the command contains `rm -rf`, `git push --force`, `git reset --hard`, or `sudo`, the script outputs `{"permissionDecision": "deny"}` and exits with code 2, blocking execution entirely.
- **PostToolUse matcher "Edit|Write|MultiEdit"** — runs `npx prettier --write $FILE_PATH && npx eslint --fix $FILE_PATH` on every file Claude modifies. Formatting and lint errors are auto-fixed before Claude moves on.
- **Stop** — runs `npx tsc --noEmit` to verify the entire project still type-checks. If TypeScript finds errors, exit code 2 sends the errors back to Claude, which continues working until the project compiles cleanly.

The guard script reads JSON from stdin, extracts the command field with `jq`, checks it against a denylist of patterns, and exits accordingly. This gives you programmatic control that goes far beyond static permission rules — you can implement any logic you want, from checking branch protection to scanning for secrets.

**Chaining quality gates** in a single PostToolUse hook is powerful: `npx eslint --fix $FILE_PATH && tsc --noEmit && npm test -- --related $FILE_PATH --passWithNoTests`. The `&&` ensures each step must pass before the next runs. First failure stops execution and reports exactly which gate failed. Claude sees the specific error and fixes it.

## Common Mistakes to Avoid

**The Giant README anti-pattern.** Treating CLAUDE.md like documentation for humans. It should be concise, focused on coding standards, and free of installation guides or product descriptions. Every unnecessary token in CLAUDE.md is context Claude has to process on every turn.

**Dead scaffolding in rules.** Old, unused `.claude/rules/*.md` files still load into context if their path conditions are met. This creates context rot — Claude's reasoning quality degrades as irrelevant rules consume context window space. Audit your rules directory quarterly and remove anything that no longer reflects current conventions.

**Leaking local settings to git.** Teams frequently forget to add `.claude/settings.local.json` and `CLAUDE.local.md` to `.gitignore`. This pollutes the repository with developer-specific overrides, machine paths, and personal preferences that break for other teammates.

**Relying on CLAUDE.md alone for formatting.** Claude can be told to "always run the linter after writing code" and will usually comply — but "usually" is not good enough for code quality gates. Long sessions cause instruction drift. Hooks solve this completely by making formatting deterministic rather than advisory.

**Setting allow rules too broadly.** A broad `Bash` allow-rule suppresses all prompts, including the ones that would catch a mistake. Scope your allow rules to specific commands: `Bash(npm test)`, `Bash(npm run lint)`, `Bash(git status)`. Grant autonomy where it is safe; require approval where it matters.

## The Bottom Line

The difference between AI-generated code that ships and AI-generated code that haunts you is thirty minutes of configuration. CLAUDE.md gives Claude the context to write the right code. `.claude/rules/` gives it path-scoped standards so the right code means the right code for each part of your system. Hooks make those standards deterministic — formatting, linting, type checking, and destructive-command blocking that run every single time, without exception.

The teams winning with Claude Code in 2026 are not the ones with the cleverest prompts. They are the ones who treated configuration as engineering, not as an afterthought. Start with a focused CLAUDE.md, add path-scoped rules for each domain, and wire up PostToolUse hooks that auto-format and auto-lint every file Claude touches. Then stop worrying about code quality and start worrying about what to build next.

If you want help auditing your Claude Code configuration, setting up production-grade hooks, or building a rules system tailored to your stack, [ishchuk.eu](https://ishchuk.eu) offers AI automation consulting for engineering teams. We can ship a production-ready rules configuration in days, not months.


## FAQ

### How do I set up Claude Code project rules for consistent code quality?

Create three layers of configuration. First, write a CLAUDE.md file in your project root with your tech stack, architecture, coding rules, and commands, kept under 200 lines. Second, add domain-specific rule files in .claude/rules/ with paths frontmatter so they load only when Claude works on matching files. Third, configure hooks in .claude/settings.json — use PostToolUse hooks to auto-run Prettier and ESLint on every file edit, PreToolUse hooks to block destructive commands, and Stop hooks to run type checking before the session ends. This combination makes code quality deterministic rather than dependent on the model remembering instructions.

### What is the difference between CLAUDE.md and .claude/rules/ in Claude Code?

CLAUDE.md is a single file at your project root that Claude reads at the start of every session. It contains always-true project facts like your tech stack, architecture, and global coding standards. The .claude/rules/ directory contains modular, domain-specific rule files that can include a paths frontmatter field. When a rule file has paths like src/api/**/*.ts, it loads into Claude's context only when working on matching files. This keeps your root CLAUDE.md short and focused while distributing detailed standards across targeted files that load only when relevant, saving tokens and improving rule adherence.

### How do Claude Code hooks work for automatic linting and formatting?

Claude Code hooks are shell commands configured in the hooks field of .claude/settings.json that fire at specific lifecycle points. PostToolUse hooks with a matcher like Edit|Write run after Claude modifies a file. You can chain commands like npx prettier --write $FILE_PATH and npx eslint --fix $FILE_PATH to auto-format and auto-fix linting issues immediately after every edit. If linting fails, the error is sent back to Claude, which fixes the issue and rewrites the file. PreToolUse hooks can block destructive commands by exiting with code 2 and outputting permissionDecision deny in JSON. Unlike CLAUDE.md instructions, hooks are deterministic and cannot be skipped by the model.

### Why is AI-generated code quality a problem in 2026?

GitClear's 2026 Maintainability Gap research, analyzing 623 million code changes, found that code block duplication has surged 81% since AI coding adoption scaled, refactoring activity is down 70%, and code churn has doubled from a pre-AI baseline of 3.3% to 7.1% in 2025. Veracode's 2026 report found that 44% of AI code generation tasks introduced known security vulnerabilities, with the security pass rate remaining flat at 56% despite improvements in syntactic fluency. The root cause is not the AI models themselves but the lack of project rules — teams that invest in CLAUDE.md and rules files see 40-60% fewer revision cycles on AI-generated code.

### What are the most common Claude Code configuration mistakes to avoid?

The most common mistakes are: treating CLAUDE.md like a human onboarding guide instead of focusing on coding standards; leaving dead rule files in .claude/rules/ that cause context rot by loading irrelevant instructions; forgetting to gitignore .claude/settings.local.json and CLAUDE.local.md, which pollutes the repo with personal overrides; relying on CLAUDE.md instructions alone for formatting instead of using deterministic hooks; and setting allow rules too broadly, like allowing all Bash commands, which suppresses important approval prompts. Audit your configuration quarterly and keep CLAUDE.md under 200 lines focused on always-true project facts.