SafeLint#
Holzmann "Power of Ten" safety lint rules for modern Python, JavaScript, TypeScript, and Java (with Spring Boot framework preset), adapted from C/C++ aerospace conventions to bound function length, nesting depth, cyclomatic complexity, error-handling discipline, hidden side effects, dataflow taint, and other classes of bugs that a typical linter (ruff, pylint, mypy, ESLint, SpotBugs, Checkstyle) doesn't reach.
SafeLint complements your existing linters. Where ruff handles style and pylint catches general defects, SafeLint enforces a focused set of safety rules: the kind you'd want in code that has to be reviewable, testable, and predictably-terminating. It's a CLI, a pre-commit hook, a JSON / SARIF emitter for editor and CI consumers, and an AI-client skill that twelve agents (Claude Code, Cursor, GitHub Copilot, Gemini, Windsurf, codex, Continue.dev, Cline, aider, Trae, Antigravity, Zed) speak.
Currently supported languages#
| Language | Extensions | Notes |
|---|---|---|
| Python | .py, .pyw |
Default language; the rule set was originally designed for Python and ports unchanged. No per-runtime configuration. |
| JavaScript | .js, .mjs, .cjs |
Runtime-agnostic source analysis covering Node.js, browser, Deno, Cloudflare Workers, Bun, and any WASM-hosted JS engine. Per-runtime defaults are switchable via [tool.safelint.javascript] runtime = "...". |
| TypeScript (including AssemblyScript) | .ts, .tsx, .as |
Reuses the JS rule implementations end-to-end with TS-specific handling for type-only constructs (generics, as casts, non-null assertions, declare global blocks, etc.). Shares JS runtime presets since TS compiles to JS. |
| Java (with Spring Boot framework preset) | .java |
16 cross-language rules port cleanly; 4 Spring-specific structural rules (SAFE901-904) target Spring annotation patterns. Per-framework defaults are switchable via [tool.safelint.java] framework = "...". |
Rule coverage: 16 cross-language rules apply across Python / JavaScript / TypeScript / Java; 2 are Python-only (bare_except, global_state), 1 applies to Python / JS / TS but not Java (global_mutation; the Python global keyword and JS globalThis.x = ... patterns have no clean Java analogue; deferred to a future release), 1 is JavaScript-family-only (wide_scope_declaration; var's function-scoping hazard doesn't exist in Python or Java), and 4 are Java + Spring Boot only (spring_field_injection, spring_missing_transactional, spring_unvalidated_input, spring_async_checked_exception).
Planned future languages (in working-priority order, no timelines committed): Go, Rust, C, C++, PHP. See the language-coverage roadmap.
Quick start#
pip install 'safelint[python]' # adds .py, .pyw
pip install 'safelint[javascript]' # adds .js, .mjs, .cjs
pip install 'safelint[typescript]' # adds .ts, .tsx, .as (also bundles JS)
pip install --pre 'safelint[java]==2.1.0rc1' # adds .java (Spring Boot framework preset available; RC pin needed until v2.1.0 GA)
pip install --pre 'safelint[all]==2.1.0rc1' # every supported language (RC pin needed until v2.1.0 GA so [all] includes Java)
pip install --pre 'safelint[python,java]==2.1.0rc1' # multiple extras compose (Java row needs the same RC pin)
# uv add 'safelint[typescript]' works the same way.
safelint check src/ # lint a directory
safelint check --all-files . # lint everything (default is git-modified only)
safelint check --format json src/ # machine-readable output for editors / CI
Pick the extras that match the languages you actually lint. Every grammar ships as an opt-in extra so a Python-only project never pays for JavaScript / TypeScript grammars, a Go/JS-only project never pays for the Python grammar, and so on. pip install safelint alone installs only the engine; safelint emits a one-line install hint on first run telling you which extra to add for the files it found.
Where to go from here#
- Configuration: every CLI flag, every rule, every TOML option. Start here once you've installed.
- Pre-commit: drop a 10-line block into
.pre-commit-config.yamland SafeLint runs on everygit commit. - AI client integrations: install the skill into Claude Code / Cursor / 10 other agents with one command, then ask "run safelint" in the chat.
- JSON output schema: for editor and plugin authors building on top of
safelint --format json. - Contributing: three contribution paths (rule, AI client, language), each with its own walkthrough.
- Changelog: what shipped when.
What SafeLint won't do#
SafeLint is a review tool, not a refactor tool. It surfaces violations and may emit advisory Suggestions in JSON output for editor integrations, but it never auto-fixes. There is no --fix flag and there never will be: every change to your code goes through your eyes.