Claude Code tips: 12 production practices that make it useful
Most Claude Code users stop at the first layer: open it in a terminal, type a request, watch it edit files, and close it. After a month, that workflow can feel only slightly better than an AI autocomplete tool.
Claude Code’s real productivity curve starts later. When you use hooks to run lint before every save, CLAUDE.md to preserve engineering conventions, subagents to split work into parallel windows, and custom slash commands to turn repeated workflows into one command, the same model and the same API calls can produce a very different output curve.
This guide collects 12 production-tested Claude Code practices. Each one includes copy-ready configuration, plus a stable access setup through ClaudeAPI.
Write a useful CLAUDE.md
CLAUDE.md is not a README. It is a high-priority instruction file that gets pulled into context for every session. A good one saves repeated prompts like “please follow our code style”; a bad one wastes tokens.
A useful CLAUDE.md:
# Project conventions
## Tech stack
- Backend: FastAPI 0.115, async-first
- ORM: SQLAlchemy 2.0 with asyncio style
- Tests: pytest + pytest-asyncio; do not use unittest
## Code style
- Do not write multi-line docstrings; each function gets at most one comment line
- Error handling: raise custom Exceptions at business boundaries; do not catch and swallow errors in the service layer
- Do not create new files unless necessary; prefer editing existing files
## Files to read first
- `app/core/deps.py` — all dependency injection entry points
- `app/models/base.py` — all models must inherit from BaseModel
## Forbidden
- Any `print()` debugging statement
- `from x import *`
- Editing already-applied migration files under `migrations/`
# Project conventions
## Tech stack
- Backend: FastAPI 0.115, async-first
- ORM: SQLAlchemy 2.0 with asyncio style
- Tests: pytest + pytest-asyncio; do not use unittest
## Code style
- Do not write multi-line docstrings; each function gets at most one comment line
- Error handling: raise custom Exceptions at business boundaries; do not catch and swallow errors in the service layer
- Do not create new files unless necessary; prefer editing existing files
## Files to read first
- `app/core/deps.py` — all dependency injection entry points
- `app/models/base.py` — all models must inherit from BaseModel
## Forbidden
- Any `print()` debugging statement
- `from x import *`
- Editing already-applied migration files under `migrations/`
A bad CLAUDE.md is full of project background, team size, and the history of why the stack was chosen. That may help humans, but it is noise for the model.
Keep CLAUDE.md under about 200 lines. If it grows beyond that, split the rest into child files and import them only when needed.
Use hooks to automate repeated reminders
Hooks are one of Claude Code’s strongest features, but many users never enable them. Hooks let you insert shell scripts before or after tool calls, turning repeated reminders such as “run tests,” “format after editing,” or “do not touch production config” into hard constraints.
~/.claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "if [[ $CLAUDE_FILE_PATHS == *.py ]]; then ruff format $CLAUDE_FILE_PATHS && ruff check --fix $CLAUDE_FILE_PATHS; fi"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|git push --force|drop database' && exit 1 || exit 0"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "if [[ $CLAUDE_FILE_PATHS == *.py ]]; then ruff format $CLAUDE_FILE_PATHS && ruff check --fix $CLAUDE_FILE_PATHS; fi"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|git push --force|drop database' && exit 1 || exit 0"
}
]
}
]
}
}
The first hook runs ruff format and ruff check --fix whenever Claude Code edits or writes a Python file.
The second hook blocks dangerous Bash commands such as rm -rf, git push --force, and drop database.
The benefit is simple: you no longer need to write “remember to run ruff” in every prompt, and the model cannot forget.
Turn repeated workflows into custom slash commands
If you do the same task five times per week, such as writing a changelog, generating API docs, or turning an issue into a PR description, make it a slash command.
Create .claude/commands/changelog.md:
---
description: Generate a CHANGELOG entry from recent git commits
---
Read all commits from the previous tag to HEAD using `git log <last-tag>..HEAD --oneline`.
Group them by feat / fix / chore / docs.
Append a new section using the existing format in CHANGELOG.md.
Requirements:
- Use today's date + the version from package.json as the heading
- For feat entries, explain what the user can now do; do not just paste commit messages
- Mark breaking changes separately with ⚠️
---
description: Generate a CHANGELOG entry from recent git commits
---
Read all commits from the previous tag to HEAD using `git log <last-tag>..HEAD --oneline`.
Group them by feat / fix / chore / docs.
Append a new section using the existing format in CHANGELOG.md.
Requirements:
- Use today's date + the version from package.json as the heading
- For feat entries, explain what the user can now do; do not just paste commit messages
- Mark breaking changes separately with ⚠️
After that, type /changelog in Claude Code to trigger the workflow without retyping the full instruction.
Slash commands can also accept arguments:
---
description: Write review comments for a specific PR
argument-hint: <pr-number>
---
Use `gh pr view $ARGUMENTS --json files,title,body` to fetch the PR content.
Review each item from review-checklist.md.
When you find an issue, post a comment with `gh pr review $ARGUMENTS --comment -b "..."`.
---
description: Write review comments for a specific PR
argument-hint: <pr-number>
---
Use `gh pr view $ARGUMENTS --json files,title,body` to fetch the PR content.
Review each item from review-checklist.md.
When you find an issue, post a comment with `gh pr review $ARGUMENTS --comment -b "..."`.
Call it with:
/review 1234
/review 1234
Use parallel subagents to compress independent work
Claude Code’s Agent tool can start multiple subagents at once. Each one gets its own independent context window and runs in parallel.
Good use cases include:
- Finding all call sites of one API across 5 different modules.
- Adding the same logging pattern to 10 service classes across a repository.
- Running code review, security analysis, and performance analysis as 3 independent passes.
The right way to trigger this is to ask for multiple Agent tasks in one response rather than serializing them. Claude Code can start them in parallel when you explicitly say the tasks are independent.
Please run the following three tasks at the same time, in parallel:
1. Under services/, find every place that calls `external_api.py`
2. Under tests/, find every test that mocks external_api
3. Under docs/, find every document that mentions external_api
Use one independent Agent task for each item, and start all three in parallel.
Please run the following three tasks at the same time, in parallel:
1. Under services/, find every place that calls `external_api.py`
2. Under tests/, find every test that mocks external_api
3. Under docs/, find every document that mentions external_api
Use one independent Agent task for each item, and start all three in parallel.
In practice, the same “research three independent areas in a large repository” task can go from about 90 seconds serially to about 30 seconds with three parallel subagents.
Use plan mode before complex edits
Complex changes fail most often when Claude Code starts editing while it is still discovering the shape of the codebase. Halfway through, the approach turns out wrong, but 8 files are already changed.
Use plan mode before important tasks. You can toggle it with Shift+Tab, or say: “Give me an implementation plan first. Do not edit code yet.”
Claude Code can then inspect the repository, propose an approach, and list steps. You approve the plan before it writes code.
Plan mode is especially useful for:
- Refactors touching more than 3 files.
- Introducing a new dependency or architecture pattern.
- Database migrations or API version changes.
- Areas of the codebase you do not know well.
Manage context in long sessions
Claude Code has a large context window, and Opus 4.7 supports 1M tokens, but that does not mean you should keep everything forever.
After very long sessions:
- Early unrelated discussion can pollute the model’s attention.
- Finding the most recent key decision gets slower.
- Token cost keeps accumulating.
Use three habits:
- Run
/clearafter finishing a subtask. Start the next task from a clean context. - Use
/compactfor long sessions. Claude summarizes the earlier conversation, preserving decisions while removing noise. - Put cross-session decisions in
CLAUDE.mdinstead of relying on “we decided X in the last session.”
Let Claude Code read issues, PRs, and logs directly
Claude Code is not only for editing code. When the source of a problem is a GitHub issue, a PR comment, or a log file, let it read the source directly instead of pasting snippets manually.
# Ask Claude to read the full issue
Use `gh issue view 456 --comments` to read the issue and all comments,
then tell me how we should fix it.
# Ask Claude to inspect the CI failure
The latest push failed CI. Use `gh run list -L 1` to find the run ID,
then use `gh run view <id> --log-failed` to read the failed logs and analyze the cause.
# Ask Claude to analyze production logs
Read the last 500 lines of `~/var/log/myapp/2026-05-27.log`.
Find every ERROR-level record and group them by frequency.
# Ask Claude to read the full issue
Use `gh issue view 456 --comments` to read the issue and all comments,
then tell me how we should fix it.
# Ask Claude to inspect the CI failure
The latest push failed CI. Use `gh run list -L 1` to find the run ID,
then use `gh run view <id> --log-failed` to read the failed logs and analyze the cause.
# Ask Claude to analyze production logs
Read the last 500 lines of `~/var/log/myapp/2026-05-27.log`.
Find every ERROR-level record and group them by frequency.
Direct source reading reduces missed context and avoids copy-paste drift.
Use /cost to make spending visible
The /cost command shows the accumulated cost for the current session. Build a habit around it:
- Run
/costbefore and after large tasks so you know what that task cost. - When context grows into hundreds of thousands of tokens, use it to spot the cost inflection point.
- For team workflows, session cost can help estimate the AI cost of a feature.
Pair /cost with /clear to set a practical upper bound on each session.
Capture team practices as Skills
Skills are reusable Claude Code capability packages. They are more structured than slash commands because they can include instructions, templates, and helper scripts.
For example, a team’s “create a new microservice” workflow can become a skill:
.claude/skills/new-microservice/
├── SKILL.md # description + trigger conditions
├── templates/
│ ├── pyproject.toml.tpl
│ ├── Dockerfile.tpl
│ └── main.py.tpl
└── scripts/
└── setup.sh
.claude/skills/new-microservice/
├── SKILL.md # description + trigger conditions
├── templates/
│ ├── pyproject.toml.tpl
│ ├── Dockerfile.tpl
│ └── main.py.tpl
└── scripts/
└── setup.sh
SKILL.md:
---
name: new-microservice
description: Create a company-standard microservice skeleton under services/, including a FastAPI entry point, Dockerfile, and CI template. Use this when the user says "create a new XX service" or "add a microservice."
---
Follow these steps:
1. Ask for the service name in kebab-case
2. Copy all templates under templates/ into services/<service-name>/ and replace placeholders
3. Run scripts/setup.sh to initialize dependencies
4. Add the matching CI file under .github/workflows/
---
name: new-microservice
description: Create a company-standard microservice skeleton under services/, including a FastAPI entry point, Dockerfile, and CI template. Use this when the user says "create a new XX service" or "add a microservice."
---
Follow these steps:
1. Ask for the service name in kebab-case
2. Copy all templates under templates/ into services/<service-name>/ and replace placeholders
3. Run scripts/setup.sh to initialize dependencies
4. Add the matching CI file under .github/workflows/
After that, anyone on the team can say “create an order lookup service,” and Claude Code will trigger the skill and generate the service using the same standard structure.
Layer models by task difficulty
Not every task needs Opus 4.7. Claude Code supports manual model switching with /model.
| Task type | Recommended model | Why |
|---|---|---|
| Complex refactors, architecture design, logic across many files | claude-opus-4-7 |
Strongest reasoning |
| New features, bug fixes, single-file code changes | claude-sonnet-4-6 |
About 5x faster, with enough quality for most work |
| Simple search, documentation, commit messages | claude-haiku-4-5-20251001 |
About 1/20 the cost, with fast responses |
Set Sonnet 4.6 as the default in settings.json, then switch to Opus only for hard problems. This can reduce monthly cost by more than 60%.
{
"env": {
"ANTHROPIC_MODEL": "claude-sonnet-4-6"
}
}
{
"env": {
"ANTHROPIC_MODEL": "claude-sonnet-4-6"
}
}
Configure permissions to reduce prompts while keeping safety
Claude Code asks for authorization on many Bash commands and file writes by default. Frequent prompts interrupt flow.
~/.claude/settings.json:
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(gh issue view *)",
"Bash(gh pr view *)",
"Bash(pytest *)",
"Read(**)",
"Edit(src/**)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(curl * | sh)",
"Edit(.env*)",
"Edit(secrets/**)"
]
}
}
{
"permissions": {
"allow": [
"Bash(npm test)",
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(gh issue view *)",
"Bash(gh pr view *)",
"Bash(pytest *)",
"Read(**)",
"Edit(src/**)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(curl * | sh)",
"Edit(.env*)",
"Edit(secrets/**)"
]
}
}
Allow frequent safe actions such as reading files, running tests, and inspecting git state. Deny dangerous actions such as recursive deletion, force-pushes, shell-piped installers, .env edits, and secrets edits.
Use a stable gateway to remove network as a variable
Direct Anthropic API calls can sometimes run into connection interruptions, stalled responses, or cross-region latency swings depending on the runtime environment. For Claude Code, that matters because the session is stateful; recovering from a mid-conversation interruption can be expensive.
You can point Claude Code at ClaudeAPI’s gateway endpoint. The interface is compatible with the Anthropic SDK, so Claude Code can use it transparently.
# macOS / Linux
export ANTHROPIC_AUTH_TOKEN="sk-your-ClaudeAPI-key"
export ANTHROPIC_BASE_URL="https://gw.claudeapi.com"
# macOS / Linux
export ANTHROPIC_AUTH_TOKEN="sk-your-ClaudeAPI-key"
export ANTHROPIC_BASE_URL="https://gw.claudeapi.com"
# Windows PowerShell (persistent)
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "sk-your-ClaudeAPI-key", "User")
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://gw.claudeapi.com", "User")
# Windows PowerShell (persistent)
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "sk-your-ClaudeAPI-key", "User")
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://gw.claudeapi.com", "User")
Or add it to settings.json:
{
"env": {
"ANTHROPIC_AUTH_TOKEN": "sk-your-ClaudeAPI-key",
"ANTHROPIC_BASE_URL": "https://gw.claudeapi.com",
"ANTHROPIC_MODEL": "claude-sonnet-4-6"
}
}
{
"env": {
"ANTHROPIC_AUTH_TOKEN": "sk-your-ClaudeAPI-key",
"ANTHROPIC_BASE_URL": "https://gw.claudeapi.com",
"ANTHROPIC_MODEL": "claude-sonnet-4-6"
}
}
After this, Claude Code starts through the configured gateway endpoint, so you do not need to debug timeout settings as a separate variable. The ClaudeAPI console provides session-level usage details. Used together with /cost, it helps teams see the actual Claude Code cost for each project and developer.
Summary
Claude Code is not a “install it and forget it” tool. Spend half a day configuring CLAUDE.md, hooks, custom slash commands, and permissions, and the next few months of output will look very different from an unconfigured setup.
The three highest-priority changes are:
- Write a concise but specific
CLAUDE.md, and keep it under 200 lines. - Enable hooks for automatic formatting and dangerous-command blocking.
- Set the default model to Sonnet 4.6, and switch to Opus 4.7 only for hard problems.
Get started
Use ClaudeAPI when you need stable Claude Code access through an Anthropic-compatible gateway, with clear billing, usage visibility, Stripe and major credit card payments, and enterprise invoicing available.



