Unified structural linter for Python + TypeScript projects
Project description
swarm-lint
Unified structural linter for Python + TypeScript projects. Runs multiple checks under one CLI:
- Structural checks (pure Python, stdlib only) — file line count limits, folder item count limits, nested import detection
- Vulture — dead Python code detection (shells out to
vulture) - ESLint — TypeScript/React linting (shells out to local
node_modules/.bin/eslint) - Knip — unused TypeScript exports, dependencies, and files (shells out to local
node_modules/.bin/knip)
Installation
pip install swarm-lint
# with optional extras
pip install "swarm-lint[watch]" # adds --watch mode (watchfiles)
pip install "swarm-lint[vulture]" # adds vulture dead-code detection
pip install "swarm-lint[all]" # both of the above
Quick start
# interactive setup wizard — the fastest way to get going
swarm-lint setup
# or scaffold a default config non-interactively
swarm-lint init --root /path/to/project
# run all checks once
swarm-lint check --root /path/to/project
# watch mode — re-checks on every file save
swarm-lint check --watch --root /path/to/project
CLI reference
swarm-lint setup
Interactive wizard that auto-detects your project structure (Python dirs, TypeScript dirs, virtual environments, node_modules) and walks you through choosing checks, setting rules, and scaffolding config files — all from the terminal.
swarm-lint check
swarm-lint check [--root DIR] [--config FILE] [--watch/--no-watch] [--color/--no-color]
| Flag | Description |
|---|---|
--root DIR |
Project root directory (default: .) |
--config FILE |
Explicit path to a JSON config file |
--watch |
Watch for file changes and re-lint continuously |
--no-color |
Disable colored terminal output |
Running swarm-lint with no subcommand is equivalent to swarm-lint check.
swarm-lint init
swarm-lint init [--root DIR] [--with-tasks] [--with-pyright] [--with-whitelist]
Non-interactive scaffolding — creates a swarm-lint-config/ folder with a general-config.json config file. Optional flags:
| Flag | Creates |
|---|---|
--with-tasks |
.vscode/tasks.json + .vscode/extensions.json |
--with-pyright |
swarm-lint-config/pyright-config.json template |
--with-whitelist |
swarm-lint-config/vulture_whitelist.py stub |
The .vscode/ files are always overwritten to stay in sync with swarm-lint. Other scaffolded files are skipped if they already exist.
swarm-lint config
Manage configuration without hand-editing JSON.
# pretty-print the resolved config (defaults + your overrides)
swarm-lint config show
# set a value using dot-path notation
swarm-lint config set rules.max-file-lines 300
swarm-lint config set vulture.venv_path backend/.venv
# toggle checks on/off
swarm-lint config enable vulture
swarm-lint config disable eslint
Configuration
swarm-lint looks for config in this order:
--configflag (explicit path)swarm-lint-config/general-config.jsonin the--rootdirectory- Built-in defaults
Your config is deep-merged on top of defaults — you only need to override what differs from the defaults.
Example swarm-lint-config/general-config.json
{
"rules": {
"vulture-min-confidence": 1,
"vulture-error-threshold": 1
},
"exclude": [
"node_modules", ".venv", "dist", "build", "__pycache__",
".git", ".cursor", ".vscode", "swarm-lint-config",
"uv-bin", "data", "public"
],
"vulture": {
"targets": ["backend", "debug.py"],
"venv_path": "backend/.venv",
"exclude": ".venv,__pycache__,data,uv-bin",
"whitelist": "swarm-lint-config/vulture_whitelist.py"
},
"eslint": {
"directory": "frontend"
},
"knip": {
"directory": "frontend"
}
}
Config reference
| Key | Type | Default | Description |
|---|---|---|---|
enabled.* |
bool |
true |
Toggle individual checks on/off |
rules.max-file-lines |
int |
250 |
Max lines per source file |
rules.max-folder-items |
int |
7 |
Max items per folder |
rules.vulture-min-confidence |
int |
80 |
Min confidence to flag a vulture finding |
rules.vulture-error-threshold |
int |
90 |
Confidence at which a finding becomes an error |
rules.no-nested-imports |
bool |
true |
Detect imports inside function bodies |
include_extensions |
list[str] |
[".py", ".ts", ...] |
File extensions to check |
exclude |
list[str] |
["node_modules", ...] |
Glob patterns for excluded dirs/files |
exceptions.<rule> |
list[str] |
[] |
Glob patterns for files exempt from a rule |
vulture.targets |
list[str] |
["."] |
Paths to scan (relative to root) |
vulture.venv_path |
str|null |
null |
Venv dir containing bin/vulture |
vulture.exclude |
str |
".venv,__pycache__" |
Comma-separated vulture exclusions |
vulture.whitelist |
str|null |
null |
Path to whitelist file (relative to root) |
eslint.directory |
str |
"." |
Directory containing node_modules/.bin/eslint |
eslint.args |
list[str] |
["src/", ...] |
Arguments passed to eslint |
knip.directory |
str |
"." |
Directory containing node_modules/.bin/knip |
VS Code integration
Run swarm-lint setup (or swarm-lint init --with-tasks) to create .vscode/tasks.json and .vscode/extensions.json:
- tasks.json — auto-starts
swarm-lint --watchwhen the workspace opens, feeds errors into the Problems panel via problem matchers, groups errors by check type (structural, vulture, eslint, knip) - extensions.json — recommends the ESLint VS Code extension
These files are always overwritten on re-run to stay in sync with swarm-lint.
Output format
Every error line matches: file:line:col: severity: message [rule-tag]
Sections are delimited by <name>: checking... and <name>: done. N error(s) found. lines. This format is stable and consumed by VS Code problem matchers.
External tools
swarm-lint shells out to these tools when their checks are enabled. Install them yourself:
- vulture —
pip install vulture(or use theswarm-lint[vulture]extra) - eslint —
npm install eslintin your frontend directory - knip —
npm install knipin your frontend directory
Development
git clone <repo-url>
cd linter
pip install -e ".[all]"
swarm-lint check --root .
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file swarm_lint-0.1.1.tar.gz.
File metadata
- Download URL: swarm_lint-0.1.1.tar.gz
- Upload date:
- Size: 18.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6c90495420f5ef7efeb18d1f73c62deb6e64ddecf48ab97eddb07c5a3ccf9ca
|
|
| MD5 |
bcc4902d8283b331fb5bd98d2cc157b7
|
|
| BLAKE2b-256 |
c956b73a1c71663ede99ceabf9499af2c13734996f8b4e464d484e68ab31e218
|
File details
Details for the file swarm_lint-0.1.1-py3-none-any.whl.
File metadata
- Download URL: swarm_lint-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbd15d35fc40250809bf2a428f49c4977c769e9b724f0a4c18aae674e191085d
|
|
| MD5 |
0a335e2c48e58c6b20ac516a9d165eec
|
|
| BLAKE2b-256 |
f8e2c59331944ff2d67490583fc35e910643314b2bce275066efbcbaac74bac2
|