Discover / Marketing
schema-dts
by googleTypeScript
TypeScript typings for schema.org structured data used in AI search
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 matchedNo 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 confidenceJSON-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
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
ThingorOrganizationrequire a type union that includes the object itself, it can also include any of its children. Now, if you want type something as aThing_exactly_, you can importThingLeafwhich 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/Datewhich conflicts withschema.org/Date. Now, this is exported aswww_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/Daterenders asDateif"@context": "www.omg.org/spec/Commons/DatesAndTimes/"only. Otherwise, it renders asnamespace_Dateif"@context" { "namespace": "www.omg.org/spec/Commons/DatesAndTimes/" }, andwww_omg_org_spec_Commons_DatesAndTimes_Dateif 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 includeimport type {...} from 'schema-dts-lib';followed byexport type { ... };.
What's Changed
- Support Input and Output constraints by @Eptagone in https://github.com/google/schema-dts/pull/202
- prevent
Role
Tags
README
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:
- schema-dts-gen Providing a
command-line tool to generate TypeScript files based on a specific Schema
version and layer.
- schema-dts Pre-packaged
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.mdfor 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 tohttps://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.