npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

stac-node-validator

v2.0.0-rc.3

Published

STAC Validator for NodeJS

Downloads

2,577

Readme

stac-node-validator

Validate STAC Items, Catalogs, Collections and all STAC extensions in JavaScript/Typescript/Node environments.

Versions

Current version: 2.0.0-rc.3

| STAC Node Validator Version | Supported STAC Versions | | --------------------------- | -------------------------------- | | 1.1.0 / 1.2.x / 2.x.x | >= 1.0.0-rc.1 | | 0.4.x / 1.0.x | >= 1.0.0-beta.2 and < 1.0.0-rc.3 | | 0.3.0 | 1.0.0-beta.2 | | 0.2.1 | 1.0.0-beta.1 |

Quick Start

Two options:

  1. Go to check-stac.moregeo.it for an online validator.
  2. npx stac-node-validator /path/to/your/file-or-folder to temporarily install the library and validate the provided file for folder. See the chapters below for advanced usage options.

Usage

CLI

Install a recent version of node (>= 22.1.0) and npm.

Then install the CLI on your computer:

npm install -g stac-node-validator
  • Validate a single file: stac-node-validator /path/to/your/file.json
  • Validate multiple files: stac-node-validator /path/to/your/catalog.json /path/to/your/item.json

Instead of paths to local files, you can also use HTTP(S) URLs. Other protocols such as S3 are not supported yet.

  • Validate a single folder (considers all json and geojson files in the given folder and all sub-folders): stac-node-validator ./stac-spec

Further options to add to the commands above:

  • To validate against schemas in a local STAC folder (e.g. dev branch): --schemas /path/to/stac/folder
  • To validate against a specific local schema (e.g. an external extension): --schemaMap https://stac-extensions.github.io/foobar/v1.0.0/schema.json=./json-schema/schema.json
  • To not verify SSL/TLS certificates: --ignoreCerts
  • Add --verbose to get a more detailed output
  • Add --strict to enable strict mode in validation for schemas and numbers (as defined by ajv for options strictSchema, strictNumbers and strictTuples)
  • To set the depth for folder traversal: --depth 0 (0 = no sub-folders, -1 = unlimited, default: -1)
  • To lint local JSON files: --lint (add --verbose to get a diff with the changes required)
  • To format / pretty-print local JSON files: --format (Attention: this will override the source files without warning!)
  • To run custom validation code: --custom ./path/to/validation.js - The validation.js needs to contain a class that implements the BaseValidator interface. See custom.example.js for an example.

Note on API support: Validating lists of STAC items/collections (i.e. GET /collections and GET /collections/:id/items) is partially supported. It only checks the contained items/collections, but not the other parts of the response (e.g. links).

You can also pass a config file via the --config option. Simply pass a file path as value. Parameters set via CLI will not override the corresponding setting in the config file.

The config file uses the same option names as above. To specify the files to be validated, add an array with paths. The schema map is an object instead of string separated with a = character.

Programmatic

You can also use the validator programmatically in your JavaScript/NodeJS applications.

Install it into an existing project:

npm install stac-node-validator

For browsers

Then in your code, you can for example do the following:

const validate = require('stac-node-validator');

// Add any options, e.g. strict mode
const config = {
  strict: true,
};

// Validate a STAC file from a URL
const result = await validate('https://example.com/catalog.json', config);

// Check if validation passed
if (result.valid) {
  console.log('STAC file is valid!');
} else {
  console.log('STAC file has errors:');
}

For NodeJS

const validate = require('stac-node-validator');
const nodeLoader = require('stac-node-validator/src/loader/node');

// Add any options
const config = {
  loader: nodeLoader,
};

// Validate a STAC file from a URL
const result = await validate('https://example.com/catalog.json', config);

// Check if validation passed
if (result.valid) {
  console.log('STAC file is valid!');
} else {
  console.log('STAC file has errors:');
}

JSON Schema Versions

By default, only JSON Schema draft-07 is supported (used by all core STAC schemas). Some extensions may use newer JSON Schema drafts (2019-09 or 2020-12).

