How to Install rumdl on Ubuntu: A Fast Markdown Linter and Formatter Written in Rust

rumdl checks and formats Markdown. It follows the markdownlint rules you may already know (MD001 and up), points at each problem by line and column, and can repair most of them automatically. Taking its cue from Ruff, it rolls linting, formatting, caching and a Language Server into a single Rust binary that finishes long before a Node.js-based linter has even started up.

rumdl is not available from the Ubuntu archive. Getting it normally means cargo install, pip install, a global npm package or a release tarball, so either you keep a whole language toolchain around for one linter or you track new versions yourself.

The unofficial deb.griffo.io repository offers a cleaner path: rumdl packaged as a proper Ubuntu .deb and delivered over APT, so you install it and keep it current with the same commands you already use.

Install the Latest rumdl on Ubuntu: The Short Version

If you only came for the commands, this adds the repository and installs the latest rumdl .deb package on Ubuntu:

sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null
sudo apt update
sudo apt install rumdl

The rest of this guide explains what each command does, how to verify the install, how to keep rumdl up to date, and what to check when something goes wrong.

What Makes rumdl Special?

  • ⚡ Built for speed - Native Rust with a results cache, so unchanged files are skipped on the next run.
  • 📏 markdownlint rule set - Rules for headings, lists, whitespace, code fences, links, images and overall style.
  • 🛠️ Automatic fixes - rumdl check --fix and rumdl fmt rewrite files to resolve most issues.
  • 🔄 Easy migration - Reads existing markdownlint configuration as-is, and rumdl import converts it to TOML.
  • 🧩 Flavor aware - Understands GFM, MkDocs, MDX, Quarto, Pandoc, Obsidian, MyST, Hugo and other dialects.
  • 🧠 Language Server included - rumdl server powers live diagnostics and fix-on-save in LSP-capable editors.
  • 🔧 Simple configuration - A .rumdl.toml, rumdl.toml or [tool.rumdl] table in pyproject.toml.
  • 🚦 Made for automation - Predictable exit codes, JSON output and an official pre-commit hook.

Why Use the deb.griffo.io Repository?

  • Easy installation and updates through APT rather than cargo, pip or npm.
  • Zero dependencies, since the package contains the statically linked musl binary.
  • Completions out of the box for bash, fish and zsh.
  • Always tracks upstream releases so you stay near the latest rumdl.
  • Works across supported Ubuntu releases on amd64 and arm64, with the codename detected for you.

Prerequisites

Before starting, confirm you have:

  • An Ubuntu system (Jammy 22.04 LTS, Noble 24.04 LTS, Questing 25.10, or Resolute 26.04 LTS)
  • An amd64 or arm64 machine
  • sudo privileges
  • curl installed (sudo apt install curl if needed)

Nothing else is required: the rules, the configuration schema and the Language Server are all built into the binary.

Step 1: Add the deb.griffo.io Repository

Register the key and repository source:

# Create the keyrings directory
sudo install -d -m 0755 /etc/apt/keyrings

# Download and install the repository GPG key
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg

# Add the repository (auto-detects your distro codename)
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null

# Update the package list
sudo apt update

Breaking it down:

  1. Create the keyrings directory - makes sure /etc/apt/keyrings exists with the right permissions.
  2. Install the GPG key - downloads and de-armours the repository key into its own keyring so APT can verify signatures.
  3. Add the repository - writes a signed-by source line, letting lsb_release -sc fill in your Ubuntu codename.
  4. Update the package list - refreshes APT’s view of available packages.

Step 2: Update the Package List

If you did not run the final command above, do it now:

sudo apt update

Step 3: Install rumdl

Install with APT:

sudo apt install rumdl

APT fetches rumdl and installs it across the system, shell completions included.

Step 4: Verify the Installation

The binary is rumdl. Check the version:

rumdl --version

You should see something like:

rumdl 0.2.73

There is no man page upstream; run rumdl --help for the full command listing, or rumdl check --help for a single subcommand.

Getting Started with rumdl

Your First Lint

