Configuration
Shuck can be configured through a shuck.toml or .shuck.toml file.
This page covers Shuck's native configuration for shuck check, shuck format, shuck run, and related native commands. ShellCheck compatibility mode uses .shellcheckrc instead; see the ShellCheck compatibility guide.
Default behavior
If you do not add a config file, Shuck enables all implemented non-style rules by default.
That baseline includes:
- Correctness rules (
C) - Performance rules (
P) - Portability rules (
X) - Security rules (
K)
All style rules are disabled by default, including S074. Shuck also reserves a small internal compatibility exclude list for ShellCheck-style opt-in checks when they map to standalone non-style rules.
You only need a config file when you want to change that baseline.
For example, the following configuration keeps the defaults, adds all style rules, and ignores one specific rule:
[lint]
extend-select = ["S"]
ignore = ["S074"]
fixable = ["ALL"]
unfixable = []Config file discovery
When Shuck needs configuration for a file or input path, it searches upward from that path for either:
.shuck.tomlshuck.toml
If both files exist in the same directory, .shuck.toml wins.
Shuck uses the nearest matching config root for each analyzed path. A single invocation can therefore pick up different config files when you lint inputs from different project roots.
Discovered config files do not cascade or merge. Shuck uses the closest config file it finds and ignores parent config files.
Precedence
Configuration is resolved in this order:
--isolateddisables discovered config files.--config path/to/file.tomluses one explicit config file for the entire run.- Otherwise, Shuck discovers the nearest
.shuck.tomlorshuck.tomlfor each analyzed path. - Inline overrides passed as
--config "<key> = <value>"are applied last. - If you pass the same inline setting more than once, the last one wins.
--isolated cannot be combined with --config path/to/file.toml, but it can still be used with inline overrides.
# Use the nearest discovered config
shuck check .
# Use one explicit config file for the whole run
shuck --config ci/shuck.toml check .
# Ignore discovered config files and rely only on inline overrides
shuck --isolated --config "lint.select = ['C001']" check .Check settings
The [check] section controls file-level analysis behavior.
embedded
Enables linting for supported embedded shell scripts in non-shell files such as GitHub Actions workflows and composite actions.
This setting defaults to true.
[check]
embedded = trueSet it to false if you want shuck check to ignore embedded run: blocks and only lint standalone shell files.
See the Embedded Scripts guide for the supported file types and how diagnostics are remapped back to workflow YAML.
Lint settings
Shuck's stable rule-selection config surface lives under [lint].
select
Replaces the default rule set with the selectors you provide.
Selectors can be:
- A named selector like
google - A full category prefix like
CorK - A narrower prefix like
C12 - An exact rule code like
S074 ALL
[lint]
select = ["google"]ignore
Removes rules from the currently selected set.
[lint]
select = ["ALL"]
ignore = ["S", "C011"]extend-select
Adds more rules on top of the current selection.
[lint]
extend-select = ["google"]per-file-ignores
Defines rule ignores for files matching a glob pattern.
[lint]
extend-select = ["S"]
[lint.per-file-ignores]
"scripts/*.sh" = ["S074"]
"testdata/**" = ["ALL"]extend-per-file-ignores
Adds more per-file ignores on top of any existing per-file-ignores entries.
[lint]
extend-select = ["S"]
extend-per-file-ignores = { "vendor/**" = ["ALL"], "scripts/*.sh" = ["S074"] }fixable
Restricts which rules are eligible when you run shuck check --fix.
By default, all rules are considered fixable candidates when fixes exist.
[lint]
extend-select = ["S"]
fixable = ["C", "S074"]unfixable
Marks selected rules as ineligible for automatic fixes, even when --fix is enabled.
[lint]
select = ["ALL"]
unfixable = ["C001"]extend-fixable
Adds more fixable rules on top of an existing fixable selection.
[lint]
extend-select = ["S"]
fixable = ["C"]
extend-fixable = ["S074"]Zsh plugin resolution
Shuck's zsh-specific plugin resolution settings live under [lint.zsh.plugins].
Use that section when you want Shuck to resolve real zsh plugin entrypoints for startup files such as .zshrc, especially for oh-my-zsh roots, dynamic plugin lists, and custom plugin entrypoints.
See the dedicated Zsh Support guide for the recommended setup patterns and the Settings Reference for the generated key-by-key reference.
Contracts
Shuck prefers to discover behavior from real sourced files and resolved plugin
entrypoints first. Use [lint.contracts] when important runtime or framework
behavior cannot be recovered from source alone.
Typical examples include:
- runtime-provided names that a script reads;
- plugin settings assigned in
.zshrcand consumed later by framework code; - metadata assigned in one file and consumed elsewhere by a dispatcher.
See the dedicated Contracts guide for the discovery boundary,
examples, and when to prefer Contracts over more source resolution. The
Settings Reference includes the exact [lint.contracts]
syntax.
Format settings
The formatter reads style options from [format].
[format]
indent-style = "space"
indent-width = 2
binary-next-line = true
switch-case-indent = true
space-redirects = true
keep-padding = true
function-next-line = false
never-split = falseFormatter config follows the same discovery and override rules as the rest of Shuck config. CLI flags passed to shuck format override [format] for that invocation.
Dialect is the exception: [format].dialect is rejected so projects do not accidentally force one parser mode for every file. Use file names, shebangs, or shuck format --dialect ... for a one-off override.
See the dedicated Formatting guide for command examples, stdin behavior, --check, --diff, --simplify, and --minify.
Runtime settings
The [run] section controls managed interpreter defaults for shuck run, shuck install, and shuck shell.
[run]
shell = "bash"
shell-version = "5.2"
[run.shells]
bash = "5.2"
zsh = "5.9"Use [run].shell for a project-wide default interpreter, [run].shell-version for a generic version constraint, and [run.shells] for per-shell pins that apply after Shuck has resolved the script's shell.
See the dedicated Managed Runtime guide for resolution order, inline script metadata, and --system behavior. The generated Settings Reference also includes every supported [run] key.
CLI-only file selection
Some commonly expected settings are command-line flags today, not shuck.toml keys. In particular:
--exclude--extend-exclude--respect-gitignoreand--no-respect-gitignore--force-excludeand--no-force-exclude
Use those flags directly on shuck check:
shuck check --exclude vendor --extend-exclude fixtures --force-exclude .Shuck does not currently support configuring those file-selection options in shuck.toml.