The CLI automatically supports all three drafts.

For programmatic use, you can opt into newer drafts without affecting your bundle size when you don't need them. Pass the Ajv classes via config.schemaVersions:

const validate = require('stac-node-validator');

const result = await validate(data, {
  schemaVersions: {
    '2019-09': require('ajv/dist/2019'),
    '2020-12': require('ajv/dist/2020'),
  },
});

If a schema requires a draft that isn't provided, the validator will report an error indicating which draft is needed.

Validation Results

The validate function returns a Report object with the following structure:

{
  id: "catalog.json", // File path or STAC ID
  type: "Catalog",    // STAC type (Catalog, Collection, Feature)
  version: "1.0.0",   // STAC version
  valid: true,        // Overall validation result
  skipped: false,     // Whether validation was skipped
  messages: [],       // Info/warning messages
  children: [],       // Child reports for collections/API responses
  results: {
    core: [],         // Core schema validation errors
    extensions: {},   // Extension validation errors (by schema URL)
    custom: []        // Custom validation errors
  },
  apiList: false,     // Whether this is an API collection response
  source: null        // Original file path (null for objects)
}

Browser

The validator is available as browser bundles for client-side validation:

  • ESM bundle (dist/index.mjs) — recommended, self-contained.
  • UMD bundle (dist/index.js) — deprecated, self-contained.

CDN Usage (ESM)

<script type="module">
  import validate from 'https://cdn.jsdelivr.net/npm/stac-node-validator@2/dist/index.mjs';

  const result = await validate({
    stac_version: '1.0.0',
    type: 'Catalog',
    id: 'my-catalog',
    description: 'A sample catalog',
    links: [],
  });

  if (result.valid) {
    console.log('STAC is valid!');
  } else {
    console.log('Validation errors:', result.results.core);
  }
</script>

CDN Usage (UMD)

<script src="https://cdn.jsdelivr.net/npm/stac-node-validator@2/dist/index.js"></script>
<script>
  validate({
    stac_version: '1.0.0',
    type: 'Catalog',
    id: 'my-catalog',
    description: 'A sample catalog',
    links: [],
  }).then(function (result) {
    if (result.valid) {
      console.log('STAC is valid!');
    } else {
      console.log('Validation errors:', result.results.core);
    }
  });
</script>

Custom Validators

You can extend the validator with custom validation logic by creating a class that extends BaseValidator. This lets you add domain-specific rules beyond what the STAC JSON Schemas cover.

Getting Started

Create a JavaScript file that extends BaseValidator and override one or more lifecycle methods:

const BaseValidator = require('stac-node-validator/src/baseValidator.js');

class CustomValidator extends BaseValidator {
  async afterValidation(data, test, report, config) {
    // data is the STAC object (a stac-js object if stac-js is installed)
    // test provides assertion methods to collect errors
    // report is the validation report
    // config is the validator configuration

    test.truthy(typeof data.title === 'string', 'must have a title');
    test.equal(data.type, 'Collection', 'type must be Collection');
  }
}

module.exports = CustomValidator;

Run it via the CLI:

stac-node-validator /path/to/files --custom ./my-validator.js

Or programmatically:

const validate = require('stac-node-validator');
const CustomValidator = require('./my-validator.js');

const config = {
  customValidator: new CustomValidator(),
};

const result = await validate('/path/to/file.json', config);

Lifecycle Methods

A custom validator can override the following methods, which are called in order during validation:

createAjv(ajv)

Customize the ajv JSON Schema validator instance before schemas are compiled. Return the modified ajv instance.

async createAjv(ajv) {
  ajv.addKeyword('x-custom-keyword');
  return ajv;
}

afterLoading(data, report, config)

Preprocess the STAC data after it has been loaded but before validation begins. Must return the (possibly modified) data object.

Warning: This may affect validation results!

For example, you can inject additional extension schemas to be validated:

async afterLoading(data, report, config) {
  if (!Array.isArray(data.stac_extensions)) {
    data.stac_extensions = [];
  }
  data.stac_extensions.push('https://example.com/my-schema/v1.0.0/schema.json');
  return data;
}

