Skip to content

Instantly share code, notes, and snippets.

@dcj
Created April 15, 2026 00:03
Show Gist options
  • Select an option

  • Save dcj/b0bb18a44b11eea3ebfab647c12c73a2 to your computer and use it in GitHub Desktop.

Select an option

Save dcj/b0bb18a44b11eea3ebfab647c12c73a2 to your computer and use it in GitHub Desktop.
Claude Code slash command for clj-xref: AI-driven Clojure cross-reference queries

Cross-reference Clojure code with clj-xref

Query the cross-reference database for the current Clojure project. Built on clj-kondo static analysis.

How to run

/xref init                          — generate/regenerate the xref database
/xref who-calls ns/fn               — who calls this function?
/xref calls-who ns/fn               — what does this function call?
/xref who-implements ns/Protocol     — who implements this protocol?
/xref unused                        — find dead code (defined but never referenced)
/xref ns-deps ns                    — what namespaces does this one depend on?
/xref ns-dependents ns              — what namespaces depend on this one?
/xref apropos pattern               — search for vars matching a name pattern
/xref graph ns/fn                   — show transitive call graph

Instructions

Initialization (if arg is "init")

Generate the xref database:

JENV_VERSION=21 clj -T:xref generate

This uses the global :xref alias from ~/.clojure/deps.edn and produces .clj-xref/xref.edn.

Ensure .clj-xref/ is in .gitignore (the database is generated, not committed).

If .clj-xref/xref.edn doesn't exist when a query is requested, run init automatically first.

Queries

For all query commands, run via the global :xref alias:

JENV_VERSION=21 clojure -M:xref -e '
(require (quote [clj-xref.core :as xref]))
(def db (xref/load-db))
;; ... query here ...
'

who-calls

(doseq [r (xref/who-calls db (quote <fully-qualified-sym>))]
  (println (format "  %s (%s:%d)" (:from r) (:file r) (:line r))))

Report each caller with its file and line number.

calls-who

(doseq [r (xref/calls-who db (quote <fully-qualified-sym>))]
  (println (format "  %s (%s:%d)" (:to r) (:file r) (:line r))))

unused

(xref/unused-vars db)

Report unused vars. Note: defrecord constructors (->Foo, map->Foo), -main, and test functions will show as "unused" because they're entry points called externally — filter these out when reporting.

ns-deps / ns-dependents

(xref/ns-deps db (quote <ns-sym>))
(xref/ns-dependents db (quote <ns-sym>))

apropos

(xref/apropos db #"<pattern>")

graph

(xref/call-graph db (quote <fully-qualified-sym>) {:depth 3 :direction :outgoing})

Report as a set of [from to] edges.

Using xref for your own work

When working on code changes in this session, use xref proactively:

  • Before changing a function signature: run who-calls to find all callers that need updating
  • Before understanding unfamiliar code: run calls-who to see dependencies
  • After refactoring: regenerate with clj -T:xref generate :only '["path/to/changed/file.clj"]' for incremental update

Regenerating after edits

After significant code changes, regenerate the database:

JENV_VERSION=21 clj -T:xref generate

Or incrementally for specific files:

JENV_VERSION=21 clj -T:xref generate :only '["src/path/to/file.clj"]'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment