Discover / Marketing

schema-dts

by googleTypeScript

TypeScript typings for schema.org structured data used in AI search

Repositorystable

Maturity: stable because 8y old, v2.0.0 released 133d ago. Derived from release and commit history, not a rating.

Stars
1.2k
Forks
53
Downloads / mo
9.8M
Last commit
2026-06-29
License
Apache-2.0
Open issues
15

Market and trust evidence

Edition not yet matched

No exact skills.sh identity match is available for this repository. Repository adoption and freshness remain visible above; install momentum is not inferred.

Trust analysis is a screening signal, not a security warranty. Read the ranking and trust methodology.

In practice

Written by AI from this repository’s README · high confidence

JSON-LD written by hand has no type checking, so invalid Schema.org properties ship unnoticed.

Use it when

Use it when you build structured data in TypeScript and want completions and validation on Schema.org types.

Not the right pick when

The README states this is not an officially supported Google product, so support expectations should be set accordingly.

Capabilities

  • typings exposed as complete sets of discriminated type unions
  • WithContext helper to add @context to a top level item
  • MergeLeafTypes to combine multiple concrete @type values
  • Graph type for @graph objects with @id references and stubs
  • WithActionConstraints for -input and -output property annotations
  • schema-dts-gen command line tool to generate types for a schema version and layer

Cost: Free and open source

Install

Derived from the published package name in the repository, not from a model.

What the repository ships

CI configured

Detected from the actual files in the repository root.

Latest release v2.0.0

Published 2026-03-23

