Skip to content

vacuum is the worlds fastest OpenAPI 3, OpenAPI 2 / Swagger linter and quality analysis tool. Built in go, it tears through API specs faster than you can think. vacuum is compatible with Spectral rulesets and generates compatible reports.

License

Notifications You must be signed in to change notification settings

daveshanley/vacuum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo

vacuum - The world's fastest OpenAPI & Swagger linter.

build Go Report Card discord Docs npm Docker Pulls Mentioned in Awesome Go

An ultra-super-fast, lightweight OpenAPI linter and quality checking tool, written in golang and inspired by Spectral.

It's also compatible with existing Spectral rulesets.

Install using homebrew tap

brew install daveshanley/vacuum/vacuum

Install using npm

npm i -g @quobix/vacuum

Install using yarn

yarn global add @quobix/vacuum

Install using curl

curl -fsSL https://quobix.com/scripts/install_vacuum.sh | sh

For CI/CD environments

To avoid GitHub API rate limiting in automated environments, set a GitHub token:

# Using repository token (GitHub Actions)
GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} curl -fsSL https://quobix.com/scripts/install_vacuum.sh | sh

# Using personal access token
GITHUB_TOKEN=your_github_token curl -fsSL https://quobix.com/scripts/install_vacuum.sh | sh

GitHub Actions example

- name: Install vacuum
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Increases rate limit from 60 to 5000 requests/hour
  run: |
    curl -fsSL https://quobix.com/scripts/install_vacuum.sh | sh

Note: The GitHub token prevents intermittent installation failures in CI/CD environments caused by API rate limiting. No additional permissions are required, the token only accesses public repository information.

Install using Docker

The image is available at: https://hub.docker.com/r/dshanley/vacuum

docker pull dshanley/vacuum

Multi-platform support: Docker images are available for both linux/amd64 and linux/arm64 architectures, including native ARM64 support for Apple Silicon Macs.

To run, mount the current working dir to the container and use a relative path to your spec, like so

docker run --rm -v $PWD:/work:ro dshanley/vacuum lint <your-openapi-spec.yaml>

Alternatively, you can pull it from Github packages. To do that, replace dshanley/vacuum with ghcr.io/daveshanley/vacuum in the above commands.

Run with Go

If you have go >= 1.16 installed, you can use go run to build and run it:

go run github.com/daveshanley/vacuum@latest lint <your-openapi-spec.yaml>

Sponsors

If your company is using vacuum, please considering supporting this project, like our very kind sponsors:

speakeasy'

Speakeasy

bump.sh'

bump.sh

scalar

scalar

apideck'

apideck


Come chat with us

Need help? Have a question? Want to share your work? Join our discord and come say hi!

Documentation

🔥 New in v0.20 🔥: Support for auto fixing custom rules

Got some rules that don't really need a human to look at?

Well now you can define an AutoFixFunction for your rules, and when you run with the --fix flag, the fixes will will be applied to the file, or use --fix-file to write them to a different file.

See Auto-Fixing Rule Violations for more specifics.


v0.19: Ignore rules with x-lint-ignore

Got an error in your spec you know about but can't get round to fixing yet? Migrating from zally and wanting to keep your existing x-zally-ignore issues silenced?

Now you can! Just add x-lint-ignore: rule-id to the yaml node reporting the failure (or x-lint-ignore: [rule-one, rule-two] if there are multiple issues to ignore).


v0.18: New dashboard, new lint command, new rules!.

Upgrades all around. There is a completely new dashboard command with a completely new dashboard terminal UI. It's completely interactive and allows you to explore, and filter violations, view full docs and see code. The dashboard command also adds a new -w / --watch flag that will watch your OpenAPI file for changes and re-lint and re-render results automatically.

A re-written lint command that has a whole new rendering engine and output. Everything is much more readable, easier to see on a screen, matches the new dashboard style. It's 100% backwards compatible with previous versions, all flags as they were.

New rules:


v0.17: Github Action.

vacuum now has an official Github Action. Read the docs, or check it out in the GitHub Marketplace.


v0.16.11: Composed bundling mode.

A different way to bundle exploded OpenAPI specifications into a single file. Read the docs.


v0.16+ : JSON 9535 Compliant.

vacuum now expects JSON Path Queries to be RFC 9535 compliant. Finally standardized!


v0.15+: Fixes, New Rules, Functions and Command.

There is a new command generate-ignorefile that will generate an ignore file from a linting report.

New rule no-request-body checks for incorrect request bodies in operations, and path-item-refs checks for $refs being used in path items.


See all the documentation at https://quobix.com/vacuum


vacuum can suck all the lint of a 5mb OpenAPI spec in milliseconds.

Designed to reliably lint OpenAPI specifications, very, very quickly. Including very large ones. Spectral can be quite slow when used as an API and does not scale for enterprise applications.

