# shfmt

> Shell script formatter built on a Go parser for POSIX sh, Bash, Zsh and mksh. The same repo ships a syntax package, shell helpers and an interpreter.

Stars: 9.2k · Language: Go · License: BSD-3-Clause · Categories: Shell

- Repository: https://github.com/mvdan/sh
- Website: https://pkg.go.dev/mvdan.cc/sh/v3
- Page: https://www.trmn.sh/tools/shfmt

## Install

- Go: `go install mvdan.cc/sh/v3/cmd/shfmt@latest`

## Overview

shfmt formats shell scripts. It is the command-line front end of the mvdan/sh project, a Go library that parses, formats and interprets shell code. It supports POSIX Shell, Bash, Zsh and mksh. A typical invocation is `shfmt -l -w script.sh`, which lists files whose formatting differs and rewrites them in place. The default style is shown in the repository's canonical.sh, and a manpage documents the remaining flags.

The repository also provides Go packages. The `syntax` package parses scripts into a syntax tree that you can inspect and print back out the way shfmt does. The `shell` package has helpers to split a command line into arguments, quote them back like `shlex`, expand `$VAR` and `~`, and glob with `**` or match `case`-style patterns. The `interp` package runs shell scripts without a system shell, including on Windows, and its handlers control what scripts can execute and access. Because the library is pure Go, the interpreter cannot follow POSIX and Bash semantics exactly. For example, subshells run as goroutines, so real PIDs and file descriptors are not available.

The README lists known parser limits. Bash associative array indices should be quoted, since otherwise they are parsed as arithmetic expressions. The `$((` versus `((` ambiguity is not supported. `export`, `let` and `declare` are parsed as keywords. The formatter deliberately cannot be disabled for ranges of lines, and the project avoids adding formatting options.

Users are mainly developers and teams who want consistent shell formatting in editors, pre-commit hooks and CI. Documented integrations include plugins for VS Code, (Neo)Vim, Emacs, JetBrains IDEs and micro, a pre-commit hook, the sh-checker GitHub Action, a Prettier plugin, and mdformat-shfmt for scripts embedded in Markdown. Docker images are published for release tags, `v3` and `latest`, and they contain only shfmt. For JavaScript use, the third-party npm package sh-syntax bundles the parser and formatter compiled to WASM.

### Installation

```bash
# via Go
go install mvdan.cc/sh/v3/cmd/shfmt@latest
```

## Alternatives

- [up](https://www.trmn.sh/tools/up.md): Interactive terminal UI for building Linux pipelines with live preview of command results (Go, 8.9k stars)
- [direnv](https://www.trmn.sh/tools/direnv.md): Shell extension that automatically loads and unloads environment variables based on current directory (Go, 15.5k stars)
- [gum](https://www.trmn.sh/tools/gum.md): CLI tool providing interactive components for shell scripts with input prompts, menus, spinners, and styling (Go, 24.6k stars)
- [McFly](https://www.trmn.sh/tools/mcfly.md): Replaces ctrl-r shell history search with a full-screen search ranked by a small neural network using directory, prior commands, and exit status. (Rust, 7.8k stars)
- [inshellisense](https://www.trmn.sh/tools/inshellisense.md): IDE-style autocomplete for shells, running as a terminal-native runtime for the withfig/autocomplete specs covering 600+ CLI tools on Windows, Linux, and macOS. (TypeScript, 10.8k stars)

---

Canonical: https://www.trmn.sh/tools/shfmt
