Yup: runtime schema validation for TypeScript, and where the type inference stops
Dead simple Object schema validation
At a glance
- What is it?
- Yup builds runtime schemas that cast and validate values, and its InferType helper turns those schemas back into static types. The mechanism is compact, but the gap between cast and strict validate is where most surprises live.
- Who is it for?
- Adopt Yup if you already write TypeScript and want one schema to serve both runtime validation and static inference, especially for form or API payload checks. Skip it if your inputs are untrusted and you need structural validation with coercion rules you can audit line by line, since cast silently rewrites values.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Yup is for, and who ends up using it
Yup is a schema builder for runtime value parsing and validation. You describe the shape of an object once, then use that description to coerce an incoming value, assert that a value already has the right shape, or both. The package is written in TypeScript and published under MIT, so it slots into a typed codebase without a separate type definition package.
The people who reach for it are usually holding a value whose type the compiler cannot see. A form submission, a JSON response, a query string parsed into an object. TypeScript erases at runtime, so a field declared as number can still arrive as the string "24". Yup closes that gap by giving you an object that exists at runtime and that the compiler can also read types from. The README calls the schema interface concise and expressive, and the examples bear that out: object, string, number, date, chained with required, positive, integer, email, url, nullable, default.
It is not a general-purpose validator for arbitrary untrusted input. It is a schema builder for shaped objects, and its ergonomics assume you know roughly what you are receiving.
Transforms and tests: the two halves of a Yup schema
Every Yup schema is a chain of two kinds of operation. Transforms are parsing actions: they change the value. Tests are assertions: they check the value and produce an error if it fails. The README states this split directly, and it explains most of the library's behaviour.
When you call validate, Yup first runs the transforms, then the tests. That ordering is why a string like "24" can pass a number().required().positive().integer() schema: the number type coerces it before the assertions run. When you call cast, only the transforms run. No assertions are made, so cast never throws for a value that is the wrong shape; it just returns whatever the coercion produced.
The distinction matters because an API boundary and a form boundary want different things. At an API boundary you may want to reject anything that is not already the right type. At a form boundary you want to accept the string the input element gave you and normalize it. Yup supports both, but the default is the lenient one, and the lenient path is the one people reach for without noticing.
InferType and the TypeScript contract
The README's headline example defines a userSchema and then extracts a type from it with InferType. The inferred type is not a copy of the schema written by hand. It reflects the modifiers: name is string, age is number, email is string | undefined because it was not marked required, website is string | null | undefined because it is nullable, and createdOn is Date because the default supplies a value.
That is the strongest reason to pick Yup over a plain assertion library. The schema is the single source of truth, and the type follows from it. Change required to notRequired and the inferred type changes with it, which means a stale type cannot drift away from a stale schema.
There is a second direction too. The README documents ensuring that a schema matches an existing type, so you can start from an interface and confirm the schema implements it rather than inferring from scratch. For codebases that already have a domain type, that ordering avoids inventing a second definition. The README also covers extending built-in schema with new methods, which is what addMethod is for, and notes a TypeScript configuration section for the compiler settings the library expects.
Installing Yup and validating a first payload
Yup is published to npm under the name yup. The README's examples import from 'yup' directly, and package.json lists the entry points as lib/index.js for CommonJS and lib/index.esm.js for ESM, so both module systems are covered.
npm install yupWith the package installed, the README's getting-started example is the shortest path to a working schema. It defines an object schema with a required string, a required positive integer, an optional email, a nullable URL, and a date that defaults to the current time.
import { object, string, number, date, InferType } from 'yup';
let userSchema = object({
name: string().required(),
age: number().required().positive().integer(),
email: string().email(),
website: string().url().nullable(),
createdOn: date().default(() => new Date()),
});
type User = InferType<typeof userSchema>;From there, the README shows two ways to use the schema. The first coerces an input that has the right values in the wrong types. The second asserts that the input is already parsed.
// Attempts to coerce values to the correct type
let parsedUser = userSchema.cast({
name: 'jimmy',
age: '24',
createdOn: '2014-09-23T19:25:25Z',
});
// { name: 'jimmy', age: 24, createdOn: Date }// ValidationError "age is not a number"
let parsedUser = await userSchema.validate(
{ name: 'jimmy', age: '24' },
{ strict: true },
);Run the cast version and the age field comes back as the number 24, not the string. Run the strict version with the same input and it rejects, because strict mode skips the parsing logic that would have done the coercion. That contrast is the fastest way to understand what strict does.
Where Yup is the wrong tool
The cast behaviour is the main hazard. Because cast runs transforms and no tests, a value that looks wrong can be quietly rewritten into something that looks right. If you cast an object from an untrusted source and then trust the result, you have moved the validation problem rather than solved it. The README is explicit that cast does not make further assertions, but the function name invites the opposite assumption.
Strict mode is the counterweight, and it is opt-in. You pass { strict: true } to validate, or call schema.strict(true) to set it on the schema. Nothing in the default path warns you that coercion happened.
There is also a scope limit. Yup models shaped objects and their fields. If your problem is validating a document against a specification with cross-document references, or validating a binary format, the object-schema model is the wrong shape and you will fight it. And if your team already validates with a library that derives its schema from the type rather than the other way around, adding Yup means maintaining two descriptions of the same payload.
How Yup differs from Zod
Zod is the comparison most TypeScript teams make, and the difference is directional. Yup's README leads with InferType, which extracts a type from a schema. Zod's design starts from the type and derives the validator, so the schema is a value whose type is inferred by TypeScript's own inference rather than by a helper you call.
The practical consequence is where you write things down first. With Yup you write the schema and let the type follow; with Zod you usually write the type or the schema in a way that the compiler tracks without an explicit extraction step. Both give you runtime validation and static types, and both are TypeScript-first.
Yup's other distinguishing feature in the README is Standard Schema compatibility. The README lists it as a killer feature and links the specification. If you are building a form library, a framework integration, or any tool that wants to accept schemas from more than one validation library, that compatibility is the reason to prefer Yup over a library that only understands its own schema objects.
Maintenance, licence, and what an upgrade costs
The repository is not archived, and the last push was on 2026-09-18. The most recent release listed is v1.0.0 from 2023-02-08, with the beta line running through 2022. Between the release and the current package version of 1.7.1 there is a stretch of development that reached npm without a corresponding entry in the release list shown here, so treat the release list as incomplete rather than as evidence that nothing shipped.
The v1.0.0 release note is short and informal, and the README points readers of older documentation to a pre-v1 branch. That tells you the v1 line was a breaking change with a migration path rather than a drop-in. If you are on a pre-v1 version, the upgrade is a real project, and the two README trees are the reference for what moved.
The licence is MIT, which permits commercial and closed-source use. That is a permissive licence and not a copyleft one, but licence questions about your own distribution are for your counsel, not for a README.
Build-wise, package.json shows the library ships a CommonJS build, an ESM build, and generated declaration files via a separate build:dts step. There is no runtime dependency list in the portion of package.json shown, and the README does not document a rollback procedure for a bad upgrade.
Editorial conclusion
Adopt Yup if you already write TypeScript and want one schema to serve both runtime validation and static inference, especially for form or API payload checks. Skip it if your inputs are untrusted and you need structural validation with coercion rules you can audit line by line, since cast silently rewrites values. Before committing, write a schema for one real payload, run cast on a string-typed number, then run the same input through validate with strict: true, and confirm the error you get is the one you want to show a user.
Frequently asked questions
What is Yup?
Yup is a schema builder for runtime value parsing and validation, written in TypeScript and published under MIT. You define a schema, then use it to cast a value into the right types, assert the shape of a value, or both.
How do I use Yup?
Import the type constructors you need from 'yup', chain them into an object schema, then call validate to parse and assert or cast to coerce without asserting. The README's getting-started example builds a user schema with string, number and date fields and extracts a type from it with InferType.
What is React Yup?
The README does not describe a React-specific package. Yup itself is framework-agnostic; its documentation covers schema definition, TypeScript integration and error customization, and does not document a React binding.
Can I use Yup with React Hook Form?
The README does not mention React Hook Form, so this cannot be confirmed from the project's own documentation. What the README does state is that Yup is compatible with Standard Schema, which is the mechanism a form library would use to accept a Yup schema.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jquense-yup)