Open-source project
super-linter/super-linter avatar
super-linter/super-linter

Super-Linter: one container that runs every linter your repository uses

Combination of multiple linters to run as a GitHub Action or standalone

10,616 stars1,078 forksShellMIT

At a glance

What is it?
A GitHub Action and standalone image bundling dozens of linters into a parallel run, curated to avoid overlapping checks and built on GNU Parallel.
Who is it for?
Super-Linter answers a problem that appears the moment a repository stops being monolingual: getting a working linter setup for every language without maintaining an installation script for each one. The container approach means version pinning and installation are the project's job rather than yours, and the curation rule, refusing linters that duplicate each other's checks, is what keeps the image from becoming a pile of redundant tools.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 8, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem of a repository that speaks five languages

The stated goal is establishing best practices and consistent formatting across multiple programming languages and ensuring developers adhere to those conventions. That is a modest sentence for a fairly aggressive project, because the tooling required to achieve it is substantial. Every language has its own linter, its own package manager, its own version to pin, and its own opinions about what a config file looks like. Assembling that for a repository with a handful of languages means maintaining an installation script that will break when a dependency changes.

Super-Linter's answer is to pre-assemble it. It is a ready-to-run collection of linters and code analyzers that ships as a GitHub Action and as a container image, with the only external requirement being an OCI-compatible container runtime engine such as Docker. Findings come back as console output and as GitHub Actions status checks, so the same run works locally, in CI, and in a pre-commit hook.

The README also positions it as a governance project rather than only a tooling one. It notes the project is maintained by a team of independent developers and is not commercially backed by any entity that might influence its course, and it describes itself as the most widely used and most forked project of its kind. Whether a repository adopts it or not, there is an argument that a shared lint configuration is a governance artifact: it makes style decisions once, in one place, instead of in a style guide nobody reads.

Curation as the design principle, not inclusion

The feature list has one item that explains the project's shape more than any other: a highly curated set of linters, described as deliberately avoiding linters that implement overlapping checks, to reduce bloat, scanning time and container image size. That is a decision most bundling projects get wrong. Including every linter that works feels generous, and it produces an image where two tools report the same problem in different formats, disagree about which is correct, and double the scan time while adding nothing.

The README is also candid about the originality question, noting that to the best of the project's knowledge it is the first open-source fully containerized linting suite, and that other projects have borrowed ideas and design choices from it. It takes a relaxed view of that, which is a reasonable stance for infrastructure.

The remaining features are about execution. Linters run in parallel, a change made in version 6, described as reducing the scan of massive repositories to seconds. The codebase is described as lean because it builds on established tools rather than reimplementing them, and GNU Parallel is named as one of them. And the test suite is described as covering every single linter and analyzer that ships, which is the claim that makes the rest of the promise credible. A bundler that does not test each bundled tool is just a Dockerfile.

Where the coverage stops is also visible in the language table. Several rows defer rather than name a tool, for example C# pointing to Dotnet solutions for linting while using the dotnet format whitespace command for formatting, and Ansible, ASL, ARM and CloudFormation rows pointing at the JSON and YAML formatters for formatting. Those deferrals are honest and keep the table consistent, but they are worth noticing if you are picking a tool for a language where Super-Linter has no opinion.

Twenty-four pinned build stages, and why they are all there

The Dockerfile is the most informative file in the repository, because it enumerates the entire dependency surface as a list of pinned upstream images. Every stage is pinned to an exact version, which is the mechanism by which the project makes a reproducibility claim it can actually keep.

bash
FROM hashicorp/terraform:1.16.2 AS terraform
FROM zricethezav/gitleaks:v8.30.1 AS gitleaks
FROM koalaman/shellcheck:v0.11.0 AS shellcheck
FROM mvdan/shfmt:v3.14.1 AS shfmt
FROM rhysd/actionlint:1.7.12 AS actionlint
FROM hadolint/hadolint:v2.15.1-alpine AS dockerfile-lint

Reading that list tells you what kind of repository Super-Linter is aimed at. It is heavy on infrastructure-as-code and DevOps tooling: terragrunt, tflint, helm, kustomize, terraform, kubeconform, trivy and checkov all have stages, as do the shell linters shellcheck and shfmt, actionlint for GitHub Actions workflow files, editorconfig-checker, hadolint for Dockerfiles, gitleaks for secret scanning, dotenv-linter, goreleaser and clj-kondo. Language-specific bases include golang for Go, a Dart SDK, a dotnet SDK and composer for PHP, plus protolint for protobuf and scalafmt for Clojure and Scala.

Two entries stand out for what they say about cost. The dotnet SDK stage is a full .NET SDK, and the composer stage is a full PHP dependency manager, both pulled in to run a formatter. There is also no clang-format image: that stage installs clang, cmake, git, llvm development headers and ninja on Alpine, then clones the LLVM project at a branch computed from the installed clang version and builds from source. Building clang-format rather than downloading it costs a great deal of build time in exchange for a version matched to the toolchain rather than a release artefact.

