| name | clojure-review |
| description | Review Clojure and ClojureScript code changes for compliance with Metabase coding standards, style violations, and code quality issues. Use when reviewing pull requests or diffs containing Clojure/ClojureScript code. |
| allowed-tools | Read, Grep, Bash, Glob |
Clojure Code Review Skill
@./../_shared/clojure-style-guide.md
@./../_shared/clojure-commands.md
Review guidelines
What to flag:
- Check compliance with the Metabase Clojure style guide (included above)
- If
CLOJURE_STYLE_GUIDE.adoc exists in the working directory, also check compliance with the community Clojure style guide
- Flag all style guide violations
What NOT to post:
- Do not post comments congratulating someone for trivial changes or for following style guidelines
- Do not post comments confirming things "look good" or telling them they did something correctly
- Only post comments about style violations or potential issues
Example bad code review comments to avoid:
This TODO comment is properly formatted with author and date - nice work!
Good addition of limit 1 to the query - this makes the test more efficient without changing its behavior.
The kondo ignore comment is appropriately placed here
Test name properly ends with -test as required by the style guide.
Special cases:
- Do not post comments about missing parentheses (these will be caught by the linter)
Quick review checklist
Use this to scan through changes efficiently:
Naming
Documentation
Docstring content — check every new or rewritten docstring against the anti-pattern table in the
style guide above. Read the diff's docstrings on their own, separately from the code: prose is
where review attention slides off, and a long docstring reads as diligence rather than as the
liability it usually is.
Code Organization
Tests
Modules
REST API
MBQL
Database
Drivers
Miscellaneous
Pattern matching table
Quick scan for common issues:
| Pattern | Issue |
|---|
calculate-age, get-user | Pure functions should be nouns: age, user |
update-db, save-model | Missing ! for side effects: update-db!, save-model! |
snake_case_var | Should use kebab-case |
| Public var without docstring | Add docstring explaining purpose |
;; TODO fix this | Missing author/date: ;; TODO (Name 2025-01-01) -- description |
(defn foo ...) in namespace used elsewhere | Should be (defn ^:private foo ...) |
| Function > 20 lines | Consider breaking up into smaller functions |
/api/dashboards/:id | Use singular: /api/dashboard/:id |
Query params with snake_case | Use kebab-case for query params |
| New API endpoint without tests | Add tests for the endpoint |
Feedback format examples
For style violations:
This pure function should be named as a noun describing its return value. Consider user instead of get-user.
For missing documentation:
This public var needs a docstring explaining its purpose, inputs, and outputs.
For docstrings documenting code they don't own:
This describes how lib decides binning strategies internally. Nothing here fails when that
changes, so it will go stale silently — drop it and let available-binning-strategies answer
for its own behavior.
For docstring content that belongs in the body:
This paragraph explains why the branches are ordered this way, which is what someone editing
the cond needs — but a caller can't act on it. Move it to an inline comment above the cond.
For organization issues:
This function is only used in this namespace, so it should be marked ^:private.
For API conventions:
Query parameters should use kebab-case. Change user_id to user-id.