vacuum will tell you what is wrong with your spec, why, where, and how to fix it.

vacuum will work at scale and is designed as a CLI (with a web or console UI) and a library to be consumed in other applications.

Dashboard

vacuum comes with an interactive dashboard (vacuum dashboard <your-openapi-spec.yaml>) allowing you to explore rules and violations in a console, without having to scroll through thousands of results.

speakeasy'

To read about the dashboard, see the dashboard command docs.

HTML Report

vacuum can generate an easy to navigate and understand HTML report. Like the dashboard you can explore broken rules and violations, but in your browser.

No external dependencies, the HTML report will run completely offline.

vacuum html-report


Supports OpenAPI Version 2 (Swagger) and Version 3+

You can use either YAML or JSON, vacuum supports both formats.

Using vacuum with pre-commit

Vacuum can be used with pre-commit.

To do that, add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/daveshanley/vacuum
    rev: # a tag or a commit hash from this repo, see https://github.com/daveshanley/vacuum/releases
    hooks:
      - id: vacuum

See the hook definition here for details on what options the hook uses and what files it checks by default.

If no filenames or more than one filename in your repository matches the default files pattern in the hook definition, the pattern needs to be overridden in your config so that it matches exactly one filename to lint at a time. To lint multiple files, specify the hook multiple times with the appropriate overrides.

Build an interactive HTML report

./vacuum html-report <your-openapi-spec.yaml | vacuum-report.json.gz> <report-name.html>

You can replace report-name.html with your own choice of filename. Open the report in your favorite browser and explore the results.

See full linting report

./vacuum lint -d <your-openapi-spec.yaml>

Lint multiple files at once

./vacuum lint -d <spec1.yaml> <spec2.yaml> <spec3.yaml>

Lint multiple files using a glob pattern

./vacuum lint -d some/path/**/*.yaml

See full linting report with inline code snippets

./vacuum lint -d -s <your-openapi-spec.yaml>

See just the linting errors

./vacuum lint -d -e <your-openapi-spec.yaml>

See just a specific category of report

./vacuum lint -d -c schemas <your-openapi-spec.yaml>

The options here are:

  • examples
  • operations
  • information
  • descriptions
  • schemas
  • security
  • tags
  • validation
  • owasp

Generate a Spectral compatible report

If you're already using Spectral JSON reports, and you want to use vacuum instead, use the spectral-report command

./vacuum spectral-report <your-openapi-spec.yaml> <report-output-name.json>

The report file name is optional. The default report output name is vacuum-spectral-report.json

Generate a vacuum report

Vacuum reports are complete snapshots in time of a linting report for a specification. These reports can be 'replayed' back through vacuum. Use the dashboard or the html-report commands to 'replay' the report and explore the results as they were when the report was generated.

./vacuum report -c <your-openapi-spec.yaml> <report-prefix>

The default name of the report will be vacuum-report-MM-DD-YY-HH_MM_SS.json. You can change the prefix by supplying it as the second argument to the report command.

Ideally, you should compress the report using -c. This shrinks down the size significantly. vacuum automatically recognizes a compressed report file and will deal with it automatically when reading.

When using compression, the file name will be vacuum-report-MM-DD-YY-HH_MM_SS.json.gz. vacuum uses gzip internally.

Ignoring specific linting errors

You can ignore specific linting errors by providing an --ignore-file argument to the lint and report commands.

./vacuum lint --ignore-file <path-to-ignore-file.yaml> -d <your-openapi-spec.yaml>
./vacuum report --ignore-file <path-to-ignore-file.yaml> -c <your-openapi-spec.yaml> <report-prefix>

The ignore-file should point to a .yaml file that contains a list of errors to be ignored by vacuum. The structure of the yaml file is as follows:

<rule-id-1>:
  - <json_path_to_error_or_warning_1>
  - <json_path_to_error_or_warning_2>
<rule-id-2>:
  - <json_path_to_error_or_warning_1>
  - <json_path_to_error_or_warning_2>
  ...

Ignoring errors is useful for when you want to implement new rules to existing production APIs. In some cases, correcting the lint errors would result in a breaking change. Having a way to ignore these errors allows you to implement the new rules for new APIs while maintaining backwards compatibility for existing ones.


Try out the dashboard

This is an early, but working console UI for vacuum. The code isn't great, it needs a lot of clean up, but if you're interested in seeing how things are progressing, it's available.

./vacuum dashboard <your-openapi-spec.yaml | vacuum-report.json.gz>

Supply your own Spectral compatible ruleset

If you're already using Spectral and you have your own custom ruleset, then you can use it with vacuum!

The lint, dashboard and spectral-report commands all accept a -r or --ruleset flag, defining the path to your ruleset file.

Here are some examples you can try

All rules turned off