Changes in schema-dts

  • Supports the latest Schema.org release from Schema.org v30 -- See https://schema.org/docs/releases.html#v30.0
  • Input and Output constraints are now supported, for example:

    import type {SearchAction, WebSite, WithActionConstraints} from 'schema-dts';

    const potentialAction: WithActionConstraints<SearchAction> = {
      '@type': 'SearchAction',
      'query-input': 'required name=search_term_string',
      // ...
    };

    const website: WebSite = {
      '@type': 'WebSite',
      potentialAction: {
        '@type': 'SearchAction',
        'query-input': 'required name=search_term_string',
      } as WithActionConstraints<SearchAction>,
    };
  • Breaking change: Update typings for Roles so that they are not recursive, see #205 for more details
  • Breaking change: Quantity is now a core DataType, this is a change done in schema.org v30.0 and will technically make certain formerly-legal (but likely invalid) assignments no longer work
  • "Leaf" types are now exported. While objects like Thing or Organization require a type union that includes the object itself, it can also include any of its children. Now, if you want type something as a Thing _exactly_, you can import ThingLeaf which can only be a Thing and does not allow sub-types.
  • Support MergeLeafTypes, which fixes a long-running user request (#179 #189 #203), allowing a multi-typed schema object to be declared. Shout out to @mjy9088 and @cochinescu for the work to get this working. This allows declarations like this to be made:

    import type { MergeLeafTypes,ProductLeaf, SoftwareApplicationLeaf,  WithContext } from 'schema-dts';

    const app: WithContext<MergeLeafTypes<[ProductLeaf, SoftwareApplicationLeaf]>> =
      {
        '@context': 'https://schema.org',
        '@type': ['Product', 'SoftwareApplication'],
        name: 'My App',
        offers: {
          '@type': 'Offer',
          price: 89,
          priceCurrency: 'USD',
        },
        operatingSystem: 'Any',
      };

while #189 and #179 are not completely addressed since a random Thing cannot be a merged type, this allows some multi-type objects to exist, though they need to be explicitly declared as such by the developer.

  • Technically a breaking change: Some non-schema.org types exported in schema-dts are now renamed. These are included mostly for equivalence because the Schema.org ontology defines them, but most users should not depend on them. The names for these classes are now escaped fully-qualified IRIs instead of just the "in-context" name. This is needed because new types with the same "in-context" name have been added as external references, e.g. www.omg.org/spec/Commons/DatesAndTimes/Date which conflicts with schema.org/Date. Now, this is exported as www_omg_org_spec_Commons_DatesAndTimes_Date.

Changes in schema-dts-gen

  • Compatibility with Schema.org v30
  • Breaking change: schema.org/Quantity is now emitted as a DataType
  • Breaking change: out-of-context classes are now exported with an escaped fully-qualified IRI instead of just the hypothetical 'in-context' name. For example: www.omg.org/spec/Commons/DatesAndTimes/Date renders as Date if "@context": "www.omg.org/spec/Commons/DatesAndTimes/" only. Otherwise, it renders as namespace_Date if "@context" { "namespace": "www.omg.org/spec/Commons/DatesAndTimes/" }, and www_omg_org_spec_Commons_DatesAndTimes_Date if no context entry exists
  • Breaking change: the emitted output now depends on https://www.npmjs.com/package/schema-dts-lib -- the first two lines from the emitted output will include import type {...} from 'schema-dts-lib'; followed by export type { ... };.

What's Changed

  • Support Input and Output constraints by @Eptagone in https://github.com/google/schema-dts/pull/202
  • prevent Role

Tags

README

Build Status

Coverage Status

schema-dts npm version

schema-dts-gen version

schema-dts

JSON-LD TypeScript types for Schema.org vocabulary.

schema-dts provides TypeScript definitions for

Schema.org vocabulary in JSON-LD format. The typings are

exposed as complete sets of discriminated type unions, allowing for easy

completions and stricter validation.

Example of Code Completion using schema-dts

This repository contains two NPM packages:

command-line tool to generate TypeScript files based on a specific Schema

version and layer.

TypeScript typings of latest Schema.org schema, without

pending and other non-core layers.

Note: This is not an officially supported Google product.

Usage

To use the typings for your project, simply add the

schema-dts NPM package to your

project:


npm install --save-dev schema-dts

Then you can use it by importing "schema-dts".

Root context

You will usually want your top-level item to include a @context, like

https://schema.org. In order for your object type to accept this property, you

can augment it with WithContext, e.g.:


import type {Person, WithContext} from 'schema-dts';

const p: WithContext<Person> = {
  '@context': 'https://schema.org',
  '@type': 'Person',
  name: 'Eve',
  affiliation: {
    '@type': 'School',
    name: 'Nice School',
  },
};

Merging multiple concrete types

Some Schema.org objects can legitimately carry multiple concrete @type values.

For those advanced cases, schema-dts exports leaf types alongside the usual

union aliases, plus a MergeLeafTypes helper for combining them:


import type {
  MergeLeafTypes,
  ProductLeaf,
  SoftwareApplicationLeaf,
  WithContext,
} from 'schema-dts';

const product: WithContext<
  MergeLeafTypes<[ProductLeaf, SoftwareApplicationLeaf]>
> = {
  '@context': 'https://schema.org',
  '@type': ['Product', 'SoftwareApplication'],
  name: 'My App',
  offers: {
    '@type': 'Offer',
    price: 89,
    priceCurrency: 'USD',
  },
  operatingSystem: 'Any',
};

MergeLeafTypes expects concrete leaf types such as ProductLeaf, not union

aliases such as Product.

Graphs and IDs

JSON-LD supports '@graph' objects that have richer interconnected links

between the nodes. You can do that easily in schema-dts by using the Graph

type.

Notice that any node can have an @id when defining it. And you can reference

the same node from different places by simply using an ID stub, for example

{ '@id': 'https://my.site/about/#page } below is an ID stub.

The example below shows potential JSON-LD for an About page. It includes

definitions of Alyssa P. Hacker (the author & subject of the page), the specific

page in this URL, and the website it belongs to. Some objects are still defined

as inline nested objects (e.g. Occupation), since they are only referenced by

their parent. Other objects are defined at the top-level with an @id, because

multiple nodes refer to them.


import type {Graph} from 'schema-dts';

const graph: Graph = {
  '@context': 'https://schema.org',
  '@graph': [
    {
      '@type': 'Person',
      '@id': 'https://my.site/#alyssa',
      name: 'Alyssa P. Hacker',
      hasOccupation: {
        '@type': 'Occupation',
        name: 'LISP Hacker',
        qualifications: 'Knows LISP',
      },
      mainEntityOfPage: {'@id': 'https://my.site/about/#page'},
      subjectOf: {'@id': 'https://my.site/about/#page'},
    },
    {
      '@type': 'AboutPage',
      '@id': 'https://my.site/#site',
      url: 'https://my.site',
      name: "Alyssa P. Hacker's Website",
      inLanguage: 'en-US',
      description: 'The personal website of LISP legend Alyssa P. Hacker',
      mainEntity: {'@id': 'https://my.site/#alyssa'},
    },
    {
      '@type': 'WebPage',
      '@id': 'https://my.site/about/#page',
      url: 'https://my.site/about/',
      name: "About | Alyssa P. Hacker's Website",
      inLanguage: 'en-US',
      isPartOf: {
        '@id': 'https://my.site/#site',
      },
      about: {'@id': 'https://my.site/#alyssa'},
      mainEntity: {'@id': 'https://my.site/#alyssa'},
    },
  ],
};

Input and Output constraints

Actions support additional information to describe inputs and outputs, so each

property can be annotated using -input and -output suffixes and you can do

that in schema-dts by using the WithActionConstraints type for each action

type you want to annotate. See the following examples:


import type {SearchAction, WithActionConstraints} from 'schema-dts';

const potentialAction: WithActionConstraints<SearchAction> = {
  '@type': 'SearchAction',
  'query-input': 'required name=search_term_string',
  // ...
};

import type {SearchAction, WebSite, WithActionConstraints} from 'schema-dts';

const website: WebSite = {
  '@type': 'WebSite',
  potentialAction: {
    '@type': 'SearchAction',
    'query-input': 'required name=search_term_string',
  } as WithActionConstraints<SearchAction>,
};

Real-world examples

Below are common patterns for using schema-dts types when building JSON-LD for

real websites.

Organization and WebSite (every site should have these)

import type {Organization, WebSite, WithContext} from 'schema-dts';

const org: WithContext<Organization> = {
  '@context': 'https://schema.org',
  '@type': 'Organization',
  name: 'Acme Corp',
  url: 'https://acme.com',
  logo: 'https://acme.com/logo.png',
  sameAs: ['https://twitter.com/acme', 'https://www.linkedin.com/company/acme'],
};

const site: WithContext<WebSite> = {
  '@context': 'https://schema.org',
  '@type': 'WebSite',
  name: 'Acme Corp',
  url: 'https://acme.com',
};
Product with Offer (e-commerce)

import type {Product, WithContext} from 'schema-dts';

const product: WithContext<Product> = {
  '@context': 'https://schema.org',
  '@type': 'Product',
  name: 'Classic Leather Wallet',
  description: 'Full-grain leather bifold wallet with RFID blocking.',
  image: 'https://shop.example/images/wallet.jpg',
  sku: 'WALLET-001',
  brand: {
    '@type': 'Brand',
    name: 'Example Shop',
  },
  offers: {
    '@type': 'Offer',
    price: 89,
    priceCurrency: 'USD',
    availability: 'https://schema.org/InStock',
    url: 'https://shop.example/products/classic-wallet',
  },
};
FAQPage (content sites)

import type {FAQPage, WithContext} from 'schema-dts';

const faq: WithContext<FAQPage> = {
  '@context': 'https://schema.org',
  '@type': 'FAQPage',
  mainEntity: [
    {
      '@type': 'Question',
      name: 'Do you ship internationally?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Yes, we ship to over 50 countries.',
      },
    },
    {
      '@type': 'Question',
      name: 'What is your return policy?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'We offer a 30-day return policy on all items.',
      },
    },
  ],
};
Article (blog posts)

