mrkeyoor.com_
Sat 08 Aug 21:02 UTC
npmCLI & Toolingupdated 08 Aug 2026

oas-linter

oas-linter is the default style-rule plugin used by the oas-validator package while walking an OpenAPI document. It loads YAML or JSON rule files, checks named OpenAPI object types such as operation, parameter, and response, and accumulates warnings for missing fields, naming patterns, mutually exclusive properties, length limits, ordering, and embedded JSON Schema checks. Despite the name, this npm package is not a standalone command-line program and does not parse an API document by itself.

Verdict

Keep oas-linter when maintaining an OAS-Kit stack that already depends on its rule DSL. For a new linting workflow, install Spectral, Redocly CLI, or another actual executable instead of wiring this stateful plugin by hand.

API stability4/5Version 3.2.2 exposes six small CommonJS functions, and the documented YAML operators have stayed unchanged for years. Rule names merge predictably and old enabled flags are documented as deprecated. The weak point is that direct-call requirements are implicit: lint expects validator-shaped options, and the shared module state is observable behavior without an isolation contract.
Docs3/5The OAS-Kit site documents every rule property, the top-level rule-file shape, validator options, and the shipped default rules. The package README itself is only a short pointer. It does not provide an end-to-end custom-rule example through oas-validator, explain the absence of a CLI, show the exact warning object shape, or call out synchronous loading and global mutable state.
Maintenance2/5The latest npm package was published May 2021 and the Mermade/oas-kit repository's last push was October 2023. The repository is not archived and still hosts documentation, but this release line shows no recent package work. The package.json test script is a placeholder that exits with an error, leaving confidence dependent on monorepo-level tests and downstream use.
Ecosystem3/5oas-linter recorded 4,387,216 downloads from July 31 through August 6, 2026, chiefly because oas-validator and other OAS-Kit consumers install it. Its rules understand the object vocabulary used by that stack and can chain local rule files. Outside OAS-Kit there is little plugin or ruleset exchange, no standalone executable, and no TypeScript declaration package bundled here.

Use it if

  • You already use oas-validator and want to keep its built-in lint rules or replace them with a compatible local rule file
  • You need a small YAML rules DSL for checks tied to oas-validator object names such as operation, parameter, reference, and securityScheme
  • You maintain an existing OAS-Kit integration that calls loadRules, lint, and getResults directly
  • You need to chain a base rules file and override individual rules by their unique name
Skip it if

Setup reality

Installing npm install oas-linter succeeds without native compilation, credentials, environment variables, or peer-dependency warnings, but that does not give you a runnable linter. There is no bin field. In normal use you install oas-validator and pass { lint: true }; the validator loads this package's default rules, walks the already parsed OpenAPI object, and copies getResults() into options.warnings. Direct use is much more manual: call loadDefaultRules() or loadRules(path) first, then call lint(objectName, object, key, options) for every relevant object in the same order the validator does. The options object must contain metadata with a count object, context, lintSkip, and a numeric verbose value or the implementation can fail on assumptions that its host normally satisfies. Custom rule files are read synchronously from disk and parsed as YAML with the core schema. A top-level require can chain another rules file; extensionless paths inherit the parent file's extension, and relative paths resolve beside the parent. Rules with the same name merge, disabled rules are removed, and applyRules resets accumulated results. State is global to the loaded module, not scoped to a validator instance, so concurrent jobs with distinct rules can overwrite one another. There are no bundled TypeScript declarations. The dependencies include should, yaml 1.x, and a release-candidate range of @exodus/schemasafe. In CI, wrap oas-validator rather than this package, pin versions, load rules once per isolated process, and turn warning results into an explicit nonzero exit policy yourself.

Patterns

Run the default linter through oas-validatorvalidate-with-defaults

const validator = require('oas-validator')

const options = { lint: true }
try {
  await validator.validate(openapiDocument, options)
} catch (error) {
  console.error(error.message)
  console.error(options.warnings || [])
}

This is the supported integration path. oas-validator loads default rules, supplies traversal context, and gathers linter results into options.warnings.

