I've been messing with Claude Code for a while now. Typing prompts, letting it write code, closing the terminal. Felt productive. Then someone showed me their .claude/ folder — and I realized I'd been using maybe a tenth of what the tool can do.

Claude Code isn't a chat interface with file access. It's a configurable agent OS that lives in a single hidden folder. And most users never open it. The .claude/ folder controls instructions, permissions, automation hooks, custom slash commands, specialized sub-agents, and persistent project memory. Ignoring it is like owning a car and only ever sitting in the back seat.

Here's what's inside.


Tip 1: CLAUDE.md

You know the drill. Every session starts the same way: "Use TypeScript, run pnpm dev to start, don't touch the config folder." You type it, Claude absorbs it, then four turns later the context window rolls and it forgets. So you type it again. Every single time.

There's a file for that. Create CLAUDE.md in your project root. This file loads into Claude's system prompt at session start — and it survives /compact, which means it won't get evicted when context fills up.

# Project Overview
- Next.js 15, TypeScript, Tailwind CSS
- Run `pnpm dev` to start dev server
- Run `pnpm test` to run tests
- No server components unless specifically asked

# Conventions
- Use named exports for components
- Path aliases: @/components/*, @/lib/*
- Never modify `src/config/` without asking

Once it's there, every session starts with Claude already knowing the ground rules. No more repeating yourself.

One thing to watch: keep it under 200 lines. Past that, Claude starts tuning out the bottom half. And because it loads at session init, changes need a /compact or restart to take effect. There's no "Create CLAUDE.md" button anywhere in the UI — it's just a docs-page convention. But it's the single highest-ROI thing you can do.


Tip 2: .claude/rules/

The problem with one giant CLAUDE.md is that Claude treats it all as equally relevant. Your API conventions fire even when you're editing CSS. Your CSS rules fire during database migrations. Context budget wasted.

The rules/ folder fixes this by letting you scope instructions to specific file paths. Create .claude/rules/api-rules.md:

---
paths:
  - "src/api/**/*.ts"
  - "src/**/*.trpc.ts"
---
# API Rules
- All endpoints must validate input with Zod
- Return proper HTTP status codes (201 for create, 204 for delete)
- Log all errors to Sentry with request context

Files without frontmatter load every session. Files with path scoping only activate when Claude is editing files matching those globs. Cleaner context, less noise.

This was added in a quiet update. Most docs still say "put everything in CLAUDE.md" and the path-scoped frontmatter isn't mentioned in the quickstart. You have to dig into the settings docs to find it. Also, the glob patterns must match the file Claude is about to edit, not what it's currently reading — so if you're testing regex-like patterns, they won't work. Standard glob only.


Tip 3: Custom slash commands via .claude/skills/

Every time you want a code review, you type the same five-sentence prompt. Every time you write tests, same thing. It's like having a smart assistant and refusing to record any macros.

Skills fix this. Create .claude/skills/review/SKILL.md:

---
name: code-review
description: "Review the current changes for bugs, security, and conventions."
---

You are reviewing code changes. Focus on:
1. Logic errors and edge cases
2. Security vulnerabilities (XSS, injection, auth bypass)
3. Deviation from project conventions in CLAUDE.md
4. Performance issues in hot paths

Save it, and /review just works. Type /review, get a structured code review. Done.

The skills directory convention emerged from the user community before Anthropic officially documented it. It's not in the basic CLI help output at all. If you want to go deeper: skills support allowed-tools in frontmatter for read-only modes, model overrides to use a cheaper model for routine tasks, and disable-model-invocation: true so rarely-used skills don't chew up context budget until you invoke them.


Tip 4: Hooks — before and after every action

Claude writes unformatted code. It ignores linters. It commits files in whatever style it feels like. You either accept the mess or fix it manually every time.

Hooks are scripts that run automatically at specific points in Claude's lifecycle. Configure them in .claude/settings.json. Here's one that auto-formats TypeScript after every edit:

{
  "hooks": [
    {
      "event": "PostToolUse",
      "matcher": {
        "toolName": "edit_file",
        "pathPattern": "**/*.{ts,tsx}"
      },
      "command": "npx prettier",
      "args": ["--write", "--log-level", "warn"]
    }
  ]
}

Hooks fire at different lifecycle points. PreToolUse blocks actions (validation, access control). PostToolUse is non-blocking (formatting, logging). PermissionRequest lets you auto-approve safe operations. ContextCompaction re-injects critical context when the window fills.

Here's a real one I use to prevent Claude from touching credentials:

{
  "hooks": [{
    "event": "PreToolUse",
    "matcher": {
      "toolName": "write_file",
      "pathPattern": "**/.env*"
    },
    "command": "echo '{\"allowed\": false, \"message\": \"Protected file\"}'"
  }]
}

Exit code 0 = allow, 1 = block with message, 2 = ask Claude to reconsider.

The hook system is buried under "settings" docs — most users configure their model and never scroll further. The matcher system with tool-and-path filtering is especially obscure. You only find it if you read the full settings schema. Performance note: hooks run sequentially, so chaining slow validation scripts on every edit adds up. Combine related checks into one script, and use async: true for logging or notifications.


Tip 5: Granular permissions

The default permission model is either "ask before everything" (which you'll mash 'y' through fifty times a day) or "auto-approve everything" (which means Claude can rm -rf your project without warning). Both are wrong.

Configure .claude/settings.json with explicit allow/deny rules:

{
  "permissions": {
    "allow": ["read", "edit_file", "create_file", "write_file"],
    "deny": ["bash", "execute_command", "delete_file"],
    "approvals": {
      "Bash": "always",
      "Read": "auto"
    }
  }
}

Deny rules always win over allow rules. So you can broadly allow file operations but specifically deny dangerous shell commands.

The three-tier model (allow, deny, auto-approve) is comprehensive but most users only ever see the binary toggle. The structured JSON rules require editing config files directly. A common mistake: denying bash at the tool level blocks everything, including npm install and git status. If you want granular control, pair deny with path matchers, not blanket tool blocks.


Tip 6: Sub-agents for isolation

If you ask Claude to review its own code for security issues, you're getting a review from someone who doesn't want to admit they made mistakes. That's a fundamental conflict of interest.

Sub-agents fix this. They run in isolated context windows with their own system prompts and tool restrictions. Create .claude/agents/security-review.md:

---
name: security-review
description: "Dedicated security auditor."
tools:
  - read
---

You are a security auditor reviewing code changes. Your role is adversarial.
- Look for XSS, SQL injection, auth bypass, IDOR
- Check for hardcoded secrets
- Verify input sanitization
- Report findings with severity levels only — no fix suggestions

This agent can't write files, can't run commands, can't see your conversation history. It just reads the code and reports vulnerabilities.

The agents/ folder is newer and the docs are sparse. The line between skills and agents is blurry — agents are essentially skills with isolated context, but most users don't know that distinction exists. One gotcha: agents share the same filesystem. A destructive agent with write access can still delete files. Start with read-only agents and escalate gradually.


Pick one thing from this list. Not all six. Not tomorrow.

Open your project's .claude/ right now — or create it if it doesn't exist. Add CLAUDE.md with your two most repeated conventions. It'll take five minutes, and every session from now on starts with Claude already knowing how you work.

The gap between someone who types prompts into Claude Code and someone who configures it isn't talent. It's knowing that hidden folder exists.