
Static analysis and auto-fix for the setopts, hooks, and globs Bash never learned.
Install · User guide · Katas · Integrations · Roadmap · Changelog

# macOS, Linux, WSL
curl -fsSL https://raw.githubusercontent.com/afadesigns/zshellcheck/main/install.sh | bash
# Windows
irm https://raw.githubusercontent.com/afadesigns/zshellcheck/main/install.ps1 | iex
# Anywhere Go is installed
go install github.com/afadesigns/zshellcheck/cmd/zshellcheck@latest
--uninstall reverses any of them.
Native .deb, .rpm, .apk, and a multi-arch container at ghcr.io/afadesigns/zshellcheck ship on every release tag.
Pinning, cosign verification, and distro one-liners are in INSTALL.md.
# Lint
zshellcheck path/to/script.zsh
# Write SARIF for GitHub Code Scanning
zshellcheck -severity warning -format sarif ./scripts > zshellcheck.sarif
# Preview every auto-fix as a unified diff
zshellcheck -diff path/to/script.zsh
# Apply the fixes
zshellcheck -fix path/to/script.zsh
Exits 0 on a clean run, 1 when anything was flagged.
zshellcheck -h lists every flag, grouped by intent.
Silence inline with # noka: ZC1234.
Bare # noka silences every kata on the line.
Trailing, preceding, and file-wide forms are documented in USER_GUIDE.md.
The published action checks out your repository, installs a signed release binary, runs it, and fails the job on any finding. Add the SARIF upload to surface results in the repository Security tab:
# .github/workflows/lint.yml
name: zshellcheck
on: [push, pull_request]
permissions:
contents: read
security-events: write
jobs:
zshellcheck:
runs-on: ubuntu-latest
steps:
- uses: afadesigns/zshellcheck@latest
with:
args: -format sarif -severity warning ./scripts > zshellcheck.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: zshellcheck.sarif
Run it as a pre-commit hook instead:
# .pre-commit-config.yaml
- repo: https://github.com/afadesigns/zshellcheck
rev: latest
hooks:
- id: zshellcheck
Pin @latest and rev: latest to a tag from Releases for reproducible CI.
ZShellCheck is verified against widely used Zsh frameworks, plugin managers, plugins, and prompts on every release. The pinned corpus matrix runs a parse-and-findings sweep: zero parser errors, zero crashes, and kata findings locked to a reviewed baseline. The heaviest trees are swept manually; the full catalog with file counts lives in INTEGRATIONS.md.
| Category | Examples |
|---|---|
| Frameworks | oh-my-zsh, prezto, prezto-contrib, zephyr, zimfw |
| Plugin managers | antidote, zinit |
| Plugins | zsh-syntax-highlighting, zsh-autosuggestions, zsh-autocomplete, atuin, zsh-help |
| Prompts | powerlevel10k, spaceship-prompt, starship, gitstatus |
| Tooling | fzf, fzf-tab, fast-syntax-highlighting |
Every release replays the linter over the pinned integration corpora and gates on:
Semantic-preserving rewrites — added blank lines, comments, or variable renames — must not change which katas fire. See the local checks for the commands.
Use it
Develop with it
Contribute
Contributions of all kinds are welcome. Start with CONTRIBUTING.md.
ZShellCheck is licensed under the MIT License.
Authored and maintained by Andreas Fahl (@afadesigns). Inspired by ShellCheck.
$ claude mcp add zshellcheck \
-- python -m otcore.mcp_server <graph>