Skip to main content

Badness

Build and Test Crates.io Open VSX VS Code PyPI version npm version

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.

Installation

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 badness package on Nixpkgs
  • From source: cargo install --path . in a checkout

Install Script

The installer scripts pick the right release artifact for your platform and install to a user-local directory by default. They download the matching Badness CLI release asset and verify its checksum. If you prefer, download and inspect the script before running it.

For macOS and Linux:

curl --proto '=https' --tlsv1.2 -sSf https://badness.dev/install | sh

For Windows PowerShell:

powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://badness.dev/install.ps1 | iex"

The VS Code/Open VSX extension bundles the badness binary and starts the language server automatically when you open a supported LaTeX or BibTeX file: .tex, .sty, .cls, .dtx, .ins, or .bib.

Usage

# 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.tex

Formatting is configurable via a TOML file named badness.toml. See the documentation for the full reference.

Editor Integration

The language server runs over stdio (badness lsp); see the editor setup guide for instructions on how to integrate with your editor.

Pre-Commit Hook

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-format

GitHub Actions

badness-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@v1

Documentation

See https://badness.dev/ for the full documentation, including a user guide, reference, and developer guide.

Contributing

See CONTRIBUTING.md.

Funding

I am grateful for the financial support offered by the TeX Users Group through the TeX Development Fund.

License

MIT

Metadata

Release files for badness 0.25.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for badness 0.25.0
File Size Uploaded
badness-0.25.0.tar.gz 1.3 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for badness 0.25.0
File
badness-0.25.0-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
badness-0.25.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
badness-0.25.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
badness-0.25.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
badness-0.25.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
badness-0.25.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
badness-0.25.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
badness-0.25.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 32.9 MB

Release files / badness-0.25.0.tar.gz

Download URL badness-0.25.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
e405928667ffceebc2fa11e7ebac75b1a002bd6ef019a38728358fd41b8dbbf7
BLAKE2b-256 checksum
How to use checksums
728ebafcc58f1fafeb5e766c3d559c2cf986e90c06ce41f06a517c7d52200661
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-win_arm64.whl

Download URL badness-0.25.0-py3-none-win_arm64.whl
Size 3.8 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
ee95642d06468db12d1cb69f8cc5c3b33610212131b8553cd3f348237ec38701
BLAKE2b-256 checksum
How to use checksums
f059d07f803c14714b07ee3419868d43b6abe689af37c5455d7e94f7fc1416d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-win_amd64.whl

Download URL badness-0.25.0-py3-none-win_amd64.whl
Size 4.2 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
cac59277fd627fa8dc35940bb46f51c643986641c152d0298c574352e56ec979
BLAKE2b-256 checksum
How to use checksums
3342ca03a0f74b2ac32316b4fb9c4de36886989e3b63b728c7c65920aa1cc118
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-musllinux_1_2_x86_64.whl

Download URL badness-0.25.0-py3-none-musllinux_1_2_x86_64.whl
Size 4.2 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
f4e7742705fbe43a1e48da973b034d4f34824c12fe264f6de8555aa9aad73274
BLAKE2b-256 checksum
How to use checksums
e919a028dc27bc3b8f681c0dda398480c56e9d0a9c2414a90ddb8226ef2c6f35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-musllinux_1_2_aarch64.whl

Download URL badness-0.25.0-py3-none-musllinux_1_2_aarch64.whl
Size 3.8 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
3ca8c6f7a403dedef8d480e161107e2bbd3c2fe140c17e6a13b9667c2d7f2650
BLAKE2b-256 checksum
How to use checksums
5abe70ada4f4c2ae34047b2547da758ce742dc02d40ad3c26032fa83c069a1bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL badness-0.25.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.1 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
49a9239c276a4189c097d7546482ccbf18057ee25ff1737fd65ab773c713599c
BLAKE2b-256 checksum
How to use checksums
d19a627e3034cf7be0134a8d8e50a874163a97a8377b4c00e23b563e67ff2c13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL badness-0.25.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.9 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
8027131667f4ce2d12474087dd5fd44c25ce40a409734ec3d91ff9d706e1e059
BLAKE2b-256 checksum
How to use checksums
be0912062a231831d4f89cfcac4ff85a98c0da56cbd8302b35429577ebe734b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-macosx_11_0_arm64.whl

Download URL badness-0.25.0-py3-none-macosx_11_0_arm64.whl
Size 3.7 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f7ef742bc896766c6acb289785d40569956cc377a1edb06f41db5d9a60c750cc
BLAKE2b-256 checksum
How to use checksums
a2d6d35c968a90add43c765cd0f8ae636d988bce11cda1dc24117dec55f5ee35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / badness-0.25.0-py3-none-macosx_10_12_x86_64.whl

Download URL badness-0.25.0-py3-none-macosx_10_12_x86_64.whl
Size 3.9 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
7a5430b5cd4e04077b40743fad20fecb953a05bb5d68b3a6f011f08d848d4e2a
BLAKE2b-256 checksum
How to use checksums
83d3dd557d134f5494e414c3e3a20c44958ae92ef66aeaa19eb54031a4f311e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.25.0 This release

9 release files

0.24.0

9 release files

0.22.1

9 release files

0.22.0

9 release files

0.21.0

9 release files

0.20.0

9 release files

0.19.0

9 release files

0.18.0

9 release files

0.17.0

9 release files

0.16.0

9 release files

0.12.0

9 release files

0.11.0

9 release files

0.10.0

9 release files

0.9.0

9 release files

0.8.0

9 release files

0.7.0

9 release files

0.6.0

9 release files

0.5.0

9 release files

0.4.0

9 release files

0.3.0

9 release files

0.2.0

9 release files

0.1.0

9 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page