Or you could remove the collection property from Items:

async afterLoading(data, report, config) {
  if (typeof data.collection !== 'undefined') {
    delete data.collection;
  }
  return data;
}

bypassValidation(data, report, config)

Return a Report object to skip the standard STAC validation entirely, or return null to continue with normal validation. This is useful for validating against a different schema (e.g., OGC API Records) instead of the STAC schemas.

async bypassValidation(data, report, config) {
  if (typeof data.stac_version === 'undefined') {
    // Not a STAC entity — validate against a different schema
    // Then set report.valid to true/false for example
    report.valid = true;
    return report;
  }
  return null; // Continue with normal STAC validation
}

afterValidation(data, test, report, config)

Run custom validation rules after the core and extension schema validation has completed. This is the most commonly used method. The data parameter is a stac-js object if the dependency is installed, otherwise the raw JSON object.

async afterValidation(data, test, report, config) {
  // Require a specific license field on collections
  if (data.type === 'Collection') {
    test.truthy(
      data.license === 'CC-BY-4.0',
      'Collection must be CC-BY-4.0 licensed'
    );
  }

  // Check that self links are provided
  const selfLink = data.links?.find(l => l.rel === 'self');
  test.truthy(selfLink, 'self link is required')
}

Test Assertions

The test object passed to afterValidation wraps Node's built-in assert module. Instead of throwing on the first failure, it collects all errors so you get a complete report. Available methods:

| Method | Description | | ---------------------------------------------------- | ----------------------------------------------------- | | test.truthy(value, message) | Asserts that value is truthy | | test.ok(value, message) | Same as truthy | | test.equal(actual, expected, message) | Loose equality (==) | | test.strictEqual(actual, expected, message) | Strict equality (===) | | test.deepEqual(actual, expected, message) | Deep loose equality | | test.deepStrictEqual(actual, expected, message) | Deep strict equality | | test.notEqual(actual, expected, message) | Loose inequality | | test.notStrictEqual(actual, expected, message) | Strict inequality | | test.notDeepEqual(actual, expected, message) | Deep loose inequality | | test.notDeepStrictEqual(actual, expected, message) | Deep strict inequality | | test.match(string, regexp, message) | Asserts string matches regexp | | test.doesNotMatch(string, regexp, message) | Asserts string does not match regexp | | test.fail(message) | Unconditionally adds an error | | test.ifError(value) | Fails if value is truthy (useful for error objects) | | test.throws(fn, expected, message) | Asserts fn throws | | test.doesNotThrow(fn, message) | Asserts fn does not throw | | test.rejects(asyncFn, expected, message) | Asserts async function rejects | | test.doesNotReject(asyncFn, message) | Asserts async function does not reject |

You can also simply throw an Error in any lifecycle method — it will be caught and added to report.results.custom as well.

Using Constructor State

You can use the constructor to initialize state that persists across validations of multiple files:

class CustomValidator extends BaseValidator {
  constructor() {
    super();
    this.ids = new Set();
  }

  async afterValidation(data, test, report, config) {
    // Check for duplicate IDs across files
    test.truthy(!this.ids.has(data.id), `duplicate ID: ${data.id}`);
    this.ids.add(data.id);
  }
}

Development

  1. git clone https://github.com/moregeo-it/stac-node-validator to clone the repo
  2. cd stac-node-validator to switch into the new folder created by git
  3. npm install to install dependencies
  4. Run the commands as above, but replace stac-node-validator with node bin/cli.js, for example node bin/cli.js /path/to/your/file.json

Browser Bundle

To work on the browser bundle build it: npm run build

Then you can import it from the dist folder.

Tests

Simply run npm test in a working development environment.

To run the website tests (requires Playwright):

npx playwright install --with-deps chromium
npm run test:website

Linting & Formatting

  • Lint: npm run lint — runs oxlint and auto-fixes issues where possible
  • Format: npm run format — formats all files with Prettier