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

@tracepass/dpp-schemas

v1.0.0

Published

Machine-readable field specifications for EU Digital Product Passports (ESPR) — 13 product categories, 1004 fields, each traced to the article of EU law that mandates it. Pure JSON, no dependencies.

Downloads

1,886

Readme

EU Digital Product Passport — Field Specifications

Machine-readable field specs for 12 product categories, with every field traced to the article of EU law that mandates it.

License npm Fields Categories Dependencies Schema

Maintained by TracePass · Platform · API docs


What is a Digital Product Passport?

A Digital Product Passport (DPP) is a structured, machine-readable record of a product's composition, origin, environmental performance, and end-of-life handling, accessible by scanning a data carrier on the product — usually a QR code.

It is mandated by the EU's Ecodesign for Sustainable Products Regulation (ESPR), Regulation (EU) 2024/1781, and by product-specific instruments such as the EU Battery Regulation (EU) 2023/1542. Different product categories become mandatory on different dates: battery passports are required from 18 February 2027, with textiles, steel, packaging, construction, and others following.

The hard part of implementing one is not the QR code. It is knowing which fields your product category legally requires, and which article mandates each one. That is what this repository contains.

What's in here

Twelve JSON files, one per product category. 937 fields in total. 302 are required by an instrument in force; 198 are anticipated under a rule that has not yet been adopted.

| Category | Fields | Required | Instrument | |---|---:|---:|---| | battery | 119 | 54 | Regulation (EU) 2023/1542 | | chemicals | 96 | 28 | ESPR (EU) 2024/1781 | | construction | 49 | 43 | CPR (EU) 2024/3110 | | electronics | 167 | 20 | ESPR (EU) 2024/1781 | | fmcg | 42 | 11 | ESPR (EU) 2024/1781 | | furniture | 79 | 27 | ESPR (EU) 2024/1781 | | jewelry | 52 | 12 | ESPR (EU) 2024/1781 | | packaging | 66 | 9 | PPWR (EU) 2025/40 | | steel | 84 | 29 | ESPR (EU) 2024/1781 | | textile | 60 | 12 | ESPR (EU) 2024/1781 | | toys | 28 | 14 | ESPR (EU) 2024/1781 | | tyres | 95 | 43 | ESPR (EU) 2024/1781 |

Battery is the only category whose obligation is already in force — Regulation (EU) 2023/1542 Art. 77 applies from 18 February 2027, rather than awaiting a delegated act. That is why its required count is the highest of the twelve. It is not the case that every battery field is required: the template also carries fields that are anticipated (pending the carbon-footprint and due-diligence implementing acts) and fields that apply only to some battery sub-categories via validation.requiredBy.

required means an instrument in force compels the data. ESPR (EU) 2024/1781 is a framework: it mandates no field directly, and every Digital Product Passport obligation flows through a delegated act adopted under its Article 4. No product-group delegated act has been adopted. Fields expected under a future act carry validation.anticipated rather than required, with the CELEX of the instrument expected to impose them.

An obligation does not always apply uniformly across a category. Where the governing instrument distinguishes sub-categories, the field carries validation.requiredBy — a map from sub-category to required, conditional, or notApplicable. Battery uses the Regulation (EU) 2023/1542 split (EV, LMT, industrial_gt_2kwh): everything applies to EV batteries, LMT is exempt from the capacity-threshold-for-exhaustion field, and industrial batteries are largely conditional on gates such as having a battery management system or containing Annex X materials. conditional means the instrument compels the field only when its stated gate is met — so a passport legitimately leaves it empty otherwise. Fields with no requiredBy apply to the whole category.

What a field looks like

// templates/battery.json → fields[]
{
  "key": "ratedCapacity",
  "label": {
    "en": "Rated Capacity",
    "de": "Nennkapazität",
    "bg": "Номинален капацитет"
    // ... 21 more, one per official EU language
  },
  "dataType": "number",
  "unit": "Ah",
  "validation": { "required": true, "min": 0, "max": null },
  "defaultAccessLevel": "public",
  "regulationRef": { "article": "Art. 77", "annex": "Annex VI" },
  "aiHints": {
    "alternateNames": ["capacity", "nominal capacity", "battery capacity", "Ah rating"],
    "expectedFormat": "Numeric value in Ah",
    "extractionPriority": 9
  }
}

Five things are worth pointing out.