Define truthy and pattern rules in YAMLwrite-rules-file

# api-rules.yaml
url: https://docs.example.com/api-rules
rules:
  - name: operation-id-required
    object: operation
    description: operations need an operationId
    truthy: operationId
  - name: operation-id-style
    object: operation
    pattern:
      property: operationId
      value: '^[a-z][A-Za-z0-9]+$'

object names are supplied by oas-validator, not discovered from JSONPath. A rule with an unknown object name will never be visited.

Load a custom rules fileload-custom-rules

const linter = require('oas-linter')

linter.loadRules(require.resolve('./api-rules.yaml'))
console.log(linter.getRules().rules.map((rule) => rule.name))

loadRules reads synchronously and changes module-level state. Load once before validation and do not swap rule files between concurrent requests.

Pass custom-loaded rules to oas-validatorinject-custom-linter

const validator = require('oas-validator')
const linter = require('oas-linter')

linter.loadRules(require.resolve('./api-rules.yaml'))
const options = {
  lint: true,
  linter: linter.lint,
  linterResults: linter.getResults,
}
await validator.validate(openapiDocument, options)

Supplying linter prevents oas-validator from calling loadDefaultRules. Pair it with linterResults or the host cannot collect the warnings.

Extend a base rules filechain-rule-files

# team-rules.yaml
require: ./base-rules
rules:
  - name: operation-tags
    description: every operation needs at least one tag
    object: operation
    truthy: tags

An extensionless require inherits .yaml from the parent, and relative paths resolve from the parent rules file rather than process.cwd().

Disable a rule inherited by namedisable-default-rule

require: ./base-rules.yaml
rules:
  - name: info-contact
    disabled: true

Rules are merged by name, then entries with disabled: true are filtered out. The older enabled property is deprecated and ignored.

Require one of several propertiesrequire-one-property

rules:
  - name: operation-summary-or-description
    object: operation
    description: add summary or description
    or:
      - summary
      - description

or checks whether at least one named property is defined. It does not require the selected value to be non-empty; use truthy when emptiness must fail.

Require exactly one of two fieldsrequire-exclusive-property

rules:
  - name: example-source-exclusive
    object: example
    description: choose inline or external example data
    xor:
      - value
      - externalValue

xor reports when neither property exists and when more than one exists. It tests definedness, not whether values are non-empty.

Limit a string fieldenforce-max-length

rules:
  - name: operation-summary-length
    object: operation
    maxLength:
      property: summary
      value: 80

maxLength only runs when the target property exists and is a string. Combine it with truthy if the field is also mandatory.

Validate an object with an embedded JSON Schemaembed-json-schema

rules:
  - name: contact-shape
    object: contact
    schema:
      type: object
      required: [email]
      properties:
        email:
          type: string
          pattern: '^[^@]+@[^@]+$'

Schemas are compiled lazily with @exodus/schemasafe and cached on the in-memory rule object as $schema. Use supported JSON Schema keywords for that dependency version.

Skip selected rules for one validationskip-named-rules

const options = {
  lint: true,
  lintSkip: ['info-contact', 'license-url'],
}
await validator.validate(openapiDocument, options)

lintSkip matches exact rule names. It is useful for a temporary exception but can silently preserve policy drift if the list is never reviewed.

Read warning details after validationinspect-results

for (const warning of options.warnings || []) {
  console.error({
    rule: warning.ruleName,
    pointer: warning.pointer,
    message: warning.message,
    docs: warning.rule && warning.rule.url,
  })
}

Warnings come from shared accumulated results. Consume them immediately after one validation and isolate parallel jobs in separate processes if rule sets differ.

Alternatives

PackageRegistryPick it when
@stoplight/spectral-clinpmUse for a standalone OpenAPI and AsyncAPI linter with JSONPath-based rules, shareable rulesets, formats, and direct CI commands
@redocly/clinpmUse when linting should sit beside OpenAPI bundling, preview, documentation, and configurable organization rules
ibm-openapi-validatornpmUse for an installable OpenAPI validator and linter with its own CLI and configurable rules rather than an internal traversal plugin