Hand rumdl check a file or a folder. Folders are walked recursively, and anything in .gitignore is left alone:

# Check one document
rumdl check README.md

# Check every Markdown file in the project
rumdl check .

# Count violations per rule
rumdl check --statistics .

Output lines follow the file:line:column: [rule] message pattern, with [*] flagging the issues rumdl knows how to fix.

Repairing Files

There are two repair commands, and the difference is what they report back:

# See the proposed changes as a diff first
rumdl check --diff .

# Apply fixes and fail (exit 1) if anything could not be fixed
rumdl check --fix .

# Apply fixes and succeed (exit 0) regardless
rumdl fmt .

Pick check --fix for hooks and pipelines that should stop on leftovers, and fmt when it is acting as a plain formatter. Because fmt accepts stdin, you can also filter a buffer through it:

cat CHANGELOG.md | rumdl fmt --silent - > CHANGELOG.formatted.md

Selecting Rules

# Turn off a couple of rules for one run
rumdl check --disable MD013,MD033 docs/

# Check against a chosen subset only
rumdl check --enable MD001,MD003 docs/

# Browse the rule list, then get the details on one rule
rumdl rule
rumdl explain MD033

For one-off exceptions, an HTML comment in the document keeps the rest of the file under the normal rules:

<!-- rumdl-disable MD033 -->
<details><summary>Raw HTML is fine here</summary></details>
<!-- rumdl-enable MD033 -->

rumdl also respects markdownlint-disable comments already in your files.

Project Configuration

Generate a configuration file to start from:

# Create .rumdl.toml in the current directory
rumdl init

# Python project? Put it in pyproject.toml instead
rumdl init --pyproject

For example, a documentation site built with MkDocs could use:

[global]
line-length = 120
flavor = "mkdocs"
exclude = ["site", "node_modules"]

[per-file-ignores]
"docs/api/**/*.md" = ["MD013", "MD041"]

[MD004]
style = "dash"

rumdl looks for configuration in the current directory and its parents, stopping at the git root. These commands show you what it found:

# Full effective configuration, with the source of every value
rumdl config

# Just your overrides
rumdl config --no-defaults

# Path of the configuration file in use
rumdl config file

Personal defaults for projects without their own configuration belong in ~/.config/rumdl/rumdl.toml.

Coming from markdownlint

You do not need to convert anything on day one: rumdl reads .markdownlint.json, .markdownlint.jsonc, .markdownlint.yaml and .markdownlint.yml automatically. Once you are happy with the results, turn the old file into native TOML:

# Show the converted configuration without writing it
rumdl import --dry-run .markdownlint.yaml

# Save it as .rumdl.toml
rumdl import .markdownlint.yaml

Using rumdl in Your Editor

The built-in server talks LSP over stdio, giving any compatible editor inline warnings, quick fixes and formatting. Neovim 0.11 and later can register it natively:

vim.lsp.config("rumdl", {
  cmd = { "rumdl", "server" },
  filetypes = { "markdown" },
  root_markers = { ".git", ".rumdl.toml" },
})

vim.lsp.enable("rumdl")

For Helix, extend ~/.config/helix/languages.toml:

[language-server.rumdl]
command = "rumdl"
args = ["server"]

[[language]]
name = "markdown"
language-servers = ["rumdl"]

That [[language]] entry overrides the default Markdown servers, so add any others you rely on, marksman for instance, to the same list. In VS Code, rumdl vscode installs the extension for you.

Hooks and Pipelines

Exit codes are straightforward: 0 for clean, 1 for violations, 2 for a tool error. That makes rumdl check . a complete CI step by itself. With pre-commit, reference the upstream hook repository:

repos:
  - repo: https://github.com/rvben/rumdl-pre-commit
    rev: v0.2.73
    hooks:
      - id: rumdl
        args: [--fix]

Leave out args if the hook should only report problems. Anything that consumes results programmatically can use rumdl check --output-format json . instead of the text output.

Keeping rumdl Updated

rumdl rides along with your normal Ubuntu upgrades:

sudo apt update && sudo apt upgrade

