How to save Claude Code tokens

Every command Claude Code runs in the terminal consumes tokens. A verbose git status, test logs with hundreds of lines, full directory listings — all go straight into the model context. rtk is a CLI proxy that filters and compresses command output before it reaches the LLM, reducing consumption by 60-90%.

The problem

Claude Code uses the Bash tool to interact with your project. Every raw command output — whitespace, metadata, boilerplate — is counted as tokens. On a medium TypeScript project, a 30-minute session consumes around 118,000 tokens from shell commands alone.

Tokens wasted on output noise are cost without value. Claude doesn't need 3,000 tokens of git status when 200 tokens with the relevant information are enough.

git status3,000 tokensraw output
npm test25,000 tokensfull logs
cat file.ts40,000 tokensentire file

How it works

rtk acts as a transparent proxy between Claude and the shell. The installed hook automatically rewrites Bash commands — git status becomes rtk git status — before execution. Claude never sees the rewrite, it just gets compressed output.

Without rtkgit status
~3,000 tokens
With rtkgit status → rtk git status
~200 tokens

Four strategies are applied per command type: smart filtering (removes noise, comments, boilerplate), grouping (aggregates similar items), truncation (keeps relevant context), and deduplication (collapses repeated log lines with counts).

Installation

The simplest way is via Homebrew. For Linux or without brew, there's a curl installer:

# macOS (recommended)
brew install rtk

# Linux / macOS via curl
curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh

# verify
rtk --version
rtk gain       # shows token savings stats

Setup

After installing, run rtk init -g to configure the hook in Claude Code:

# configure the hook for Claude Code
rtk init -g

# restart Claude Code, then test
git status  # automatically rewritten to rtk git status

Restart Claude Code. From then on, commands like git status are automatically rewritten and filtered with no changes to your workflow.

Token savings

Estimates on a medium TypeScript/Rust project, 30-minute session:

git status3,000600-80%
git diff10,0002,500-75%
cat / read40,00012,000-70%
grep / rg16,0003,200-80%
npm/cargo test25,0002,500-90%
Total~118,000~23,900-80%

Key commands

The most commonly used commands in daily development — all with output automatically compressed via hook:

# git — compact output for all operations
rtk git status           # grouped changed files
rtk git log -n 10        # one-line commits
rtk git diff             # condensed diff
rtk git commit -m "msg"  # returns "ok abc1234"
rtk git push             # returns "ok main"

# files — filtered and truncated
rtk ls .                 # token-optimized directory tree
rtk read file.ts         # smart file reading
rtk grep "pattern" .     # grouped search results

# tests — failures only
rtk npm test
rtk cargo test           # -90% vs raw output
rtk pytest

Native tools

The hook only runs on Bash tool calls. Claude Code's native tools like Read, Grep, and Glob don't pass through the hook. For those, use shell commands (cat, rg, find) or call rtk directly:

# use shell commands instead of native Claude Code tools
# so the hook (and rtk) can intercept them

cat file.ts      # triggers rtk read via hook
rg "pattern" .   # triggers rtk grep via hook
find . -name "*.ts"  # triggers rtk find via hook

# or call rtk directly
rtk read file.ts
rtk grep "pattern" .
rtk find "*.ts" .

More

rtk is open-source under the MIT license. Single Rust binary, zero dependencies, under 10ms overhead. Code and docs at github.com/rtk-ai/rtk.