Efficiency hacks for daily Claude Code work
Claude Code efficiency hacks are repeatable habits that cut wasted turns and tokens: one task per session with /rename and /clear, scoped file reads, lower effort for mechanical work, shell helpers built on claude -p, and JSON output for scripts. The rule that binds them: none may remove the test gate that proves the result.
This page is for developers who already use Claude Code every day. You know the symptoms: a session that started as a bug fix is now three tasks deep, every answer takes longer, Claude reads dist/ before touching the one file you named, and you retype the same “review this diff” prompt ten times a week. The fixes below take minutes to set up and pay back on every task.
What you get from these Claude Code habits
Section titled “What you get from these Claude Code habits”- A measured baseline, so you know whether a hack helped or only felt faster.
- A session routine that keeps context small without losing work: name, hand off, clear, resume.
- Permission rules and
CLAUDE.mdlines that stop Claude reading generated files and over-summarising. - Six shell helpers that do not shadow real commands and do not need approvals they cannot get.
- A
/rev-stagedskill that replaces a review prompt you retype every week. - Scriptable output with
--output-format jsonand--json-schema, checked byjq -einstead of by eye. - A verification rule that keeps targeted tests fast during iteration and the full gate before “done”.
How do you know an efficiency hack worked?
Section titled “How do you know an efficiency hack worked?”Measure before you change anything. Two built-in commands give you the numbers (checked on Claude Code 2.1.283):
| Command | What it shows | Use it to |
|---|---|---|
/context | Current context use as a coloured grid (/context all for detail) | See how much of the window is CLAUDE.md, MCP tool definitions, file reads and conversation |
/usage | Session cost, plan limits and activity stats (/cost and /stats are aliases) | Compare the cost of the same kind of task before and after a change |
Run /context at the start of a fresh session and again after a typical task. If a large share of the window is taken before you type anything, the fix is a shorter CLAUDE.md or fewer MCP servers, not a cleverer prompt — see pruning CLAUDE.md and AGENTS.md. Team-level spend tracking belongs on the cost control page.
Which habit should you adopt first?
Section titled “Which habit should you adopt first?”Order matters: each step makes the next one measurable, and the gate goes in before any hack that reduces checking.
| Order | Habit | Set-up | Why this position |
|---|---|---|---|
| 1 | Baseline with /context and /usage | two commands | Without it you cannot tell a real saving from a feeling |
| 2 | Test gate in CLAUDE.md | three lines | Every later hack reduces work; this keeps the proof |
| 3 | One task per session | a routine, no config | The biggest context saving, and free |
| 4 | Deny rules for generated files | one settings file | Enforced, so it keeps working when a prompt forgets |
| 5 | Effort and output style | one command | Cheap to try, and easy to undo per task |
| 6 | Shell helpers, skills and JSON output | a shell profile edit, one SKILL.md | Pays back only once you repeat the task weekly |
Keep one task per session
Section titled “Keep one task per session”Stale context from the previous task makes every later turn slower and more expensive, and it pulls irrelevant files into Claude’s reasoning. The routine below keeps each session to one task without losing anything.
-
Name the session when you start it. Start with
claude -n payment-retry, or run/rename payment-retryinside a running session. The name appears in the/resumepicker and the terminal title. -
Ask side questions with
/btw./btw what does the retry decorator in src/lib/http.ts do?answers without interrupting the main conversation, so a quick lookup does not become part of the task’s context. -
Write a handoff note before you switch. Use the handoff prompt below. The note survives any later
/compactor/clear, and it is the input for the next session. -
Run
/clear. It starts a new session with empty context. The previous session stays on disk and you can reopen it from/resume. -
Resume by name when you come back.
claude -r payment-retryopens the resume picker filtered by that search term;claude -ccontinues the most recent session in the current directory.
When you must stay in one long session, compact with explicit instructions instead of waiting for automatic compaction:
/compact Keep: files I edited, the failing test names and their last output, decisions and why. Drop: exploratory file reads, rejected approaches, command output already summarised.To avoid retyping that, add a standing rule to CLAUDE.md; the summariser reads it along with the rest of the conversation. The cost control page uses the same pattern:
# Compact instructionsWhen compacting, preserve test output, error traces, file paths you changed and decisions with their reasons.Summarise discussion. Drop exploratory reads that led to no change.In the new session, start with: Read .claude/handoff.md, run the proving command first, and tell me if the result differs from the note before you continue. Add .claude/handoff.md to .git/info/exclude if you do not want it committed. If you would rather install a ready-made handoff routine than keep this prompt, see skills for context and token discipline.
Stop Claude reading what it does not need
Section titled “Stop Claude reading what it does not need”Claude Code explores before it edits, which is right for unfamiliar work and wasteful for a named bug. Scope the task in the prompt, and fence off generated files in settings so the rule holds even when a prompt forgets.
Fence generated files with permission rules. A Read(...) deny rule in .claude/settings.json stops the file tools from opening those paths; the same file can be committed so the whole team gets it:
{ "permissions": { "deny": [ "Read(./dist/**)", "Read(./build/**)", "Read(./coverage/**)", "Read(./package-lock.json)" ] }}A deny rule is enforced; a CLAUDE.md line such as “never read dist/” is only guidance. Use the rule for anything you never want in context, and keep CLAUDE.md for behaviour. See memory and CLAUDE.md for where each instruction belongs.
Cut the closing summary. Run /output-style and choose Concise (one of the four built-in styles), or add one line to CLAUDE.md:
After a change, do not summarise it. Show the changed file paths and the test command you ran with its result.Match effort to the task. Claude Opus 5.5, the Claude Code default from v2.1.280 on the latest release channel, runs at medium effort (the stable channel still starts on an older default; /model shows what you have). Drop to low for mechanical edits (renames, formatting, boilerplate) with /effort low or claude --effort low, and raise it to high when Claude misses something, before you consider another model. The models hub lists the current models and when to change.
Shell helpers that save keystrokes safely
Section titled “Shell helpers that save keystrokes safely”Two details decide whether a helper saves time or causes trouble. First, prefix every name: the popular alias cc='claude -c' shadows the C compiler in your shell. Second, a claude -p run starts in Manual permission mode with nobody to approve an edit, so one-shot helpers stay read-only and anything that writes files opens an interactive session.
# ~/.zshrc or ~/.bashrc — every name starts with "cl" so nothing shadows a real commandalias clq='claude -p' # one-shot, read-only questionalias clc='claude -c' # continue the latest session in this directoryalias clr='claude -r' # resume picker; clr payment-retry filters by name
# Review the staged diff; reports only, never editsclrev() { git diff --cached | claude -p "Review this staged diff. Report only bugs, security issues and missing tests, each with file:line. If there are none, reply 'No findings' and nothing else."}
# Explain a file and its blast radiusclexplain() { claude -p "Explain what $1 does, which modules call it, and what breaks if its exported functions change. Read only $1 and the files that import it."}
# Write tests: interactive, because it edits files and runs themcltest() { claude -n "tests-$(basename "$1")" "Write tests for $1 following the nearest existing test file. Run them and show me the output."}Before you add them, run type clq clc clr clrev clexplain cltest and confirm each prints “not found”. Piping build and test output into Claude is covered on the terminal mastery page.
Turn a prompt you retype into a skill
Section titled “Turn a prompt you retype into a skill”A shell helper works outside a session; inside one, the same prompt belongs in a skill. Save the file below as .claude/skills/rev-staged/SKILL.md and commit it, and every teammate gets /rev-staged with the same wording (skill format checked against Claude Code 2.1.283):
---description: Review the staged diff for bugs, security issues and missing testsdisable-model-invocation: trueallowed-tools: Bash(git diff *)---Review this staged diff. Report only bugs, security issues and missing tests,each with file:line. If there are none, reply "No findings" and nothing else.
!`git diff --cached`Three lines decide how it behaves:
- The
!`git diff --cached`line runs before Claude sees the skill, so the diff arrives inlined and Claude spends no turn fetching it. disable-model-invocation: truemeans only you can trigger it, and it keeps the skill out of Claude’s context until you do, so it costs no tokens in sessions that never use it.allowed-toolspre-approves the injectedgit difffor that one invocation; without it, the injection can stop and wait for approval.
Frontmatter mistakes fail silently, which is why custom commands and skills adds a CI lint for skill files. Use a skill when the prompt runs inside a session and a shell helper when you want an answer without opening one.
Get output a script can trust
Section titled “Get output a script can trust”When Claude’s answer feeds another command, ask for JSON and check its shape mechanically. --output-format works only with -p.
# Plain answer as a string: read .resultclaude -p "List every HTTP route in src/api with its method and handler file, one per line." \ --output-format json | jq -r '.result'For fields you can rely on, add --json-schema. The validated object lands in structured_output, next to the run metadata:
claude -p "Find source files in src/api that have no matching test file." \ --output-format json \ --max-budget-usd 1 \ --json-schema '{"type":"object","properties":{"untested":{"type":"array","items":{"type":"string"}}},"required":["untested"]}' \ > untested.json
jq -e '.structured_output.untested | type == "array"' untested.json >/dev/null \ && jq -r '.structured_output.untested[]' untested.jsonjq -e exits non-zero when the check fails, so a script stops instead of acting on a malformed answer. --max-budget-usd caps what a runaway print-mode run can spend, and the same JSON carries total_cost_usd if you want to log it. For CI jobs and larger pipelines, go to Claude Code automation.
Keep the gate that proves the result
Section titled “Keep the gate that proves the result”The most tempting hack is to stop running tests. Do it only in the shape below: targeted tests while iterating, the full gate before anything is called done. Then you verify behaviour from test output rather than by reading every changed line.
# Test scope (CLAUDE.md)- While iterating, run only the tests for files you changed: npx vitest run <path>- Before you say a task is done, run: npm run typecheck && npm run lint && npm test- Report each command with its exit status. Never call a task done with a failing or skipped test.Three layers back that rule up:
- A
Stophook can run the gate automatically when Claude finishes a turn, so the rule no longer depends on the model remembering it. See hooks automation. /code-reviewbefore you commit gives a second pass focused on bugs, not style. See review automation.- CI runs the same commands, so a local shortcut can never be the last check.
Quick wins from the command line
Section titled “Quick wins from the command line”All flags below are from claude --help on version 2.1.283.
# Give Claude tool access to a sibling repository in the same sessionclaude --add-dir ../shared-components
# Fall back to other models when the primary is overloaded or unavailableclaude --model opus --fallback-model sonnet
# Resume the session linked to pull request 123 (or pick from linked sessions)claude --from-pr 123--fallback-model accepts a comma-separated list and retries the primary model at the start of each user turn, so a fallback lasts one turn, not the whole session. If a fallback turn produced a weaker answer, rerun that step once the primary is back. More flags and commands are collected on features you have not tried and slash commands mastery.
When Claude Code efficiency hacks backfire
Section titled “When Claude Code efficiency hacks backfire”| Symptom | Cause | Recovery |
|---|---|---|
cc (or another short alias) runs Claude instead of the tool you expected | The alias shadows an existing command | unalias cc, rename helpers with a unique prefix, check with type |
| A helper prints nothing useful or says it could not edit | claude -p starts in Manual mode and cannot get approval | Keep -p helpers read-only; run editing helpers interactively |
| You cleared the wrong session | /clear was run before the handoff | /resume and pick the old session by name; /rewind can also restore from before /clear |
After /compact, Claude forgets a decision or re-reads files | The summary dropped it | Restate it once, then add it to your compact instructions or the handoff note |
| Claude edits without reading callers and breaks them | Scope rules are too tight for the task | Widen the prompt for this task (“read callers of formatInvoiceTotal”); keep deny rules for generated files only |
| Targeted tests pass, CI fails | A change broke code outside the tested path | Keep the full gate in CLAUDE.md and a Stop hook; never let the targeted rule become the only rule |
/rev-staged does not appear, or Claude runs it unasked | The frontmatter is misspelt or the opening --- is not on line 1, so Claude Code ignores it | Fix the file, restart the session, and add the skill lint from custom commands and skills |
| A script acted on a half-formed answer | Output parsed without a schema | Add --json-schema and a jq -e check before the next command |
Where to go next with Claude Code efficiency
Section titled “Where to go next with Claude Code efficiency”- Prerequisite: configure Claude Code so settings and
CLAUDE.mdare in place. - Next: terminal mastery for layout, piping and multi-session work.
- Context in depth: understanding context windows.
- Spend at team scale: cost control.
- The same habits in Codex: Codex efficiency hacks.