regulation.effectiveDate is the date the passport obligation begins — not the date the regulation applies. Those are different dates and can sit years apart. PPWR (EU) 2025/40 has applied since 12 August 2026, but its packaging DPP provisions phase in from 2027, so packaging carries 2027, not 2026-08-12.

Read both dates with their precision marker. datePrecision / mandatoryDatePrecision are "day" or "year"; absent means "day":

  • "day" — a real statutory date. Battery is 2027-02-18, set by ESPR Article 77.
  • "year" — only the year is known, because the governing delegated or implementing act is not yet adopted. The day and month are filler. Do not render these as a deadline. Eleven of the twelve categories are currently "year"; only battery is "day".
r = template["regulation"]
if r.get("datePrecision", "day") == "year":
    print(f"DPP obligation expected in {r['effectiveDate'][:4]}")   # "2027"
else:
    print(f"DPP obligation from {r['effectiveDate']}")              # "2027-02-18"

Upgrading from 0.3.x? The date values did not change and no key was removed, so code that reads this data keeps working. One case does break: if you vendored a copy of schema.json from 0.3.x and validate 0.4.0 template data against it, eleven of the twelve templates are rejected — that version closed the regulation object with additionalProperties: false, so the new precision keys are refused. Take the schema.json shipped in this package alongside the data. From 0.4.1 the regulation object is open, so later additive keys will not do this again.

regulationRef is the reason this data is worth having. Every field says which article and annex mandates it, so a compliance report can cite its source rather than assert it.

label is provided in the 24 official EU languages, because ESPR Article 8 requires the passport to be available in the language of the member state where the product is placed on the market.

defaultAccessLevel encodes who may read the field: public (anyone scanning the QR code), restricted (holders of a granted token, such as a recycler), or authority (market-surveillance bodies). A DPP is not one document — it is several views of one record.

aiHints lists the synonyms a supplier datasheet might use for the field. If you are extracting values from unstructured PDFs, these are the search terms that work.

No build step

There is nothing to compile and nothing to install. Read the JSON.

curl -O https://raw.githubusercontent.com/malinoto/tracepass-dpp-schemas/main/templates/battery.json
import json, urllib.request

url = "https://raw.githubusercontent.com/malinoto/tracepass-dpp-schemas/main/templates/battery.json"
template = json.load(urllib.request.urlopen(url))

required = [f for f in template["fields"] if f["validation"]["required"]]
print(f"{template['category']}: {len(required)} required fields under {template['regulation']['number']}")

for f in required[:3]:
    ref = f.get("regulationRef") or {}
    print(f"  {f['key']:24} {ref.get('article', '—')}  {ref.get('annex', '')}")

For TypeScript users, @tracepass/dpp-schemas ships the same files on npm, and @tracepass/dpp-types provides the matching types.

npm install @tracepass/dpp-schemas

Validating the specs themselves

schema.json is a JSON Schema (Draft 2020-12) describing the template format. All 12 templates validate against it — which is how the format stays honest.

pip install jsonschema
python -c "
import json, glob
from jsonschema import Draft202012Validator
v = Draft202012Validator(json.load(open('schema.json')))
for p in sorted(glob.glob('templates/*.json')):
    errs = list(v.iter_errors(json.load(open(p))))
    print(('ok   ' if not errs else 'FAIL '), p)
"

Two conventions the schema pins down, both of which will bite you otherwise:

  • Absent optional values are explicit null, not omitted keys. A field with no unit carries "unit": null. A validation rule with no upper bound carries "max": null. Treat null as no constraint, and be careful not to coerce it to 0.
  • Dates are ISO 8601 strings ("2027-02-18"), not timestamps.

Related

  • tracepass-open — the compliance validator, EPCIS 2.0 event mapper, and GS1 utilities that consume these specs. Apache-2.0, zero dependencies.

Provenance and limits

These specs are hand-authored from the regulations and the relevant standards, and are cross-checked against published guidance where it exists — the battery template against the Battery Pass Consortium content guidance, for instance. They are maintained because TracePass runs a DPP compliance platform on them.

They are not legal advice, and not an official EU artefact. Delegated acts are still landing and several categories have no delegated act yet; where a field anticipates one, the regulationRef cites the parent instrument. Verify against EUR-Lex before relying on any single field for a market-placement decision. Corrections are welcome — open an issue.

Contributing

Corrections to a field's regulatory citation, datatype, or translation are the most valuable contributions. Open an issue with the article you're citing, or a pull request that keeps schema.json passing.

License

Apache-2.0. Use them, fork them, ship them in a commercial product.