# Getting Started

Shuck is a Rust toolkit for working with shell scripts: linting, formatting, editor feedback, and managed shell execution from one CLI.

- ⚡ Lint 20-100x faster than ShellCheck in benchmarked runs, with per-file caching for incremental checks.
- 🐚 Work across bash, sh/POSIX, dash, ksh, mksh, and zsh from the same binary.
- 🧩 Check shell scripts and embedded GitHub Actions `run:` blocks with parser-backed diagnostics.
- 🪄 Format shell files from the command line, CI, or an editor through LSP formatting.
- 🖥️ Use the LSP server for live diagnostics, quick fixes, hover help, navigation, and format-on-save.
- 🧪 Run scripts with managed shell interpreters when you need reproducible local or CI behavior.
- 🤝 Keep ShellCheck-compatible suppressions and CLI migration paths for existing workflows.
- 📦 Install one dependency-free executable for local development, editors, and CI.

Shuck is built around one shared shell parser, so the CLI, formatter, linter, and language server agree on how each script is understood.

## Installation

### PyPI

```bash
pip install shuck-cli
```

The PyPI package name is `shuck-cli`, but it still installs the `shuck`
command.

### From source

```bash
cargo install shuck-cli
```

### Pre-built binaries

Pre-built binaries are available for macOS (aarch64) and Linux (x86_64) from the [releases page](https://github.com/ewhauser/shuck/releases).

## Linting

```bash
# Check files and directories
shuck check script.sh src/

# Check the current directory
shuck check .

# Check embedded GitHub Actions `run:` blocks
shuck check .github/workflows/ci.yml

# Read from stdin
echo 'echo $foo' | shuck check -

# Apply safe fixes automatically
shuck check --fix .
```

See the dedicated [Linting guide](/docs/linting) for rule selection, fixes, output formats, watch mode, per-file shell overrides, and CI behavior.

## Formatting

Shuck includes a formatter for standalone shell files:

```bash
# Format the current project in place
shuck format .

# Check formatting in CI
shuck format --check .

# Print a diff without changing files
shuck format --diff .
```

See the dedicated [Formatting guide](/docs/formatting) for formatter config, stdin usage, dialect overrides, and LSP formatting support.

## Pre-commit

Use the published wheel-backed hook when you want pre-commit support without a
local Rust toolchain:

```yaml
repos:
  - repo: https://github.com/ewhauser/shuck
    rev: v0.0.35
    hooks:
      - id: shuck
```

Replace `v0.0.35` with the release you want to pin.

Use the source fallback instead when you prefer to run from the Rust checkout or
need an unsupported platform:

```yaml
repos:
  - repo: https://github.com/ewhauser/shuck
    rev: v0.0.35
    hooks:
      - id: shuck-src
```

The `shuck-src` hook requires a working Rust toolchain because it runs
`cargo run -p shuck-cli -- check ...` from the cloned hook repository.

## LSP server

Shuck also ships with a first-party LSP server over stdio:

```bash
shuck server
```

See the dedicated [LSP Server guide](/docs/lsp) for setup examples in Neovim, Vim, Emacs, and Zed.

## Managed runtime

Shuck can also run scripts with managed shell interpreters instead of whatever version happens to be installed on your machine.

```bash
# Run with the resolved interpreter for this script
shuck run deploy.sh

# Pin a specific shell version
shuck run --shell bash --shell-version 5.2 deploy.sh
```

See the dedicated [Managed Runtime guide](/docs/run) for version resolution, inline metadata, `[run]` config, `shuck install`, and `shuck shell`.

## Suppression

Use inline comments to suppress warnings for a line, a command, or a whole file. Shuck supports both native `# shuck:` directives and ShellCheck-compatible `# shellcheck` directives, including mapped `SC` codes.

See the dedicated [Suppression guide](/docs/suppression) for examples of both syntaxes.

## Zsh support

Shuck treats zsh as a first-class dialect and can resolve common `oh-my-zsh` plugin setups in real startup files such as `.zshrc`.

See the dedicated [Zsh Support guide](/docs/zsh-support) for dotfile detection, plugin-resolution examples, and the zsh-specific config and CLI flags.

## ShellCheck compatibility mode

If you already have tools that invoke `shellcheck`, Shuck can expose a ShellCheck-shaped CLI without changing your primary workflow all at once.

See the dedicated [ShellCheck compatibility guide](/docs/shellcheck-compat) for activation, supported flags, `.shellcheckrc` handling, and current caveats.

<h3 id="rules_lint">Use Shuck with rules_lint</h3>

If you use `rules_lint` for shell scripts in Bazel, you can keep the existing ShellCheck-shaped lint hook and swap in Shuck underneath it.

See the dedicated [`rules_lint` replacement example](/docs/shellcheck-compat#rules-lint) for the Bazel targets and compatibility setup.

## Embedded scripts

Shuck also lints shell embedded in supported GitHub Actions workflows and composite actions. See the dedicated [Embedded Scripts guide](/docs/embedded-scripts) for supported files, shell resolution, diagnostic remapping, and suppression behavior inside `run:` blocks.