So the image is large and the build is slow, and that is the trade the project has made deliberately. If your repository is a single-language project with one linter, this is an absurd amount of machinery. If it is a platform team managing forty services, it replaces a per-language setup problem with a version bump.

How the test suite is organised, and what it reveals

The Makefile is a long list of targets and it is more informative than it first appears, because the target names are documentation. Beyond the obvious entries like `test-lib`, `inspec`, `lint-codebase` and `fix-codebase`, there are targets named after GitHub event scenarios: initial commit, push event with multiple commits, force push, merge group, repository dispatch, merge commit push to a tag, and push events that use the find algorithm with and without ignoring gitignored files.

Those names describe tests for behaviours that are easy to get wrong in a CI linting tool. Which files get linted on a force push, whether a repository-dispatch event triggers a run at all, what happens on a merge group rather than a pull request. If you have ever adopted a linting Action and found it silently skipped files in a particular event type, this is the project that thought about that case.

There are also paired targets around output handling: saving output to a custom path, saving a custom summary, and the negative cases for not saving a log file and not saving output. And a cluster of linter-expectation targets covering expect-failure, expect-success, log level notice, suppress output on success, and the bash-exec linter's ignore-libraries behaviour in both failure and success configurations. Testing that a linter correctly reports success when you suppress its output is a small thing that most bundlers skip.

One structural note: the Makefile's `format` target has been retired, printing a message telling you to run the format step through a dev shell instead, with a comment noting the change was made on 2026-03-01. That is a good example of the project documenting its own deprecations in place rather than silently changing behaviour.

Choosing whether this belongs in your CI at all

The honest case against Super-Linter is that it does not make any individual check better. Each linter it runs is the same tool you could install directly, with the same configuration file, and for most languages the native setup is a single command. What you gain is having thirty of those setups maintained by someone else. What you give up is control over which version runs and the ability to run a tool that is not in the list.

There is a real cost in evaluation time as well. Adopting a bundle of dozens of linters to a repository that previously had none means turning on checks that will fail, and the failures are spread across every language in the tree rather than concentrated in the one place your team knows how to fix. Most projects handle this by enabling the Action and then configuring each linter to a rule set the team agrees on, which is real work that the container does not do for you.

The alternative worth comparing against is a per-language setup, which for a handful of languages is often less work than the configuration fight. Against that, Super-Linter's advantages are concrete when the count of languages is high, when contributors should not have to install toolchains locally to get the same results CI gives, and when the team would rather upgrade linters in one place on a schedule.

Two smaller details are worth knowing. The tree includes a `slim/` directory, corresponding to a reduced variant for environments where the full image is impractical, and a `TEMPLATES/` directory for the workflow file you copy into your own repository. The `version.txt` file at the root is how the image version stays in step with the Action version, which is the kind of detail that prevents the confusing situation where the Action requests one version and the image resolves to another.

Editorial conclusion

Super-Linter answers a problem that appears the moment a repository stops being monolingual: getting a working linter setup for every language without maintaining an installation script for each one. The container approach means version pinning and installation are the project's job rather than yours, and the curation rule, refusing linters that duplicate each other's checks, is what keeps the image from becoming a pile of redundant tools. The two things it does not do for you are choose your configuration or run fast on a small diff. Bring your own linter config files, and start with the language you actually write most, since the parallel speed-up only becomes meaningful once several linters are in play.

Frequently asked questions

Which linter should I use?

For a single-language repository, the native linter installed directly is usually less work than a bundle. Super-Linter earns its place when a repository spans many languages and the team would rather maintain one version pin than a dozen. The README's own curation rule is a useful guide: prefer the tool the language community already uses, and use a bundle to avoid installing it.

How do I run Super-Linter outside GitHub Actions?

Through a container runtime. The README states that Super-Linter runs on GitHub Actions and on other runtime environments, with the only dependency being an OCI-compatible container runtime engine such as Docker. The repository also ships a slim image variant for environments where the full image is impractical.

Does Super-Linter fix formatting issues or only report them?

Both. The README describes Super-Linter as a collection of linters and code analyzers for validating and fixing source code, with a documented section on fixing linting and formatting issues. The language table also lists a separate formatter for most languages, including Prettier, clang-format, shfmt and scalafmt, distinct from the linters.

How large is the Super-Linter container image?

Large, and deliberately so. The Dockerfile pulls roughly two dozen pinned upstream images as build stages, including a full .NET SDK, a Dart SDK, Composer, Golang, Terraform, Trivy and gitleaks, and it builds clang-format from LLVM source rather than downloading a release artefact. That cost buys a project where every linter is installed and version pinned for you.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. super-linter/super-linter on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/super-linter-super-linter.svg)](https://hysenlabs.com/projects/super-linter-super-linter)