An aggressive, no-noise and ultra fast Go linter.
Serenity is a configurable Go code quality tool built around focused AST rules, fast package traversal, deterministic issue limits, inline source frames, cache support and automatic fixes where the rewrite is safe.
Installation · Quick Start · Usage · Configuration · Rules · Suppression · Contributing
Serenity is designed for Go projects that want sharp defaults without a noisy feedback loop. It reports issues with enough context to fix them immediately, limits output when asked, and can apply selected rewrites directly to source files.
| Area | What Serenity does |
|---|---|
| Signal | Runs explicit rule groups with severity levels and max issue limits. |
| Speed | Uses concurrent package analysis, optional cache and deterministic single-worker mode when limits are enabled. |
| Fixes | Marks fixable diagnostics and supports safe --write rewrites plus explicit --unsafe rewrites. |
| Config | Loads JSON, YAML or TOML from the current tree, an explicit path, or SERENITY_CONFIG_PATH. |
| Output | Prints severity, rule name, numeric rule id, source location, a compact code frame and a human hint. |
Install the latest version with the Go toolchain:
go install github.com/serenitysz/serenity@latestOr build it directly from the repository:
git clone https://github.com/serenitysz/serenity.git
cd serenity
go build -o serenity .
Release archives are produced with GoReleaser for Linux, macOS and Windows on
amd64 and arm64.
# Create serenity.json with the recommended preset.
serenity init
# Check the current module.
serenity check ./...
# Apply safe automatic fixes.
serenity check --write ./...
# Apply safe fixes and explicitly allowed unsafe fixes.
serenity check --write --unsafe ./...For an interactive setup that can choose JSON, YAML or TOML, strict mode and autofix defaults, run:
serenity init --interactive| Command | Description |
|---|---|
serenity check [path...] |
Analyze one or more files or directories. Defaults to the current directory. |
serenity init |
Create a default serenity.json configuration. |
serenity init -i |
Interactively choose config format, path, strict preset and autofix. |
serenity status |
Print version, commit, platform and discovered config status. |
serenity docs |
Open the Serenity documentation site in the default browser. |
serenity update |
Self-update the installed binary from GitHub releases. |
| Flag | Scope | Description |
|---|---|---|
--config path |
global/check | Load a specific config file instead of auto-discovery. |
--no-color |
global | Disable ANSI colors in output. |
--verbose |
global | Enable additional diagnostics where supported. |
--max-issues n |
check | Stop after n issues. 0 means unlimited. |
--max-file-size bytes |
check | Skip files larger than the provided byte limit. |
--write |
check | Apply safe automatic fixes and format changed files. |
--unsafe |
check | Allow unsafe fixes. Must be used with --write. |
Serenity auto-discovers one of these files from the current working directory upward:
serenity.json · serenity.yaml · serenity.yml · serenity.toml
Discovery order can be bypassed with --config or with the
SERENITY_CONFIG_PATH environment variable. If no config is found,
Serenity runs with the generated default configuration and applies the
recommended preset.
{
"$schema": "https://raw.githubusercontent.com/serenitysz/schema/main/versions/1.0.0.json",
"linter": {
"use": true,
"rules": {
"recommended": true
},
"issues": {
"use": true,
"max": 20
}
},
"assistance": {
"use": true,
"autofix": false
},
"performance": {
"use": true,
"caching": true
}
}
Rules are grouped by domain. Each enabled group uses "use": true,
and each rule accepts a severity of error,
warn or info. Rules with limits or patterns expose
extra fields such as max, pattern,
packages, maxSize or
maxUnnamedSameType.
{
"linter": {
"use": true,
"rules": {
"recommended": false,
"imports": {
"use": true,
"noDotImports": {
"severity": "error"
},
"disallowedPackages": {
"severity": "warn",
"packages": ["log", "log/slog"]
},
"redundantImportAlias": {
"severity": "warn"
}
},
"bestPractices": {
"use": true,
"useContextInFirstParam": {
"severity": "warn"
},
"maxParams": {
"severity": "warn",
"max": 4
},
"useSliceCapacity": {
"severity": "warn"
}
},
"complexity": {
"use": true,
"maxFuncLines": {
"severity": "warn",
"max": 35
},
"maxLineLength": {
"severity": "warn",
"max": 100
}
}
},
"issues": {
"use": true,
"max": 100
}
},
"assistance": {
"use": true,
"autofix": false
},
"performance": {
"use": true,
"threads": 8,
"caching": true
}
}| Preset | How to enable | Behavior |
|---|---|---|
| Recommended | "recommended": true or serenity init |
Turns on a balanced set of import, best-practice and complexity rules with a default max issue count. |
| Strict | serenity init --interactive and answer yes to strict mode |
Creates an explicit config with stricter severities and lower limits for teams that want tighter gates. |
performance.caching enables the local lint cache. The cache is
keyed by Serenity version, cache version, mutating mode, unsafe mode and the
loaded configuration. performance.threads overrides the default
worker count, which otherwise follows GOMAXPROCS.
assistance.autofix allows safe fixes to run without passing
--write. Unsafe fixes still require --write --unsafe.
The table below lists the rules wired into the current runner. The names match CLI output and suppression comments.
| Group | Config key | Rule name | Fix support |
|---|---|---|---|
| Errors | errorStringFormat |
error-string-format |
Safe |
| Errors | errorNotWrapped |
error-not-wrapped |
Safe |
| Imports | noDotImports |
no-dot-imports |
No |
| Imports | disallowedPackages |
disallowed-packages |
No |
| Imports | redundantImportAlias |
redundant-import-alias |
Safe |
| Best practices | maxParams |
max-params |
No |
| Best practices | useContextInFirstParam |
context-first-param |
Unsafe |
| Best practices | avoidEmptyStructs |
avoid-empty-structs |
No |
| Best practices | noMagicNumbers |
no-magic-numbers |
No |
| Best practices | alwaysPreferConst |
always-prefer-const |
No |
| Best practices | noDeferInLoop |
no-defer-in-loop |
No |
| Best practices | useSliceCapacity |
use-slice-capacity |
Safe |
| Best practices | noBareReturns |
no-bare-returns |
No |
| Best practices | getMustReturnValue |
get-must-return-value |
No |
| Correctness | emptyBlock |
empty-block |
No |
| Correctness | ambiguousReturns |
ambiguous-return |
No |
| Correctness | boolLiteralExpressions |
boolean-literal-expressions |
Safe |
| Complexity | maxFuncLines |
max-func-lines |
No |
| Complexity | maxLineLength |
max-line-length |
No |
| Naming | receiverNames |
receiver-name |
No |
| Naming | exportedIdentifiers |
exported-identifiers |
No |
| Naming | importedIdentifiers |
imported-identifiers |
No |
| Style | preferIncDec |
prefer-inc-dec |
Safe |
Serenity separates safe and unsafe rewrites. Safe rewrites are applied with
--write or by setting assistance.autofix to
true. Unsafe rewrites require both --write and
--unsafe.
| Mode | Command | Effect |
|---|---|---|
| Report only | serenity check |
Shows diagnostics and marks fixable issues. |
| Safe rewrite | serenity check --write |
Applies safe fixes and runs Go formatting on changed files. |
| Unsafe rewrite | serenity check --write --unsafe |
Also applies fixes that can change public signatures or call contracts. |
Suppressions use rule names, not config keys. Inline suppressions apply to the comment line and the following line. File-wide suppressions must appear before the package declaration. Unused suppressions are reported as warnings.
// @serenity-ignore no-magic-numbers: port is part of the protocol
const defaultPort = 8080
// @serenity-ignore-all no-dot-imports: generated test fixture
package fixtureSerenity works well as a focused CI gate. A minimal GitHub Actions job can install the CLI and run it against the repository:
name: Serenity
on:
pull_request:
push:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: stable
- run: go install github.com/serenitysz/serenity@latest
- run: serenity check ./...| Code | Meaning |
|---|---|
0 |
No issues or command completed successfully. |
1 |
Command-level failure, including lint issues. |
2 |
Internal error such as config, parse or filesystem failures. |
go test ./...
gofmt -w .
go run . check ./...The repository uses Go tests for the linter, config loading, output rendering, exception handling and rule messages. Release artifacts are built through the release workflow and GoReleaser configuration in this repository.
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request, and use the issue templates for bug reports or feature requests.
Security reports should follow SECURITY.md.
Serenity is released under the MIT License.