./vacuum lint -r rulesets/examples/norules-ruleset.yaml <your-openapi-spec.yaml>

Only recommended rules

./vacuum lint -r rulesets/examples/recommended-ruleset.yaml <your-openapi-spec.yaml>

Enable specific rules only

./vacuum lint -r rulesets/examples/specific-ruleset.yaml <your-openapi-spec.yaml>

Custom rules

./vacuum lint -r rulesets/examples/custom-ruleset.yaml <your-openapi-spec.yaml>

_All rules, all of them!

./vacuum lint -r rulesets/examples/all-ruleset.yaml <your-openapi-spec.yaml>

Configuration

File

You can configure vacuum using a configuration file named vacuum.conf.yaml

By default, vacuum searches for this file in the following directories

  1. Working directory
  2. $XDG_CONFIG_HOME
  3. ${HOME}/.config

You can also specify a path to a file using the --config flag

Global flags are configured as top level nodes

time: true
base: 'http://example.com'
...

Command specific flags are configured under a node with the commands name

...
lint:
  silent: true
  ...

Environmental variables

You can configure global vacuum flags using environmental variables in the form of: VACUUM_<flag>

If a flag, has a - in it, replace with _

Auto-fixing rule violations

If you have a rule that doesn't need a human to look at it, and the change can be reliably automated you can configure an AutoFixFunction on the rule. When you then run the lint command you can pass the --fix flag and the violation will be automatically fixed.

Set up

  1. Define a rule that has an autoFixFunction, e.g.:
rules:
  use-compatible-extensions:
    autoFixFunction: useExtensibleEnum
    description: Prefer compatible extensions
    id: use-compatible-extensions
    given: "$.components.schemas[[email protected]]"
    severity: warn
    message: Use x-extensible-enum instead of enum for better compatibility
    then:
      field: enum
      function: falsy

This rule flags any usage of enum and recommends they are updated to x-extensible-enum. A simple change which can be easily auto fixed!

  1. Create a function which performs the auto-fix.
func useExtensibleEnum(
	node *yaml.Node,
	document *yaml.Node,
	context *model.RuleFunctionContext,
) (*yaml.Node, error) {
	if node.Kind != yaml.MappingNode {
		return node, nil
	}

	for i := 0; i < len(node.Content); i += 2 {
		if i+1 >= len(node.Content) {
			break
		}

		keyNode := node.Content[i]

		if keyNode.Value == "enum" {
			keyNode.Value = "x-extensible-enum"

			return node, nil
		}
	}

	return node, nil
}

Note

The auto fix function must satisfy the AutoFixFunction type. It should take in the *yaml.Node of the violation, the root *yaml.Node of the document and the RuleFunctionContext. It should return the fixed *yaml.Node and an error.

  1. Configure your RuleSetExecution to use the auto fix function.
func Lint(rulesFile string, specFile string) error {
	rules, err := rulesets.LoadLocalRuleSet(ctx, rulesFile)
	if err != nil {
		return fmt.Errorf("error loading ruleset: %w", err)
	}

	rs := rulesets.BuildDefaultRuleSetsWithLogger(slog.Logger).
		GenerateRuleSetFromSuppliedRuleSet(rules)

	// NOTE: only showing the fields on the RuleSetExecution relevant to auto-fixing.
	results := motor.ApplyRulesToRuleSet(&motor.RuleSetExecution{
		AutoFixFunctions: map[string]model.AutoFixFunction{
			"useExtensibleEnum": useExtensibleEnum,
		},
		ApplyAutoFixes:         true,
		RuleSet:                rs,
	})

	// Write back to file if fixes were applied
	if len(lintResults.FixedResults) > 0 && autoFix {
		fileInfo, _ := os.Stat(specFile)

		err = os.WriteFile(specFile, result.ModifiedSpec, fileInfo.Mode())
		if err != nil {
			return fmt.Errorf("failed to write file %s: %w", c.file, err)
		}
	}

	return nil
}

When the auto fix function runs, if it returns an error the fix will not be applied, the error will be logged, and the violation will be reported in the standard results.

If the auto fix function succeeds the yaml node flagged by the violation will be replaced with the transformed version returned by the auto fix function.

Tip

When using vacuum as a library You can access the fixed yaml content in the RuleSetExecutionResult.ModifiedSpec, and choose where to write the file.

When using vacuum as a cli, the --fix flag will overwrite the spec file in place, and --fix-file flag lets you specify an alternative file to write the content to, if you want to compare the outputs.

Usage

Logo gopher is modified, originally from egonelbre

About

vacuum is the worlds fastest OpenAPI 3, OpenAPI 2 / Swagger linter and quality analysis tool. Built in go, it tears through API specs faster than you can think. vacuum is compatible with Spectral rulesets and generates compatible reports.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages