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

commonmeta-schema

v1.0.0-rc30

Published

Commonmeta JSON Schemas and conformance fixtures

Readme

commonmeta-schema

Language-neutral JSON Schema definitions and conformance fixtures for Commonmeta, the scholarly metadata interchange format.

This repository is the shared source of truth consumed by the following Commonmeta implementations:

Keeping the schema and the golden fixtures in one place lets every implementation validate against the same contract and run the same cross-format conformance tests.

Layout

schemas/
  commonmeta_v1.0.json         # the Commonmeta JSON Schema (current)
  commonmeta_v1.0rc*.json      # earlier release candidates, retained but not exported
fixtures/
  commonmeta/                  # canonical Commonmeta records (round-trip + expected output)
  <format>/                    # input fixtures in a given source format
  <format>_out/                # expected writer output (Commonmeta -> format)
  <format>_commonmeta/         # expected reader output for non-JSON inputs
  utils/                       # shared utility fixtures for helpers outside format conversion

Schema versions

Schemas are versioned by filename. The current version is commonmeta_v1.0.json, and the schema_version field of a Commonmeta record is the URL https://commonmeta.org/commonmeta_v1.0.json.

Earlier release candidates (commonmeta_v1.0rc1rc7) are kept in schemas/ for reference, but the packages export only v1.0 — new versions are added alongside existing files rather than replacing them, so implementations can pin a version.

Fixture conventions

The conformance harness in each implementation follows these naming rules (a missing pair is skipped, so partial coverage is fine):

| Test kind | Input | Expected | |----------------------|----------------------------------------|---------------------------------------------| | Round-trip | fixtures/commonmeta/<name>.json | itself (re-serialized, semantically equal) | | Reader (JSON input) | fixtures/<format>/<name>.json | fixtures/commonmeta/<name>.json | | Reader (text input) | fixtures/<format>/<name>.<ext> | fixtures/<format>_commonmeta/<name>.json | | Writer | fixtures/commonmeta/<name>.json | fixtures/<format>_out/<name>.<ext> |

Formats currently covered: crossref, crossref_xml, datacite, datacite_xml, schemaorg, csl, bibtex, cff, ris, jsonfeed, inveniordm, codemeta, orcid, orcid_xml, openalex_source.

OpenAlex scope

The openalex_source fixtures cover OpenAlex sources/containers (for example journal, repository, and blog containers), not OpenAlex works.

  • fixtures/openalex_source/*.json are OpenAlex source records (S... IDs).
  • fixtures/commonmeta/openalex_source_*.json are the expected Commonmeta container entities.

OpenAlex works should be added under a separate format namespace (for example openalex_work) to keep reader and writer behavior unambiguous.

Most fixtures are work entities; orcid and orcid_xml cover person instead. Both read a full ORCID record — with employments and educations as affiliations — from two different sources:

  • orcid/<id>.json is the ORCID REST API /record response (JSON). Because it carries the full person, its commonmeta output also has description and urls. → commonmeta/<id>.json
  • orcid_xml/<id>.xml is the ORCID Public Data File record (XML), a summary that omits biography and researcher URLs. → orcid_xml_commonmeta/<id>.json

Both fixtures trim the record's works list to the 10 most recent (the readers convert person identity and affiliations, not works).

Semantic comparison

Fixtures are compared as parsed JSON trees, not as strings, using an omitempty-aware and numeric-aware diff: key order and whitespace are irrelevant, an absent field equals an empty/zero/null value, and 52 equals 52.0. This keeps hand-authored fixtures robust across implementations.

Utility fixtures

fixtures/utils/ is reserved for shared cross-implementation test data for helper functions outside reader/writer format conversion. The first use is DOI helper coverage for encode_doi and decode_doi. These fixtures are not reader/writer conformance cases; they exist so commonmeta-py and commonmeta-rs can assert the same normalization, checksum, and error handling behavior from one canonical source.

Using this repository

Each implementation vendors (copies) the schema and fixtures it needs from here. Update the canonical files in this repository first, then sync them into commonmeta-rs and commonmeta-py.

Packaging and publishing

This repository can be published as both:

  • a Python package on PyPI (commonmeta-schema)
  • a Rust crate on crates.io (commonmeta-schema)
  • a JavaScript package on npm (commonmeta-schema)

Publishing is done explicitly via CLI (no automated release pipeline in this repo).

The packages are release candidates on the way to 1.0; both ship the v1.0 schema:

  • PyPI uses PEP 440 form: 1.0rc30
  • crates.io uses SemVer form: 1.0.0-rc30
  • npm uses SemVer form: 1.0.0-rc30

scripts/sync_versions.py is the single entry point for preparing a release. It does three things, in this order:

  1. Rewrites schemas/commonmeta_v1.0.json from the newest commonmeta_v1.0rc*.json, resetting $id, title, and the schema_version const to the stable v1.0 URL.
  2. Mirrors the canonical schemas/ and fixtures/ into rust/schemas/ and rust/fixtures/ (the crate can only package files under rust/).
  3. Syncs rust/Cargo.toml's version with pyproject.toml's.
  4. Syncs package.json's version with pyproject.toml's.
python scripts/sync_versions.py

The ordering matters and is why the mirror lives in the script rather than in a separate rsync step: mirroring before step 1 ships a crate whose commonmeta_v1.0.json still carries the previous rc's schema_version const, which then rejects the crate's own v1.0-stamped fixtures.

To verify sync in CI/local checks without changing files:

python scripts/sync_versions.py --check

Recommended pre-release checks:

python scripts/sync_versions.py --check
uv build
cargo test --manifest-path rust/Cargo.toml
cargo package --manifest-path rust/Cargo.toml
npm pack --dry-run

JavaScript / TypeScript (npm)

Install:

npm install commonmeta-schema

Read packaged assets by path:

import { readFileSync } from "node:fs";
import { fixturesPath, schemaPath } from "commonmeta-schema";

const schema = JSON.parse(readFileSync(schemaPath("1.0"), "utf8"));
const fixture = JSON.parse(
  readFileSync(`${fixturesPath("commonmeta")}/journal_article.json`, "utf8")
);

Or import JSON files directly from subpath exports:

import schema from "commonmeta-schema/schemas/commonmeta_v1.0.json" with { type: "json" };

The helper API mirrors the Python package and exports packageRoot, schemaPath(version), fixturesPath(formatName), and availableSchemaVersions().

Python (PyPI) via uv publish

  1. Ensure you are authenticated for PyPI (recommended: trusted publisher or API token).
  2. Build distribution artifacts:
uv build
  1. Optionally validate the build metadata:
uvx twine check dist/*
  1. Publish to PyPI:
uv publish

Rust (crates.io) via cargo publish

  1. Log in once with a crates.io token:
cargo login
  1. Validate package contents:
cargo package --manifest-path rust/Cargo.toml --allow-dirty
  1. Publish:
cargo publish --manifest-path rust/Cargo.toml

JavaScript / TypeScript (npm) via npm publish

  1. Validate package contents:
npm pack --dry-run
  1. Publish:
npm publish

Recommended release order

  1. Publish 1.0rc30 to PyPI with uv publish.
  2. Publish 1.0.0-rc30 to crates.io with cargo publish.
  3. Publish 1.0.0-rc30 to npm with npm publish.
  4. Create a git tag v1.0rc30 after all uploads succeed.

Copy-paste release run

Run this from the repository root:

set -euo pipefail

# 1) Regenerate the v1.0 alias, mirror assets into rust/, sync the crate version
python scripts/sync_versions.py

# 2) Fail the release if anything is still out of sync
python scripts/sync_versions.py --check

# 3) Validate both package builds
uv build
cargo test --manifest-path rust/Cargo.toml
cargo package --manifest-path rust/Cargo.toml
npm pack --dry-run

# 4) Publish Python package
uv publish

# 5) Publish Rust crate
cargo publish --manifest-path rust/Cargo.toml

# 6) Publish npm package
npm publish

# 7) Tag release (replace with the release version)
git tag v1.0rc30
git push origin v1.0rc30

License

MIT © 2026 Front Matter