import type {Article, WithContext} from 'schema-dts';

const article: WithContext<Article> = {
  '@context': 'https://schema.org',
  '@type': 'Article',
  headline: 'How to choose a leather wallet',
  datePublished: '2026-03-01',
  dateModified: '2026-03-15',
  author: {
    '@type': 'Person',
    name: 'Jane Smith',
    url: 'https://blog.example/authors/jane',
  },
  image: 'https://blog.example/images/wallet-guide.jpg',
  description: 'A practical guide to choosing a leather wallet that lasts.',
};
Injecting JSON-LD into HTML

When serializing JSON-LD for injection into a <script> tag, escape characters

that could break out of the tag or enable XSS:


function safeJsonLd(data: WithContext<Thing>): string {
  return JSON.stringify(data)
    .replace(/</g, '\\u003C')
    .replace(/>/g, '\\u003E')
    .replace(/&/g, '\\u0026')
    .replace(/'/g, '\\u0027');
}

// Use in HTML:
// <script type="application/ld+json">${safeJsonLd(product)}</script>

Tip: See examples.md for more integration patterns,

including React, Next.js, Astro, and other frameworks.

Schema Typings Generator

The Schema Typings Generator is available in the

schema-dts-gen package.


npm install --save-dev schema-dts-gen
npx schema-dts-gen --ontology=https://schema.org/version/latest/schemaorg-all-https.nt

Command line usage:

  • Specify your ontology
  • Specify --ontology: An HTTPs URL to an .nt NTriple file declaring your

ontology.

Must be compatible with Schema.org, including the Schema.org DataTypes and

specifying a top-level Thing type.

  • --context: Defaults to https://schema.org, the value or values to be

used with the "@context" property.

Can be either a single URL, or a comma separated list of two or more name:URL

pairs.

The context affects names of string properties in types, as well as the values

of an object's "@type".

  • --deprecated/--nodeprecated: Whether or not to include deprecated

Schema.org types and properties. When included, these types will still be

marked with @deprecated JSDOC tags.

  • --verbose: Outputs additional logs and debugging notes to stderr.

Developers

Use NPM to install dependencies:


npm install

We have wrappers around tsc and tsc --build to build our generator other

.d.ts files.

To generate TypeScript from the latest Schema.org Schema:


npm run build-gen && npm run build-schema

or simply build the schema-dts generator:


npm run build-gen

To contribute changes, see the CONTRIBUTING.md file.

Related tools