Badness is a language server, formatter, and linter for LaTeX. It is designed to be fast, robust, and memory efficient. It bundles three tools in one:
- Formatter (
badness format): opinionated, deterministic, and rule-based layout. - Linter (
badness lint): syntax errors and best practices. - Language server (
badness lsp): both of the above, plus information on hovering, symbol outlines, go-to-definitions, code actions, and much more.
The architecture is modeled after rust-analyzer, relying on a incremental parser that forms a full concrete syntax tree of the document, and then using that tree to provide formatting, linting, and language server features. It is designed to used both inside your editor and on the command line, and is fast enough to provide real-time analysis after every keystroke and formatting on save, even for large documents and complex projects.
The audience for Badness is both authors who write LaTeX documents (.tex and
.bib files) and developers who write LaTeX packages (.sty, .cls, .dtx,
and .ins files), and provides support both for the newer LaTeX3 programming
layer and the older LaTeX2e layer.
Badness is available from several sources:
- crates.io:
cargo install badness - Homebrew:
brew install jolars/tap/badness - npm:
npm install -g badness(bundles a prebuilt binary) - PyPI:
uv tool install badness/pipx install badness - Aqua:
aqua install jolars/badness - Prebuilt binaries: from the releases page
- VS Code/Open VSX: the Badness extension (also works in Positron and Cursor)
- NixOS: the
badnesspackage on Nixpkgs - From source:
cargo install --path .in a checkout
If you prefer a one-liner installer that picks the right binary for your platform, you can use the installer scripts below.
For macOS and Linux:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/jolars/badness/releases/latest/download/badness-installer.sh | shFor Windows PowerShell:
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/jolars/badness/releases/latest/download/badness-installer.ps1 | iex"The VS Code/Open VSX extension bundles the badness binary and starts the
language server automatically when you open a .tex file.
# Format a file in place (or `badness format -` for stdin → stdout)
badness format paper.tex
# Verify formatting without writing, showing diffs
badness format --check bibliography.bib
# Lint, reporting parse diagnostics
badness lint paper.tex
# Fix lint issues in place
badness lint --fix paper.texFormatting is configurable via a TOML file named badness.toml. See the
documentation for the full reference.
The language server runs over stdio (badness lsp); see the editor setup
guide for instructions on how to
integrate with your editor.
badness-pre-commit provides pre-commit hooks for linting and formatting. It installs a prebuilt binary wheel from PyPI, so no Rust toolchain or LaTeX distribution is required:
repos:
- repo: https://github.com/jolars/badness-pre-commit
# badness version
rev: v0.11.0
hooks:
# Lint .tex, .sty, .cls, .dtx, .ins, and .bib files
- id: badness-lint
# Format the same files in place
- id: badness-formatbadness-action installs badness and runs format and lint checks in CI:
jobs:
badness:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: jolars/badness-action@v1See https://badness.dev/ for the full documentation, including a user guide, reference, and developer guide.
See CONTRIBUTING.md.