In modern web development, it’s common to work with complex data that must be transmitted between different applications. JSON has proven to be an excellent standardized serialization process for exchanging wire data between applications.
However, with this increased complexity in wire data comes a corresponding lack of security. While JSON is flexible, it doesn’t provide any protection for your data. We then face the challenge of ensuring that the data we transmit between applications adhere to a known schema.
This uncertainty can prove problematic, especially for applications that take data security very seriously. So how do we address this?
JSON Schema provides a solution to the aforementioned security concern. It allows us to define a strict structure for the wire data transmitted between communicating applications.
Throughout this article, we’ll explore how to generate and work with JSON Schema using TypeScript types. Jump ahead:
You can check out the full project code in this GitHub repository.
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
Before we delve into JSON Schema as a solution, let’s first answer the question, what exactly is JSON Schema?
JSON Schema is an established specification that helps us to define the structure of JSON data. We define what properties the data should have, what data type we expect those properties should be, and how they should be validated.
By using the Schema, we ensure that the wire data our application is accepting is formatted correctly and that any possible errors are caught early in our development process. So, where does TypeScript fit into the picture?
TypeScript provides a static type-checking feature that validates the type consistency of variables, function parameters, and return values at compile-time. By using tools that can convert TypeScript types into JSON Schemas, we can ensure our wire data adheres to a strict schema.
In this section, we will explore how we can generate JSON Schema from our defined TypeScript types we’ll define.
We will use the ts-json-schema-generator library, which supports a wide range of TypeScript features, including interfaces, classes, enums, unions, and more. However, it’s worth noting that there are various other developer tools you can use to achieve the same result.
Let’s start by creating a new project folder named json-schema-project and running an init command within the new directory to initialize a new project:
mkdir json-schema-project; cd json-schema-project; npm init -y
Now we have set up our project, let’s install the ts-json-schema-generator library:
npm install -g ts-json-schema-generator
Once we’ve installed the library, we can use it to generate JSON Schema from our TypeScript types.
Let’s start by creating a simple TypeScript file named types.ts within the src folder. Within this file, we’ll write a simple TypeScript interface:
export interface Person {
firstName: string;
lastName: string;
age: number;
socials: string[];
}
In the above snippet, we defined a Person object using TypeScript’s interface. Note the types of each property within the interface.
ts-json-schema-generator packageNext, let’s use the ts-json-schema-generator package to generate a JSON Schema for the Person interface. We will use this command:
ts-json-schema-generator --path 'src/types.ts' --type 'Person'
This command will instruct the ts-json-schema-generator package to generate a JSON Schema for the Person type in the src/types.ts file.
If the command runs successfully, the result will be the below JSON object that represents the generated JSON Schema:
{
"$ref": "#/definitions/Person",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Person": {
"additionalProperties": false,
"properties": {
"age": {
"type": "number"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"socials": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [ "firstName", "lastName", "age", "socials"],
"type": "object"
}
}
}
Now, with this schema, we can specify that any object that claims to be of the type Person should have certain properties. These include firstName and lastName properties of type string, an age property of type number, and a socials property comprising an array of strings.
To further understand the JSON Schema, let’s take a look at different fields of the JSON Schema object and what they stand for:
$schema: Specifies the version of the JSON Schema specification being used — in this case, v7type: Specifies the type of object being described by the schema — in this case, an objectproperties: An object that describes the properties of the object being described by the schema — in this case, name, age, and hobbiesrequired: An array that specifies which properties of the object are required — in this case, all three properties are requiredNow that we have seen how to generate JSON Schema from TypeScript, we can go further to see how to use it and validate data ensuring it conforms to the expected schema that we have.
For the following example, we will programmatically use the ts-json-schema-generator package alongside the ajv schema validation package:
import Ajv from 'ajv';
import { createGenerator } from 'ts-json-schema-generator';
import path from 'path';
const repoRoot = process.cwd();
const config = {
path: path.join(repoRoot, "src", "types.ts"),
tsconfig: path.join(repoRoot, "tsconfig.json"),
type: "Person",
};
const schema = createGenerator(config).createSchema("Person")
const validate = (data: any) => {
const ajv = new Ajv();
const validateFn = ajv.compile(schema);
return validateFn(data);
};
const person = {
firstName: 'Alice',
lastName: 'Chapman',
age: 30,
socials: ['github', 'twitter']
};
console.log(validate(person)); // true
In the above snippet, we defined a few configurations:
tsconfig.json fileNote that if we want to generate JSON Schema for all types and we have more than one type definition, we can use * as the value instead of Person.
Using the createSchema method of the SchemaGenerator type, we create a JSON Schema object for the Person type and store it in the constant variable, schema.
Then, within the validate function, we use the compile method on the Ajv object to compile the JSON Schema. We then use the resulting validator function — validateFn — to validate any data sample.
To see a more practical use case, let’s modify the previous snippet by adding a middleware function to a web server. This middleware will validate the wire data against the existing JSON Schema we have:
// --snip--
import express, { Request, Response, NextFunction } from 'express';
import { Person } from "./types";
const repoRoot = process.cwd();
const configType = "Person";
const config = {
path: path.join(repoRoot, "src", "types.ts"),
tsconfig: path.join(repoRoot, "tsconfig.json"),
type: configType,
};
const schema = createGenerator(config).createSchema(configType);
const app = express();
app.use(express.json());
// Middleware to validate incoming payload against JSON Schema
const validatePayload = (req: Request, res: Response, next: NextFunction) => {
const ajv = new Ajv();
const validateFn = ajv.compile(schema);
if (!validateFn(req.body)) {
return res.status(400).json({ error: 'Invalid payload' });
}
next();
};
// Endpoint that accepts User payloads
app.post('/users', validatePayload, (req: Request, res: Response) => {
const newUser = req.body as Person;
// Do something with newUser
res.json(newUser);
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
The above snippet defined a middleware — validatePayload — that checks if the incoming payload conforms to the generated JSON Schema. If not, it returns a 400 error response.
Then, within the POST /users endpoint, we use the middleware to verify that the wire data sent conforms to the schema definition. This way, we’re able to prevent errors that can happen as a result of unexpected payloads, thereby improving the overall reliability of the API.
Start the web server using the below command:
npx ts-node .
Make sure to set the value of the main field in the package.json file to src/index.ts. We’ll use Postman to test our implementation:

In the above screenshot, we can see the result of calling our endpoint with an unexpected request body results in a 400 error response, as it should. Next, let’s send the expected payload to the endpoint:

As we can see, we get the expected 200 status response, indicating a successful request.
We looked at how to create JSON Schema from TypeScript types in this article.
We can guarantee that our data follows a rigorous schema and take advantage of TypeScript’s static type-checking by utilizing TypeScript types to build JSON Schema. This ensures that our data is both well-structured and type-safe.
Generating JSON Schema from TypeScript types can help prevent errors both client-side and server-side, as any data that does not conform to the schema will be rejected. It also helps with documentation, as clients can easily see the expected structure of the data they need to send.
Here’s the GitHub repository containing the full source files for the code examples in this article.
LogRocket lets you replay user sessions, eliminating guesswork by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks, and with plugins to log additional context from Redux, Vuex, and @ngrx/store.
With Galileo AI, you can instantly identify and explain user struggles with automated monitoring of your entire product experience.
Modernize how you understand your web and mobile apps — start monitoring for free.

CSS text-wrap: balance vs. text-wrap: prettyCompare and contrast two CSS components, text-wrap: balance and text-wrap: pretty, and discuss their benefits for better UX.

Remix 3 ditches React for a Preact fork and a “Web-First” model. Here’s what it means for React developers — and why it’s controversial.

A quick guide to agentic AI. Compare Autogen and Crew AI to build autonomous, tool-using multi-agent systems.

Compare the top AI development tools and models of November 2025. View updated rankings, feature breakdowns, and find the best fit for you.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now
2 Replies to "Generating JSON Schema from TypeScript types"
This approach should mention the alternative: runtime typescript types. This other article explains the pros/cons well: https://blog.logrocket.com/methods-for-typescript-runtime-type-checking/
What about this one?
https://typia.io/docs/json/schema/