Files
2025-11-29 18:47:15 +08:00

7.1 KiB

clj-kondo Skill

A comprehensive skill for using clj-kondo, the fast and accurate Clojure linter, including guidance on writing custom hooks for domain-specific linting rules.

Contents

  • SKILL.md - Complete documentation covering usage, configuration, built-in linters, and custom hooks
  • QUICK_REFERENCE.md - Quick reference for common configurations and hook patterns
  • INDEX.md - Navigation guide and learning path
  • examples.clj - Runnable hook examples

What is clj-kondo?

clj-kondo is a static analyzer and linter for Clojure that provides:

  • Fast, native binary with instant startup
  • Comprehensive built-in linting rules
  • Custom hooks for domain-specific linting
  • Zero configuration required (but highly customizable)
  • IDE integration (VS Code, Emacs, IntelliJ, Vim)
  • CI/CD ready
  • Cross-platform support (Linux, macOS, Windows)

Quick Start

Installation

# macOS/Linux
brew install clj-kondo/brew/clj-kondo

# Manual installation
curl -sLO https://raw.githubusercontent.com/clj-kondo/clj-kondo/master/script/install-clj-kondo
chmod +x install-clj-kondo
./install-clj-kondo

Basic Usage

# Lint a file
clj-kondo --lint src/myapp/core.clj

# Lint a directory
clj-kondo --lint src

# Lint with JSON output
clj-kondo --lint src --config '{:output {:format :json}}'

Configuration

Create .clj-kondo/config.edn:

{:linters {:unused-binding {:level :warning}
           :unused-namespace {:level :warning}
           :unresolved-symbol {:level :error}}
 :output {:pattern "{{LEVEL}} {{filename}}:{{row}}:{{col}} {{message}}"}}

Creating Your First Hook

  1. Create hook file at .clj-kondo/hooks/my_hooks.clj:
(ns hooks.my-hooks
  (:require [clj-kondo.hooks-api :as api]))

(defn deprecation-warning [{:keys [node]}]
  {:findings [{:message "This function is deprecated"
               :type :deprecated-api
               :row (api/row node)
               :col (api/col node)
               :level :warning}]})
  1. Register hook in .clj-kondo/config.edn:
{:hooks {:analyze-call {mylib/old-fn hooks.my-hooks/deprecation-warning}}}
  1. Test it:
clj-kondo --lint src

What This Skill Covers

Basic Usage

  • Installation and setup
  • Command-line usage
  • Output formats
  • Cache management

Configuration

  • Configuration file structure
  • Linter levels and options
  • Local and global configuration
  • Inline suppressions
  • Configuration merging

Built-in Linters

  • Namespace and require linters
  • Binding and symbol linters
  • Function and arity linters
  • Collection and syntax linters
  • Type checking linters

Custom Hooks (Advanced)

  • What hooks are and when to use them
  • Hook architecture and API
  • :analyze-call hooks for custom warnings
  • :macroexpand hooks for DSL support
  • Node API reference
  • Practical hook examples:
    • Deprecation warnings
    • Argument validation
    • DSL expansion
    • Thread-safety checks
    • Required keys validation
  • Testing hooks
  • Distributing hooks with libraries

Integration

  • IDE setup (VS Code, Emacs, IntelliJ, Vim)
  • CI/CD integration (GitHub Actions, GitLab CI)
  • Pre-commit hooks

Best Practices

  • Team configuration
  • Gradual adoption for legacy code
  • Performance optimization
  • Thoughtful suppression

Key Features Covered

Built-in Linting

  • Unused bindings and namespaces
  • Unresolved symbols
  • Invalid function arities
  • Duplicate map/set keys
  • Type mismatches
  • Syntax errors
  • Code style issues

Custom Hooks

  • API deprecation warnings
  • Domain-specific validations
  • Custom DSL support
  • Team convention enforcement
  • Advanced static analysis

Developer Experience

  • Real-time IDE feedback
  • Minimal configuration
  • Fast performance
  • Clear error messages
  • Extensibility

Common Use Cases

1. Basic Project Linting

# Initial setup
cd my-project
clj-kondo --lint "$(clojure -Spath)" --dependencies --parallel --copy-configs

# Regular linting
clj-kondo --lint src test

2. Deprecation Warnings

Create hooks to warn about deprecated APIs:

;; .clj-kondo/hooks/deprecation.clj
(defn warn-old-api [{:keys [node]}]
  {:findings [{:message "Use new-api instead"
               :level :warning
               :row (api/row node)
               :col (api/col node)}]})

3. DSL Linting

Expand custom macros for better analysis:

;; .clj-kondo/hooks/dsl.clj
(defn expand-defentity [{:keys [node]}]
  (let [[_ name & body] (:children node)]
    {:node (api/list-node
            [(api/token-node 'def) name (api/map-node body)])}))

4. Team Standards

Enforce consistent aliases:

{:linters {:consistent-alias {:level :warning
                              :aliases {clojure.string str
                                        clojure.set set}}}}

Learning Path

  1. Start with README.md (this file) - Quick overview
  2. Install clj-kondo - Get it running
  3. Read SKILL.md "Getting Started" - Basic usage
  4. Try basic linting - Run on your code
  5. Configure for your project - Customize linters
  6. Study built-in linters - Understand what's checked
  7. Learn hook basics - Read "Custom Hooks" section
  8. Write your first hook - Start with deprecation warning
  9. Explore advanced hooks - Study examples
  10. Integrate with IDE/CI - Set up automation

Hook Examples Preview

Simple Deprecation Hook

(defn deprecation [{:keys [node]}]
  {:findings [{:message "Deprecated: use new-fn"
               :type :deprecated
               :row (api/row node)
               :col (api/col node)}]})

Argument Validation Hook

(defn validate-args [{:keys [node]}]
  (let [args (rest (:children node))]
    (when (< (count args) 2)
      {:findings [{:message "Requires at least 2 arguments"
                   :type :invalid-args
                   :row (api/row node)
                   :col (api/col node)}]})))

Macro Expansion Hook

(defn expand-defroute [{:keys [node]}]
  (let [[_ method path & handlers] (:children node)]
    {:node (api/list-node
            [(api/token-node 'def)
             (api/token-node (gensym "route"))
             (api/map-node [method path (api/vector-node handlers)])])}))

Why Use This Skill?

  • Comprehensive: Covers all clj-kondo features including advanced hooks
  • Practical: Real-world examples and patterns
  • Well-structured: Easy navigation from basics to advanced topics
  • Hook-focused: Extensive coverage of custom hook development
  • Production-ready: Best practices for teams and CI/CD

Additional Resources

License

This skill documentation is provided as educational material. The clj-kondo tool is distributed under the EPL License (same as Clojure).