A fast, cross-platform multi-language linter and formatter written in Rust.
- π Single Command: Run both linting and formatting simultaneously
- π Multi-Language Support: Rust, Python, TypeScript, JavaScript, Go, Java, C++, Swift, Kotlin, Lua, and more
- π― Auto-Detection: Automatically detect programming languages used in your project
- βοΈ Flexible Configuration: Support for project config, global config, and CLI parameters
- π¦ Plugin System: Share and reuse configurations via Git repositories
- π¨ Format Presets: Support for popular code styles like Google, Airbnb, Standard
- β‘ Parallel Processing: Leverage multi-core CPU for faster file processing
# Using pip
pip install linthis
# Using uv (recommended)
# pip install uv
uv pip install linthiscargo install linthisgit clone https://github.com/zhlinh/linthis.git
cd linthis
cargo build --release# Create project configuration file
linthis init
# Create global configuration file
linthis init -g
# Create global git hook template (for all new repos)
linthis init -g --hook-type git
# Initialize with pre-commit hooks (project-level)
linthis init --hook-type prek
linthis init --hook-type pre-commit
linthis init --hook-type git
# Force overwrite existing files
linthis init --force
linthis init --hook-type prek -f# Check and format current directory (default behavior)
linthis
# Check and format specific directories
linthis -i src/
linthis --include src/ --include lib/
# Check only, no formatting
linthis -c
linthis --check-only
# Format only, no checking
linthis -f
linthis --format-only
# Check Git staged files (suitable for pre-commit hook)
linthis -s
linthis --staged# Check specific language
linthis -l python
linthis --lang rust
# Check multiple languages
linthis -l python,rust,cpp
linthis --lang "python,javascript,go"# Exclude specific patterns
linthis -e "*.test.js" -e "dist/**"
linthis --exclude "target/**" --exclude "node_modules/**"linthis supports Git-based configuration plugins for easy sharing of code standards across projects and teams.
# Add plugin to project config (.linthis.toml)
linthis plugin add <alias> <git-url>
# Example: Add a custom plugin
linthis plugin add myplugin https://github.com/zhlinh/linthis-plugin.git
# Add to global config (~/.linthis/config.toml)
linthis plugin add -g <alias> <git-url>
linthis plugin add --global <alias> <git-url>Plugins are automatically loaded when running linthis. After adding a plugin:
# Plugin configs are auto-loaded
linthis
# Combine with other options
linthis -l python -i src/
linthis --check-only
linthis --staged# Remove plugin from project config
linthis plugin remove <alias>
linthis plugin remove myplugin
# Remove plugin from global config
linthis plugin remove -g <alias>
linthis plugin remove --global myplugin
# Supports flexible parameter ordering
linthis plugin remove --global myplugin# View project config plugins
linthis plugin list
# View global config plugins
linthis plugin list -g
linthis plugin list --global
# Sync (update) plugins
linthis plugin sync # Sync local plugins
linthis plugin sync --global # Sync global plugins
# Initialize new plugin
linthis plugin init my-config
# Validate plugin structure
linthis plugin validate /path/to/plugin
# Clean plugin cache
linthis plugin clean # Interactive cleanup
linthis plugin clean --all # Clean all cachesCreate .linthis.toml in your project root:
# Specify languages to check (omit for auto-detection)
languages = ["rust", "python", "javascript"]
# Exclude files and directories
excludes = [
"target/**",
"node_modules/**",
"*.generated.rs",
"dist/**"
]
# Maximum cyclomatic complexity
max_complexity = 20
# Format preset
preset = "google" # Options: google, airbnb, standard
# Configure plugins
[plugins]
sources = [
{ name = "official" },
{ name = "myplugin", url = "https://github.com/zhlinh/linthis-plugin.git", ref = "main" }
]
# Language-specific configuration
# [rust]
# max_complexity = 15
# [python]
# excludes = ["*_test.py"]Global configuration file is located at ~/.linthis/config.toml, with the same format as project config.
Configuration merge priority (from high to low):
- CLI Parameters:
--option value - Project Config:
.linthis.toml - Global Config:
~/.linthis/config.toml - Plugin Config: Plugins in sources array (later ones override earlier ones)
- Built-in Defaults
linthis provides a config subcommand for convenient command-line configuration management without manual TOML editing.
Supported array fields: includes, excludes, languages
# Add to project config
linthis config add includes "src/**"
linthis config add excludes "*.log"
linthis config add languages "rust"
# Add to global config (-g or --global)
linthis config add -g includes "lib/**"
linthis config add --global excludes "node_modules/**"
# Add multiple values (automatically deduped)
linthis config add includes "src/**"
linthis config add includes "lib/**"# Remove from project config
linthis config remove excludes "*.log"
linthis config remove languages "python"
# Remove from global config
linthis config remove -g includes "lib/**"
linthis config remove --global excludes "target/**"# Clear project config field
linthis config clear languages
linthis config clear includes
# Clear global config field
linthis config clear -g excludes
linthis config clear --global languagesSupported scalar fields: max_complexity, preset, verbose
# Set complexity limit
linthis config set max_complexity 15
linthis config set max_complexity 30 -g
# Set format preset (google, standard, airbnb)
linthis config set preset google
linthis config set preset airbnb --global
# Set verbose output
linthis config set verbose true
linthis config set verbose false -g# Remove field from project config
linthis config unset max_complexity
linthis config unset preset
# Remove field from global config
linthis config unset -g verbose
linthis config unset --global max_complexity# View project config field
linthis config get includes
linthis config get max_complexity
linthis config get preset
# View global config field
linthis config get -g excludes
linthis config get --global languages# List project config
linthis config list
# List global config
linthis config list -g
linthis config list --global
# Verbose mode (show all fields including empty values)
linthis config list -v
linthis config list --verbose
linthis config list --global --verbose# Initialize project config
linthis config add includes "src/**"
linthis config add includes "lib/**"
linthis config add excludes "target/**"
linthis config add excludes "*.log"
linthis config add languages "rust"
linthis config add languages "python"
linthis config set max_complexity 20
linthis config set preset google
# View config
linthis config list
# Adjust config
linthis config set max_complexity 15
linthis config remove excludes "*.log"
linthis config add excludes "*.tmp"
# Set global defaults
linthis config set -g max_complexity 20
linthis config add -g excludes "node_modules/**"
linthis config add -g excludes ".git/**"Use the init subcommand to explicitly create configuration files:
# Create project config (.linthis.toml)
linthis init
# Create global config (~/.linthis/config.toml)
linthis init -g
linthis init --global
# Backward compatible: can also use --init flag
linthis --initWhen using the config command, configuration files are automatically created if they don't exist:
- Project Config: Creates
.linthis.tomlin current directory - Global Config: Creates
config.tomlin~/.linthis/directory
All modifications preserve TOML file format and comments.
| Short | Long | Description | Example |
|---|---|---|---|
-i |
--include |
Specify files or directories to check | -i src -i lib |
-e |
--exclude |
Exclude patterns (can be used multiple times) | -e "*.test.js" |
-c |
--check-only |
Check only, no formatting | -c |
-f |
--format-only |
Format only, no checking | -f |
-s |
--staged |
Check only Git staged files | -s |
-l |
--lang |
Specify languages (comma-separated) | -l python,rust |
-o |
--output |
Output format: human, json, github-actions | -o json |
-v |
--verbose |
Verbose output | -v |
-q |
--quiet |
Quiet mode (errors only) | -q |
--config |
Specify config file path | --config custom.toml |
|
--init |
Initialize .linthis.toml config file | --init |
|
--preset |
Format preset | --preset google |
|
--no-default-excludes |
Disable default exclude rules | --no-default-excludes |
|
--no-gitignore |
Disable .gitignore rules | --no-gitignore |
|
--no-plugin |
Skip loading plugins, use default config | --no-plugin |
| Command | Short | Long | Description |
|---|---|---|---|
plugin add <alias> <url> |
-g |
--global |
Add to global config |
--ref |
Specify Git reference | ||
plugin remove <alias> |
-g |
--global |
Remove from global config |
plugin list |
-g |
--global |
Show global config plugins |
-v |
--verbose |
Show detailed info | |
plugin clean |
--all |
Clean all caches | |
plugin init <name> |
Initialize new plugin | ||
plugin validate <path> |
Validate plugin structure |
| Command | Short | Long | Description |
|---|---|---|---|
config add <field> <value> |
-g |
--global |
Add value to array field |
config remove <field> <value> |
-g |
--global |
Remove value from array field |
config clear <field> |
-g |
--global |
Clear array field |
config set <field> <value> |
-g |
--global |
Set scalar field value |
config unset <field> |
-g |
--global |
Remove scalar field |
config get <field> |
-g |
--global |
Get field value |
config list |
-g |
--global |
List all configuration |
-v |
--verbose |
Show detailed info (including empty values) |
Supported array fields: includes, excludes, languages
Supported scalar fields: max_complexity, preset, verbose
| Command | Short | Long | Description |
|---|---|---|---|
init |
-g |
--global |
Create global config file |
--hook |
Initialize pre-commit hooks | ||
-i |
--interactive |
Interactive mode for hooks setup | |
-f |
--force |
Force overwrite existing files |
Created configuration files:
- Without
-g: Creates.linthis.toml(current directory) - With
-g: Creates~/.linthis/config.toml(global config)
Hook options:
prek: Rust-based pre-commit tool (faster)pre-commit: Python-based standard toolgit: Traditional git hook
| Language | Linter | Formatter |
|---|---|---|
| Rust | clippy | rustfmt |
| Python | pylint, flake8, ruff | black, ruff |
| TypeScript | eslint | prettier |
| JavaScript | eslint | prettier |
| Go | golangci-lint | gofmt |
| Java | checkstyle | google-java-format |
| C++ | cpplint, cppcheck | clang-format |
| Swift | swiftlint | swift-format |
| Kotlin | detekt | ktlint |
| Lua | luacheck | stylua |
| Dart | dart analyze | dart format |
Set up a global Git hook template that applies to all new repositories:
# Create global hook template
linthis init -g --hook-type git
# All new repos will automatically include the hook
git init new-project
cd new-project
# .git/hooks/pre-commit is already set up!For existing repositories:
cd existing-project
git init # Re-apply templateFeatures:
- π― Smart Detection: Only runs if project has linthis config
- π Hook Chaining: Supports
.git/hooks/pre-commit.localfor project-specific hooks - π« Zero Interference: Projects without linthis config are not affected
- β‘ One-time Setup: Works for all your new repositories
Pros:
- One-time setup for all your projects
- No need to configure hooks per project
- Perfect for personal development
- Won't interfere with other projects or hook tools
Cons:
- Not shared with team members
- Requires manual setup on each machine
See Global Hooks Guide for details.
prek is a high-performance Git hooks manager written in Rust, fully compatible with pre-commit config format but much faster.
Install prek:
# Using cargo
cargo install prek
# Or using pip
pip install prekCreate .pre-commit-config.yaml in your project:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: linthis
name: linthis
entry: linthis --staged --check-only
language: system
pass_filenames: falseInstall hook:
prek installAdd to .git/hooks/pre-commit:
#!/bin/sh
linthis --staged --check-onlyOr use linthis to create it automatically:
linthis init --hook-type gitUsing the pre-commit framework:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: linthis
name: linthis
entry: linthis --staged --check-only
language: system
pass_filenames: falsename: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install linthis
run: pip install linthis
- name: Run linthis
run: linthis --check-only --output github-actionslint:
image: rust:latest
script:
- cargo install linthis
- linthis --check-onlylinthis plugin init my-company-standards
cd my-company-standardsEdit linthis-plugin.toml:
[plugin]
name = "my-company-standards"
version = "1.0.0"
description = "My company's coding standards"
["language.python"]
config_count = 2
["language.python".tools.flake8]
priority = "P0"
files = [".flake8"]
["language.python".tools.black]
priority = "P1"
files = ["pyproject.toml"]mkdir -p python
# Add your config files to corresponding language directories
cp /path/to/.flake8 python/
cp /path/to/pyproject.toml python/git init
git add .
git commit -m "feat: Initial commit of my company coding standards"
git remote add origin [email protected]:mycompany/linthis-standards.git
git push -u origin mainlinthis plugin add company https://github.com/mycompany/linthis-standards.git
linthis # Plugin configs are auto-loadedlinthis -i src -i lib -i testslinthis -l python # Only check Python files- macOS:
~/Library/Caches/linthis/plugins - Linux:
~/.cache/linthis/plugins - Windows:
%LOCALAPPDATA%\linthis\plugins
linthis plugin sync # Sync local plugins
linthis plugin sync --global # Sync global pluginsThe ref can specify:
- Branch name:
--ref main - Tag:
--ref v1.0.0 - Commit hash:
--ref abc1234
This allows you to lock plugin versions or use development versions.
- Plugin Auto-Sync - Automatic plugin synchronization (inspired by oh-my-zsh)
- Self Auto-Update - Automatic self-update functionality
cargo buildcargo testcargo build --releaseIssues and Pull Requests are welcome!
MIT License - See LICENSE file for details