Scapegoat: a Scala compiler plugin that reports to a data directory
Scala compiler plugin for static code analysis
At a glance
- What is it?
- Scapegoat is a static analyzer for Scala implemented as a compiler plugin, so its findings are produced during compilation and written out as XML, HTML, markdown, scalastyle or GitLab code quality reports. It suits teams that want bug-pattern checks in the same build that compiles the code, and it will not replace a style linter.
- Who is it for?
- Adopt Scapegoat when your Scala build already runs scalac and you want bug-pattern inspections to arrive as a report artifact in the same run, and when you are willing to add a compiler plugin to your build definition. Do not adopt it as a style linter, because the project states plainly that Scalastyle covers style and code standards, and do not expect a single configuration to cover both, since the two tools are independent and can run side by side.
- Can I use it commercially?
- Yes. Apache-2.0 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 last received commits 4 days ago.
- What is it written in?
- Mainly Scala, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A linter that runs inside the compiler, not beside it
Scapegoat is a Scala static code analyzer, described in the project listing as a code lint tool or linter. The README explains what a static analyzer does: it flags suspicious language usage in code, which can mean behaviour likely to lead to bugs, non-idiomatic usage of a language, or code that does not conform to specified style guidelines.
The distinguishing design choice is where the analysis runs. Scapegoat is developed as a Scala compiler plugin, which means it is loaded by the compiler itself and operates on the typed tree during compilation rather than parsing source files separately. That has an obvious advantage for a typed language: an inspection can ask the compiler what the type of an expression is, so a check about nullability or about an unnecessary conversion is a question the compiler can already answer.
The project positions itself against Java's FindBugs, checkstyle, and Scala's Scalastyle. That comparison is worth reading carefully, because the README then narrows it: Scalastyle is a similar linting tool which focuses mostly on enforcing style and code standards, and there are no problems in running multiple analysis tools on the same codebase. The stated view is that running several is beneficial, since the total set of possible warnings is the union of the inspections of all enabled tools, and the worst case is that the same warning is generated by more than one tool.
The intended users are Scala teams whose build already invokes scalac, since the plugin is wired in through the build tool rather than run as a separate step.
The data directory is the only required setting
Every Scapegoat configuration in the README comes back to the same required parameter, a `dataDir` where the report will be generated. Nothing else is mandatory.
The plugin's settings are passed to the compiler as `-P:` prefixed flags, and the README documents the full set in a table with a required column. Alongside `dataDir`, which is required, there are flags for `disabledInspections` as a colon separated list defaulting to none, `enabledInspections` defaulting to all, `customInspectors` as a colon separated list of custom inspections, and `ignoredFiles` as a colon separated list of regexes to match files to ignore.
The output behaviour is controlled separately. `verbose` is a boolean flag that enables or disables verbose console messages, `consoleOutput` is a boolean flag that enables or disables console report output, and `reports` takes a colon separated list of reports to generate, with the valid options given as `none`, `xml`, `html`, `scalastyle`, `markdown`, `gitlab-codequality`, or `all`. There is also `overrideLevels`, which overrides the built in warning levels.
Two of these deserve attention in a CI setting. The `reports` list includes `gitlab-codequality`, which is the format GitLab code quality expects, and the `all` option would enable every report format at once, which is usually wasteful. The `ignoredFiles` regex list is the mechanism for excluding generated sources, and the `overrideLevels` flag is how you promote or demote an inspection without disabling it outright.
Wiring it into Maven, Gradle and sbt
The plugin is integrated through build tools, and the README covers the three common ones with complete configuration snippets.
For sbt, the project points at a separate integration, sbt-scapegoat, rather than showing configuration inline. For Maven, you add the plugin as a dependency and then configure `scala-maven-plugin` with a `compilerPlugin` entry:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<configuration>
<args>
<arg>-P:scapegoat:dataDir:./target/scapegoat</arg>
</args>
<compilerPlugins>
<compilerPlugin>
<groupId>com.sksamuel.scapegoat</groupId>
<artifactId>scalac-scapegoat-plugin_${scala.binary.version}</artifactId>
<version>1.4.6</version>
</compilerPlugin>
</compilerPlugins>
</configuration>
</plugin>The Gradle route has two paths. One is a dedicated plugin by a third party, gradle-scapegoat-plugin. The other is manual, where you add the plugin to both the `dependencies` and a `scalaCompilerPlugin` configuration, then attach it to the compile task:
tasks.withType(ScalaCompile) {
scalaCompileOptions.additionalParameters = [
"-Xplugin:" + configurations.scalaCompilerPlugin.asPath,
"-P:scapegoat:dataDir:" + buildDir + "/scapegoat"
]
}That is the whole mechanism. The plugin path is handed to scalac with `-Xplugin:`, and the settings ride along as additional parameters, which is why the same `-P:scapegoat:` flag syntax appears in every build tool.
Two things in these snippets will bite you if you copy them without reading. The Maven dependency block shows a plugin version of 1.3.12 while the `compilerPlugin` entry shows 1.4.6, so the two should be kept consistent. And the Maven note warns that you may use a separate profile so that the dependency does not end up on your runtime classpath, which is worth doing since a compiler plugin has no business in production artifacts.
Report formats decide how findings reach the rest of your pipeline
Scapegoat's raw output is files in a directory, and the format flag determines what is in them. The available reports are `none`, `xml`, `html`, `scalastyle`, `markdown`, `gitlab-codequality` and `all`.
Each of those targets a different consumer. HTML is for a human reading a build artefact. XML is the general machine-readable form. The `scalastyle` format exists so Scapegoat findings can be fed into an existing Scalastyle reporting pipeline, which is the practical bridge if your team already has a report viewer for lint results. `gitlab-codequality` produces the format GitLab code quality expects, so findings appear inline on a merge request. Markdown is the plain text form for a job log.
This design is the main practical argument for Scapegoat over a separate linting tool. Because the analysis happens during compilation and the results land as report files, the findings can be published by the same CI job that compiles the code, with no separate tool to install, schedule and interpret.
The `consoleOutput` flag decides whether the report is also echoed to the build log, and `verbose` controls the additional console messages. Turning both off is the usual choice when the reports are being collected as artefacts, since the log is then not polluted with the same information twice.
The reports flag list is where the `all` option earns its name, and using it is rarely right, since you would generate every format for every build.
Scala version coverage and the artifact naming trap
The README carries a row of Maven Central badges, one per supported Scala version, and they are the clearest statement of which Scala lines the project builds against.
Each badge points at a distinct artifact with the Scala version and patch level in the name, for example `scalac-scapegoat-plugin_2.12.21`, `scalac-scapegoat-plugin_2.13.18`, `scalac-scapegoat-plugin_3.9.0` and `scalac-scapegoat-plugin_3.10.0`. That naming is the standard Scala convention of appending the binary version to the artifact id, and it means you must pick the artifact matching your own Scala version exactly. There is no single cross-version artifact in these examples.
The `project/` directory in the repository, alongside `build.sbt` and `src/`, is where the multi-version build lives, and the presence of `.scalafix.conf`, `.scalafix-2.conf`, `.scalafmt.conf` and `.git-blame-ignore-revs` in the top level tells you the project maintains its own formatting and linting discipline, and that some commits are excluded from blame history because of formatting-only changes.
The release history shows a steady cadence rather than occasional bursts. Version 3.4.1 was tagged on 2026-10-06, 3.4.0 on 2026-09-23, and 3.3.6 on 2026-06-13, and the last push was on 2026-10-19. The README also carries a Scala Steward badge, which indicates the dependency updates for Scala ecosystem libraries are handled by that service rather than by hand.
The project is licensed Apache-2.0, with a `LICENSE` file at the top level, and the plugin is published to Maven Central, which means using it brings no licensing obligation beyond the standard Apache terms.
Where Scapegoat is the wrong choice
The clearest case for a different tool is style enforcement, and the project says so itself. Scalastyle focuses mostly on enforcing style and code standards, and the two tools do different jobs. Running Scapegoat and expecting your formatting rules to be checked is a misreading of what a compiler-plugin inspector set contains.
The second case is a codebase you cannot compile. Because the analysis is a compiler plugin, Scapegoat only sees code that scalac accepts. A build that does not compile has no findings, and a project mid-refactor with a broken build gets no static analysis at all. Any tool that parses source text would still report something in that situation.
The third is a build that is already slow and does not want another plugin in the compiler's critical path. A compiler plugin adds work to every compilation, and the inspections are on by default unless you restrict them with `enabledInspections`. On a large module that is a real cost, and the only way to bound it is configuration.
The fourth is a team that needs findings on code that is not Scala. Scapegoat is a Scala compiler plugin, so it says nothing about the surrounding Java, JavaScript or SQL in a polyglot repository, and the union argument the README makes about running several tools applies just as well to the other languages.
A practical limit of the documentation is that the inspection list itself is not in the README. The flags let you disable or enable inspections by name, such as `FinalModifierOnCaseClass`, but the set of available names and what each one checks has to come from the project documentation site, which is linked as the source of full details rather than reproduced here.
Editorial conclusion
Adopt Scapegoat when your Scala build already runs scalac and you want bug-pattern inspections to arrive as a report artifact in the same run, and when you are willing to add a compiler plugin to your build definition. Do not adopt it as a style linter, because the project states plainly that Scalastyle covers style and code standards, and do not expect a single configuration to cover both, since the two tools are independent and can run side by side. Before you commit, check the plugin artifact coordinates for your Scala binary version, because the README shows different version numbers for the dependency and the compiler plugin, and read the `reports` flag options, since the default report set may not be what your CI expects to publish.
Frequently asked questions
What is Scapegoat and what does it check?
Scapegoat is a Scala static code analyzer implemented as a compiler plugin. A static analyzer flags suspicious language usage, which can mean behaviour likely to lead to bugs, non-idiomatic usage of the language, or code that does not conform to specified style guidelines.
How do I add Scapegoat to a Maven build?
Add the `scalac-scapegoat-plugin` artifact as a dependency, then configure `scala-maven-plugin` with a `compilerPlugin` entry that also passes `-P:scapegoat:dataDir:./target/scapegoat` in the args. The README notes you can use a separate Maven profile so the dependency does not land on your runtime classpath.
Which configuration flag is required for Scapegoat?
The only required parameter is `dataDir`, the path where the report is generated, set with `-P:scapegoat:dataDir:`. Every other flag, including `disabledInspections`, `enabledInspections`, `customInspectors`, `ignoredFiles`, `verbose`, `consoleOutput`, `reports` and `overrideLevels`, is optional.
What report formats can Scapegoat produce?
The `reports` flag takes a colon separated list, and the valid options given in the README are `none`, `xml`, `html`, `scalastyle`, `markdown`, `gitlab-codequality` and `all`. The `gitlab-codequality` format is the one intended for publishing findings on a GitLab merge request.
How does Scapegoat differ from Scalastyle?
The README describes Scalastyle as a similar linting tool that focuses mostly on enforcing style and code standards. The project states that there are no problems in running multiple analysis tools on the same codebase, since the total set of warnings is the union of the inspections of all enabled tools, with the worst case being duplicate warnings.
Official sources
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.
[](https://hysenlabs.com/projects/scapegoat-scala-scapegoat)Was this useful?