When a newer rumdl appears in deb.griffo.io, apt upgrade installs it alongside your other packages. Upstream releases frequently, adding rules and refining fixes, so having APT pick them up keeps every machine linting the same way.

Other Tools from deb.griffo.io

The repository includes many tools that sit well next to rumdl:

  • Ruff - the lightning-fast Python linter and formatter that rumdl is modelled on.
  • Neovim - the hyperextensible Vim-based text editor, ready to host rumdl server.
  • Helix - a post-modern modal editor with LSP support built in.
  • just - a command runner for keeping rumdl check one short recipe away.

Troubleshooting

GPG or Key Errors

If APT flags the repository as unsigned or the key as invalid, re-import it:

curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update

Package Not Found

If APT cannot locate rumdl:

  1. Re-run sudo apt update after adding the repository.
  2. Verify your Ubuntu release is supported (Jammy, Noble, Questing, or Resolute).
  3. Check that dpkg --print-architecture reports amd64 or arm64, the only architectures upstream builds for.
  4. Check the source list: cat /etc/apt/sources.list.d/deb.griffo.io.list.

An Older rumdl Shadows the Package

Because rumdl is also published to crates.io, PyPI and npm, a copy installed that way can take priority over the packaged binary:

which -a rumdl

Uninstall it with the tool that put it there (cargo uninstall rumdl, pip uninstall rumdl, uv tool uninstall rumdl or npm uninstall -g rumdl), or remove a hand-extracted binary from /usr/local/bin, so that /usr/bin/rumdl wins.

Rules Behave Differently Than Expected

A configuration file you forgot about is the usual cause. Ask rumdl which one it loaded:

rumdl config file

rumdl stops at the first configuration it finds walking upward, preferring .rumdl.toml, then rumdl.toml, then pyproject.toml. Add --no-config to a run to see the results with built-in defaults only.

Uninstalling

Remove rumdl with:

sudo apt remove rumdl

To also remove the repository and key:

sudo rm /etc/apt/sources.list.d/deb.griffo.io.list
sudo rm /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update

Conclusion

On Ubuntu, deb.griffo.io turns rumdl into a first-class APT package: no Rust, Python or Node.js toolchain, no manual downloads, just a fast Markdown linter and formatter available on every machine. markdownlint-compatible rules, automatic fixes, editor integration through its own Language Server and a ready-made pre-commit hook all come in one small binary, maintained with apt upgrade.

If you write READMEs, run a documentation site or keep your notes in Markdown, rumdl keeps them consistent with almost no effort, and installing it this way keeps it effortless to keep current.

Frequently Asked Questions

How do I install the latest rumdl on Ubuntu?

Add the deb.griffo.io APT repository and its signing key, then run sudo apt install rumdl. The repository tracks upstream rumdl releases, so you get the latest packaged version without installing Cargo, pip or npm.

Is there a .deb package for rumdl?

Yes. deb.griffo.io publishes rumdl as a signed .deb for Ubuntu. You could download that .deb and install it by hand, but adding the repository is the better option: APT then picks up new versions on its own.

How do I update rumdl to the latest version?

Run sudo apt update && sudo apt upgrade. Once rumdl is installed from APT there is no separate updater to remember, since new releases arrive with the rest of your system updates.

Does rumdl work with my existing markdownlint setup?

Yes. It discovers markdownlint configuration files automatically, supports the same rule IDs and honours markdownlint-disable comments, so you can adopt it without touching your repository first.

How do I install rumdl on Debian?

Exactly the same way; lsb_release -sc simply resolves to a different codename. There is a companion guide with the Debian specifics: How to install rumdl on Debian.

Which Ubuntu releases are supported?

Jammy 22.04 LTS, Noble 24.04 LTS, Questing 25.10 and Resolute 26.04 LTS, on amd64 and arm64. Because the repository line is built from lsb_release -sc, the matching suite is selected for you.

Resources


Disclaimer: The deb.griffo.io repository is an unofficial community project and is not affiliated with the official Debian or Ubuntu projects, or with the upstream rumdl project.