DEV Community

Mirzalazuardi
Mirzalazuardi

Posted on

I Built a Bash Script That Traces Code Faster Than Your IDE (And Saves AI Tokens)

You're debugging a Rails app. The bug is somewhere in process_payment. You could:

A) Open your IDE, wait for LSP to index, click through 12 files.

B) Paste the whole service into ChatGPT. Hope it doesn't hallucinate the call graph.

C) Run one command:

codetracer process_payment . --mode flow --scope
Enter fullscreen mode Exit fullscreen mode

In under a second: where it's defined, every call site with enclosing method, every assignment, every place the return value goes — across all files.

I chose option C. So I built it.


What is codetracer?

A single-file bash script (~1400 lines) that traces symbols across Ruby and JavaScript/TypeScript codebases. No IDE, no LSP, no AI agent.

Requirements: bash 4+ (or zsh 5+) and ripgrep. That's it.

# Install
curl -fsSL https://raw.githubusercontent.com/mirzalazuardi/codetracer/main/codetracer.sh \
  -o /usr/local/bin/codetracer && chmod +x /usr/local/bin/codetracer
Enter fullscreen mode Exit fullscreen mode

The Killer Feature: Case-Variant Expansion

Type a symbol in any naming convention. codetracer finds all forms automatically:

Input: processPayment

Searches simultaneously:
  process_payment      (snake_case)
  PROCESS_PAYMENT      (SCREAMING_SNAKE)
  processPayment       (camelCase)
  ProcessPayment       (PascalCase)
  process-payment      (kebab-case)
Enter fullscreen mode Exit fullscreen mode

All these commands produce identical results:

codetracer process_payment
codetracer processPayment
codetracer ProcessPayment
Enter fullscreen mode Exit fullscreen mode

No more "I searched for process_payment but the JS file uses processPayment" moments.


Five Modes for Different Questions

1. Where is it defined?

codetracer PaymentService . --mode def
Enter fullscreen mode Exit fullscreen mode

Finds def, class, module, function, const =, async function, etc.

2. Who calls it?

codetracer send_email . --mode call --scope
Enter fullscreen mode Exit fullscreen mode

Every call site with full scope chain:

app/services/order_service.rb:42:    send_email(user, receipt)
  scope -> mod Billing > cls OrderService > def complete_order:38
Enter fullscreen mode Exit fullscreen mode

3. How does data flow?

codetracer current_user . --mode flow
Enter fullscreen mode Exit fullscreen mode

Tracks: assignments, passed as argument, returned/yielded, mutations.

4. Which files touch it?

codetracer stripe_key . --mode file
Enter fullscreen mode Exit fullscreen mode

File map with hit counts per file.

5. Everything at once

codetracer order_total . --mode full --scope
Enter fullscreen mode Exit fullscreen mode

NEW: Rails Route Tracing

Just shipped this week. Trace a route through the full request lifecycle:

codetracer --action "OrdersController#refund" ./app
Enter fullscreen mode Exit fullscreen mode

Output:

━━━ ROUTE TRACE: OrdersController#refund ━━━

OrdersController (app/controllers/orders_controller.rb)
├── before_action :authenticate_user!          :23  [ApplicationController]
├── before_action :set_order                   :8
├── def refund                                 :67
│   ├── params: :reason                        :68  [query]
│   ├── if @order.refundable?                  :69
│   │   ├── call: RefundService.call           :70
│   │   └── enqueue: RefundNotificationJob     :75  [async]
│   └── else                                   :77
│       └── render json: errors                :78
└── after_action :log_refund_attempt           :10
Enter fullscreen mode Exit fullscreen mode

Callbacks, conditionals, params access, service calls, Sidekiq jobs — all in one tree. Perfect for understanding unfamiliar Rails controllers or creating sequence diagrams.

Trace directly from your curl files

Got a directory of curl scripts for testing your API? Point codetracer at them:

# Your existing curl file
cat api_tests/refund.sh
Enter fullscreen mode Exit fullscreen mode
curl -X POST "http://localhost:3000/orders/123/refund?notify=true" \
  -H "Content-Type: application/json" \
  -d '{"reason": "damaged", "amount": 50.00}'
Enter fullscreen mode Exit fullscreen mode
# Trace it
codetracer --route api_tests/refund.sh ./app
Enter fullscreen mode Exit fullscreen mode

codetracer automatically:

  • Extracts the HTTP verb (POST) and path (/orders/:id/refund)
  • Converts numeric IDs to :id (123 → :id)
  • Extracts query params (notify) and JSON body keys (reason, amount)
  • Shows expected params in the trace output
Expected params from curl:
  query: notify
  body: reason amount

├── def refund
    ├── params: :reason    [query]  ← matches!
Enter fullscreen mode Exit fullscreen mode

No more wondering "does this endpoint actually use the params I'm sending?"


Why Not Just Use AI?

I use AI daily. But every question you ask about code structure — "where is this defined?", "who calls this?" — costs tokens, takes seconds, and might be wrong.

codetracer gives those answers instantly, deterministically, for free.

Save Tokens When You Do Use AI

Instead of pasting 500-line files, extract only what matters:

# Get 60 focused lines instead of 2000+ raw lines
codetracer process_payment . --mode flow --scope 2>&1 | head -60
Enter fullscreen mode Exit fullscreen mode

That's a 30x reduction in tokens.


The Scope Chain

This is my favorite feature. Every match shows its full nesting context:

codetracer process_payment . --mode call --scope
Enter fullscreen mode Exit fullscreen mode
fixture_payment_service.rb:40:        process_payment(order, order.amount)
  scope -> mod Billing:5 > cls PaymentService:6 > def batch_process:38 > blk each:39
Enter fullscreen mode Exit fullscreen mode

You instantly know: this call happens inside an each block, inside batch_process method, inside PaymentService class, inside Billing module.

No clicking through files. No mental stack tracing.


Works on macOS and Linux

Tested on:

  • macOS with bash 4+ or zsh 5+
  • Ubuntu/Debian
  • Arch Linux
# macOS
brew install ripgrep

# Ubuntu
sudo apt install ripgrep

# Optional: fzf for interactive mode, ctags for precise indexing
brew install fzf universal-ctags
Enter fullscreen mode Exit fullscreen mode

Interactive Mode with fzf

codetracer render . --inter
Enter fullscreen mode Exit fullscreen mode

Fuzzy-pick any match, preview context, press Enter to open in your editor.


Real Workflow Example

Debugging an unknown bug:

# 1. Where does this symbol exist?
codetracer process_payment . --mode file

# 2. Read the definition
codetracer process_payment . --mode def --ctags

# 3. Find callers and their context
codetracer process_payment . --mode call --scope

# 4. Trace data through the system
codetracer process_payment . --mode flow --scope --ctx 4
Enter fullscreen mode Exit fullscreen mode

Four commands. Full picture. No IDE required.


Try It

# One-liner install
curl -fsSL https://raw.githubusercontent.com/mirzalazuardi/codetracer/main/codetracer.sh \
  -o /usr/local/bin/codetracer && chmod +x /usr/local/bin/codetracer

# Try it
codetracer YourClassName ./your-project --mode def
Enter fullscreen mode Exit fullscreen mode

Links

GitHub: github.com/mirzalazuardi/codetracer

If this looks useful, I'd appreciate a star. And if you have feature requests or find bugs, issues and PRs are welcome.


Built for engineers who prefer a terminal over a GUI and a shell script over a language server.

Top comments (0)