The yup npm package is a mature, well-maintained JavaScript schema validation library, and it is safe to depend on, but it only improves your security if you run validation on the server and write schemas that reject bad input rather than merely describe good input. Yup is a schema builder for runtime value parsing and validation, popular in React forms and Node.js APIs alike. The library is not the risk. The risk is treating client-side validation as a security control, which it never is.
What yup is and where it stands
Yup lets you declare the shape and constraints of data once and validate against it at runtime, with strong TypeScript support that can infer static types from a schema. The current major line is 1.x, with 1.7.1 the latest release at the time of writing, and there are thousands of dependent projects in the npm registry. It is maintained on GitHub at jquense/yup. In supply-chain terms it is a healthy dependency: active, widely used, and with a small dependency footprint.
Installing it is exactly what you would expect. All of these do the same thing:
npm install yup
# or
npm i yup
You will see it written as npm yup, yup - npm, and npm install yup across tutorials; they are the same package.
A minimal schema
A typical server-side validation schema for a signup payload:
import * as yup from 'yup'
const signupSchema = yup.object({
email: yup.string().email().required().max(254),
password: yup.string().min(12).max(128).required(),
age: yup.number().integer().min(13).max(120),
}).noUnknown() // reject fields not declared in the schema
const clean = await signupSchema.validate(req.body, {
abortEarly: false,
stripUnknown: true,
})
Two choices in that snippet do real security work. noUnknown() and stripUnknown prevent mass-assignment, where an attacker slips an extra field like isAdmin: true into the JSON body and hopes it flows into a database update. And the max bounds cap input size so a giant payload cannot be used to exhaust memory downstream. A schema that only lists the fields you want, without rejecting the ones you do not, is doing half the job.
The one mistake that undoes everything
Yup runs the same in the browser and on the server, which is convenient and dangerous. Client-side validation with yup is a user-experience feature: it gives instant feedback and reduces round trips. It is not a security boundary, because anyone can bypass the browser entirely and POST directly to your API with curl.
Every rule that matters for security has to run on the server, on data you do not trust. If your React form validates with yup but your Express handler takes req.body straight into the database, you have a validated form and an unvalidated API. Share the schema between client and server if you like (that is a genuine benefit of a runtime validator), but the server-side call is the one that counts.
Validation is not sanitization
Yup confirms that data matches a shape. It does not make that data safe to hand to a SQL engine, an HTML renderer, or a shell. A string can be a perfectly valid email format and still be part of an injection attempt against a downstream system.
So yup sits at the front of a defense-in-depth chain, not at the end of it:
- Validate structure and bounds with yup at the API boundary.
- Parameterize every database query so validated input cannot alter query structure.
- Encode on output so validated input cannot execute in a browser context.
Skipping the second and third steps because "the input was validated" is a common and costly assumption. For the broader picture of how these layers fit, our DAST product page covers testing the runtime behavior that validation alone will not protect.
Watch the version and the tree
Yup itself has a clean track record, but "safe today" is a statement with a shelf life. Any dependency can develop a vulnerability, and any dependency pulls in its own transitive packages. Pin yup in a committed package-lock.json, run npm audit in CI, and layer an SCA scan so you catch an advisory the moment one lands, including in anything yup depends on. An SCA tool such as Safeguard can flag a newly disclosed issue in a transitive dependency before it reaches production.
One ecosystem note that applies to any popular package: because yup is a short, common name, be deliberate about installing the real package from the official registry and not a typosquatted lookalike. A committed lockfile with integrity hashes is the practical defense against a compromised or substituted release.
Choosing yup versus alternatives
Yup is a solid default, especially in React ecosystems where it integrates cleanly with form libraries. Newer options like Zod have gained ground for their TypeScript-first ergonomics. From a security standpoint the differences are mostly about developer experience and correctness of your schemas, not about one library being fundamentally safer than another. Whatever you pick, the rules stand: validate on the server, reject unknown fields, bound input size, and pair validation with parameterization and output encoding.
FAQ
Is the yup npm package safe to use?
Yes. Yup is actively maintained, widely adopted, and has a small dependency footprint. It is a healthy dependency. Its safety in your app depends on running validation server-side and writing schemas that reject unexpected input, not on the library alone.
Can I rely on yup for client-side validation?
For user experience, yes. For security, no. Client-side validation is trivially bypassed by sending requests directly to your API, so every security-relevant rule must also run on the server against untrusted input.
Does yup protect against SQL injection or XSS?
No. Yup validates that data matches a defined shape; it does not sanitize data for downstream contexts. Prevent SQL injection with parameterized queries and XSS with output encoding. Yup is the first layer of defense in depth, not the whole chain.
How do I install yup?
Run npm install yup (or npm i yup). Pin the version with a committed lockfile and run dependency scanning in CI so you are alerted to any future advisory in yup or its dependencies.