# STAC: the JSON contract that makes geospatial catalogues crawlable

> The stac-spec repository defines the SpatioTemporal Asset Catalog family of specifications, a small set of JSON object types, Item, Catalog and Collection, linked by relations so that providers can publish static files and consumers can discover assets without writing code against every provider's private API. Searching over those objects is a separate layer, the STAC API, which extends OGC API Features.

**radiantearth/stac-spec** — SpatioTemporal Asset Catalog specification - making geospatial assets openly searchable and crawlable

- Repository: https://github.com/radiantearth/stac-spec
- Website: https://stacspec.org
- Stars: 939 · Forks: 191
- Language: JavaScript
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/radiantearth-stac-spec

## A family of small specifications, not one big one

The SpatioTemporal Asset Catalog family exists to standardise the way geospatial asset metadata is structured and queried. A spatiotemporal asset is defined as any file that represents information about the Earth at a certain place and time. The original focus was scenes of satellite imagery, and the scope has widened to aircraft and drone sources, hyperspectral optical data, synthetic aperture radar, video, point clouds, lidar, digital elevation models, vector data, machine learning labels and composites such as NDVI and mosaics. What did not widen is the core. The README is explicit that STAC is intentionally designed with a minimal core and a flexible extension mechanism, and that the Item, Catalog and Collection specifications together define a minimal core of the most frequently used JSON object types. The repository is therefore mostly specification text, schemas and worked examples, with the `overview.md`, `principles.md`, `process.md` and `best-practices.md` documents setting out the reasoning, and a `STAC-UML.drawio` plus `STAC-UML.pdf` pair carrying the object model.

## Item, Catalog and Collection form a static hierarchy

The three core types have distinct jobs and are meant to be used together. An Item describes a single asset and is the entity that gets discovered. A Catalog is a structure that links Items, Catalogs and Collections together to be crawled or browsed, described in the README as a simple, flexible JSON file of links. A Collection adds information about a spatio-temporal group of data, such as its spatial and temporal extent, licence and keywords, and enables discovery at a higher level than individual Items. Because of the hierarchical structure between these objects, the README makes a point that has real architectural consequences: a STAC catalog can be implemented in a completely static manner, as a group of hyperlinked Catalog, Collection and Item URLs, letting a data publisher expose data as a browsable set of files with no application server at all. That is the design choice that separates STAC from most catalogue systems, and it is why the format travels well to object storage and static hosting.

## An Item is a GeoJSON Feature with foreign members

The most important object in STAC is the Item, and the README describes it in one line: a GeoJSON Feature with a well-defined set of additional attributes, the so-called foreign members. That definition is doing a lot of work. It means STAC does not invent a new geometry encoding, and any existing GeoJSON tooling can parse the geometry half of an Item. What STAC adds sits beside it, with fields for attributes like time, links to related entities and links to assets including thumbnails. Shared pieces live in the `commons/` folder, which the README lists as covering assets, links and common metadata, so those concepts are specified once and reused by every extension. The repository's `examples/` folder makes the shape concrete, holding `core-item.json`, `simple-item.json`, `extended-item.json`, `collectionless-item.json`, `catalog.json` and `collection.json`, plus `extensions-collection/` and `collection-only/` directories, with the examples linked together into two complete examples.

## Crawling is not searching

STAC separates two operations that people often conflate. The static side is the link relations described as a HATEOAS-style traversable interface, which is enough to walk a catalogue from the top down. The query side needs more, and that is what the STAC API specification provides, an implementation of a web service interface to query over a group of STAC objects, usually held in a database, with additional browse and search interfaces over a RESTful API. The README is precise about the layering: the STAC API extends OGC API Features Part 1 Core with additional web service endpoints and object attributes, while the Item, Catalog and Collection specifications stay independent of it and can be used in other contexts. The practical consequence for an engineer is that adopting the object types does not commit you to running an API, while adopting search means implementing a separate specification with its own server, and that server is where the complexity and the operational cost sit.

## Extensions keep the core small without freezing it

