lychee

A fast, async link checker written in Rust — checks thousands of URLs in parallel and integrates seamlessly into CI pipelines.

lychee is a fast, async link checker that finds broken hyperlinks in Markdown, HTML, reStructuredText, and source code files. It checks URLs in parallel using async I/O, making it orders of magnitude faster than sequential link checkers. It's equally at home running locally or as a step in a CI pipeline protecting your documentation from link rot.

Features

  • Async and parallel — checks hundreds of links concurrently using Tokio; large docs sites that would take minutes with sequential checkers finish in seconds
  • Multiple input formats — scans Markdown, HTML, reStructuredText, plain text, and source code files; also accepts URLs piped via stdin
  • Multiple input sources — check local files, entire directories, remote URLs, or a sitemap
  • Caching — an optional on-disk cache avoids re-checking URLs that were valid recently, dramatically speeding up repeated runs
  • GitHub token support — authenticates with the GitHub API to avoid rate-limiting when checking many github.com links
  • Flexible exclusions — exclude URLs by regex pattern, domain, or status code (e.g. ignore all localhost links in CI)
  • Multiple output formats — human-readable summary, detailed per-link output, JSON, Markdown, or a GitHub Actions-compatible format
  • Retry logic — configurable retries with backoff for flaky servers
  • Archive fallback — optionally suggest Wayback Machine snapshots for dead links

Installation

cargo install lychee

Or via your system package manager:

# macOS
brew install lychee

# Debian / Ubuntu (Debian 12+)
apt install lychee

# Fedora
dnf install lychee

# Arch Linux
pacman -S lychee

# Nix
nix-env -iA nixpkgs.lychee

Pre-built binaries are also available on the releases page.

Usage

# Check all links in a single Markdown file
lychee README.md

# Check all Markdown files in a directory tree
lychee --glob "**/*.md" docs/

# Check a remote URL directly
lychee https://example.com

# Check links in a remote HTML page
lychee https://docs.example.com/index.html

# Check links from stdin
cat links.txt | lychee -

# Exclude specific URL patterns (e.g. localhost, internal domains)
lychee --exclude 'localhost' --exclude 'internal\.example\.com' docs/

# Only report errors, suppress successful results
lychee --quiet docs/

# Use the on-disk cache to skip recently checked URLs
lychee --cache docs/

# Output results as JSON
lychee --format json docs/ > results.json

# Set a custom timeout and number of retries
lychee --timeout 20 --max-retries 3 docs/

GitHub Actions Integration

lychee is particularly popular as a CI check for documentation repositories. The official action handles installation automatically:

name: Check links

on:
  push:
    branches: [main]
  schedule:
    # Run weekly to catch external link rot
    - cron: "0 9 * * 1"

jobs:
  linkcheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Restore lychee cache
        uses: actions/cache@v4
        with:
          path: .lycheecache
          key: cache-lychee-${{ github.sha }}
          restore-keys: cache-lychee-

      - name: Check links
        uses: lycheeverse/lychee-action@v1
        with:
          args: --cache --max-cache-age 1d --quiet "**/*.md"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Configuration

lychee reads from a lychee.toml file (or .lychee.toml) in the current directory:

# Maximum number of concurrent requests
max_concurrency = 64

# Request timeout in seconds
timeout = 20

# Retry attempts for failed requests
max_retries = 3

# Skip these URL patterns entirely
exclude = [
  "^https://localhost",
  "^http://127\\.0\\.0\\.1",
  "^https://example\\.com",
]

# Treat these HTTP status codes as success (e.g. 429 Too Many Requests)
accept = [200, 429]

# User-agent string
user_agent = "lychee/0.15.1"

# Use the cache
cache = true
max_cache_age = "1d"

Tips

  • Set GITHUB_TOKEN in your environment to avoid GitHub API rate limits when checking repos with many GitHub links.
  • Use --exclude-path to skip generated files or third-party directories like node_modules/.
  • The --dump flag prints all found links without checking them — useful for auditing what lychee would check.