The extension mechanism is how STAC covers domains that the minimal core does not name, and the README describes extensions as things that extend the functionality of the core spec or add fields for specific domains. Two properties matter. Extensions can be published anywhere, so a provider is not forced to wait for the core specification to grow, and the preferred location for public extensions is in the repository's own `extensions/` folder. The `extensions/` directory has its own README describing the mechanism, and the `examples/extensions-collection/` directory shows extensions in use. This is the design decision that keeps the core small while still allowing domain fields such as machine learning labels, and it has a cost: a consumer who needs a particular domain field must also depend on the right extension version, and the spec's own versioning story is tied to that. The README also notes that the STAC specifications follow Semantic Versioning, so any breaking change requires the spec to go to 2.0.0, which is a useful guarantee for consumers building against a pinned version.

## Checking your items against the schemas

The repository is a specification, but it ships tooling to keep the specification and the examples honest. The `package.json` in the root defines the checks that run in CI, and the entry point for contributors is the `test` script, which runs the markdown check and the example check in sequence. The example check is where a STAC implementer finds the useful part, because it lints the examples against the validation schemas held in this repository:

```bash
npm run check-examples
```

Underneath that script the validator is invoked as `stac-node-validator examples --lint --verbose --schemas .`, pointing at the `examples/` folder and the schemas in the repository root. The same tool can rewrite files in place with `npm run format-examples`, and the schemas themselves are published to GitHub Pages by `publish-schemas`, which runs `node .circleci/publish-schemas.js`. A separate `remark` configuration lints the prose in the specification documents, with rules such as a 150 character maximum line length and a rule forbidding shell dollar signs in code blocks, which tells you the specification documents are held to the same house style as any other repository.

## Where STAC stops and what to check first

Three limits are worth naming before you commit. First, the specification does not order or deliver data. It describes metadata and discovery, so an Item tells you an asset exists and where it lives, and the actual retrieval path, authentication and storage are outside the scope. Second, if your use case depends on searching by spatial or temporal predicate across a large collection, the core catalog types are not enough and you need an implementation of the STAC API with a database behind it, which is a significantly larger commitment than publishing JSON files. Third, the object model is still evolving. The master branch is described as the stable version, currently 1.1.0, while the `dev` branch is where active development happens and may contain inconsistent examples; a release is cut and `dev` merged into `master` when development stabilises, so `master` should be stable at any given time. On maintenance, the last push was on 2026-10-10 and the latest release is v1.1.0 from 2024-09-11, which tells you the specification moves on a slow, deliberate cadence while the branch stays hot. The licence is Apache-2.0, a permissive choice for a standard that both providers and consumers implement, with the `LICENSE` file and a `CITATION.cff` in the repository root.

## Conclusion

STAC fits organisations that publish satellite, drone, lidar or vector holdings and want a documented format instead of a bespoke API, and teams that consume many providers and would otherwise write a parser per vendor. It does not fit teams that need spatial or temporal query over large holdings, because search lives in the separate STAC API specification and needs a service and a database behind it. Before adopting version 1.1.0, confirm the static catalog model covers your access patterns, check whether the extensions you need are published and stable, and run npm run check-examples against your own items so a schema error does not surface in a client.

## FAQ

### What is the difference between a STAC Item, Catalog and Collection?

An Item describes a single asset and is a GeoJSON Feature with extra fields. A Catalog is a JSON file of links that ties Items, Catalogs and Collections together for browsing. A Collection adds higher level information about a group of Items, such as extent, licence and keywords.

### Do I need to run a server to publish a STAC catalogue?

No. Because of the hierarchy between the object types, the README says a STAC catalog can be implemented in a completely static manner as a group of hyperlinked Catalog, Collection and Item URLs, so a publisher can expose data as browsable files. Search over those objects needs a STAC API implementation with a database.

### How can I validate my STAC items against the specification?

The repository ships stac-node-validator with the schemas, and the check-examples script lints the examples folder against them. Running npm run check-examples locally applies the same validation to your own files.

### Which version of the STAC specification should I implement?

The master branch is the stable version and is currently 1.1.0, while the dev branch carries active development and may have inconsistent examples. The specification follows Semantic Versioning, so a breaking change means a 2.0.0 release.

## Sources

- [License: Apache-2.0](https://github.com/radiantearth/stac-spec/blob/master/LICENSE)
- [Project website](https://stacspec.org)
- [radiantearth/stac-spec on GitHub](https://github.com/radiantearth/stac-spec)
- [README](https://github.com/radiantearth/stac-spec/blob/master/README.md)
- [Releases](https://github.com/radiantearth/stac-spec/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/radiantearth-stac-spec
