diff --git a/packages/docs-v3/.editorconfig b/packages/docs-v3/.editorconfig
new file mode 100644
index 0000000000..a9452c74a7
--- /dev/null
+++ b/packages/docs-v3/.editorconfig
@@ -0,0 +1,12 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+charset = utf-8
diff --git a/packages/docs-v3/CHANGELOG.md b/packages/docs-v3/CHANGELOG.md
new file mode 100644
index 0000000000..a18ea6f143
--- /dev/null
+++ b/packages/docs-v3/CHANGELOG.md
@@ -0,0 +1,255 @@
+# Changelog
+
+## Release notes are now stored in Github Releases: https://github.com/colinhacks/zod/releases
+
+## Previous Releases
+
+### 3.10
+
+- New parser that allows parsing to continue after non-fatal errors have occurred. This allows Zod to surface more errors to the user at once.
+
+### 3.9
+
+- Custom error messages in schemas
+
+```ts
+const name = z.string({
+ invalid_type_error: "Name must be string",
+ required_error: "Name is required",
+});
+```
+
+Under the hood, this creates a custom error map that's bound to the schema. You can also pass a custom error map explicitly.
+
+```ts
+const name = z.string({ errorMap: myErrorMap });
+```
+
+- Rest parameters for tuples
+
+```ts
+const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
+type t1 = z.output; // [string, number, ...boolean[]]
+```
+
+- Selective `.partial`
+
+You can specify certain fields to make optional with the `ZodObject.partial` method.
+
+```ts
+const user = z.object({
+ name: z.string(),
+ age: z.number(),
+});
+
+const optionalNameUser = user.partial({ name: true });
+// { name?: string; age: number; }
+```
+
+- Specify key schema in ZodRecord
+
+Previously, `z.record` only accepted a single schema:
+
+```ts
+z.record(z.boolean()); // Record;
+```
+
+Now `z.record` has been overloaded to support two schemas. The first validates the _keys_ of the record, and the second validates the _values_.
+
+```ts
+const schema = z.record(z.number(), z.boolean());
+type schema = z.infer; // Record
+
+const schema = z.record(z.enum(["Tuna", "Trout"]), z.boolean());
+type schema = z.infer; // Record<"Tuna" | "Trout", boolean>
+```
+
+### 3.8
+
+- Add `z.preprocess`
+- Implement CUID validation on ZodString (`z.string().cuid()`)
+- Improved `.deepPartial()`: now recursively operates on arrays, tuples, optionals, and nullables (in addition to objects)
+
+### 3.7
+
+- Eliminate `ZodNonEmptyArray`, add `Cardinality` to `ZodArray`
+- Add optional error message to `ZodArray.nonempty`
+- Add `.gt/.gte/.lt/.lte` to `ZodNumber`
+
+### 3.6
+
+- Add IE11 support
+- `ZodError.flatten` now optionally accepts a map function for customizing the output
+- `.void()` now only accepts undefined, not null.
+- `z.enum` now supports `Readonly` string tuples
+
+### 3.5
+
+- Add discriminator to all first-party schema defs
+
+### 3.4
+
+- `unknown` and `any` schemas are always interpreted as optional. Reverts change from 3.3.
+
+### 3.3
+
+- HUGE speed improvements
+- Added benchmarking: `yarn benchmark`
+- Type signature of `ZodType#_parse` has changed. This will affects users who have implemented custom subclasses of `ZodType`.
+- [reverted] Object fields of type `unknown` are no longer inferred as optional.
+
+### 3.2
+
+- Certain methods (`.or`, `.transform`) now return a new instance that wrap the current instance, instead of trying to avoid additional nesting. For example:
+
+```ts
+z.union([z.string(), z.number()]).or(z.boolean());
+// previously
+// => ZodUnion<[ZodString, ZodNumber, ZodBoolean]>
+
+// now
+// => ZodUnion<[ZodUnion<[ZodString, ZodNumber]>, ZodBoolean]>
+```
+
+This change was made due to recursion limitations in TypeScript 4.3 that made it impossible to properly type these methods.
+
+### 3.0.0-beta.1
+
+- Moved default value logic into ZodDefault. Implemented `.nullish()` method.
+
+### 3.0.0-alpha.33
+
+- Added `.returnType` and `.parameters` methods to ZodFunction
+
+### 3.0.0-alpha.32
+
+- Added `.required()` method to ZodObject
+
+### 3.0.0-alpha.30
+
+- Added Rollup for bundling ESM module
+
+### zod@3.0.0-alpha.24
+
+- Added back ZodIntersection
+- Added .and() method to base class
+
+### zod@3.0.0-alpha.9
+
+- Added `z.strictCreate`
+
+### zod@3.0.0-alpha.8
+
+- Allowing optional default values on ZodOptional
+
+### zod@3.0.0-alpha.5
+
+March 17, 2021
+
+- Refactored parsing logic into individual subclass methods
+- Eliminated ZodTypes to enable custom ZodType subclasses
+- Removed ZodIntersection
+- Added ZodEffects as a container for refinement and transform logic
+- Added `or` method to `ZodType`
+- Added `format` method to `ZodError`
+- Added `unwrap` method to `ZodOptional` and `ZodNullable`
+- Added new `default` method and moved default functionality into ZodOptional
+- Implemented `z.setErrorMap`
+- Exporting `z` variable from `index.ts` to enable `import { z } from 'zod';`
+
+### zod@3.0.0-alpha.4
+
+Jan 25, 2021
+
+- New implementation of transformers
+- Removed type guards
+
+### zod@2
+
+- Added ZodTransformer
+- Async refinements
+
+### zod@1.11
+
+- Introduced `.safeParse` option
+- Introduced .regex method on string schemas
+- Implemented `.primitives()` and `.nonprimitives()` on object schemas
+- Implemented `z.nativeEnum()` for creating schemas from TypeScript `enum`s
+- Switched to `new URL()` constructor to check valid URLs
+
+### zod@1.10
+
+- Dropping support for TypeScript 3.2
+
+### zod@1.9
+
+- Added z.instanceof() and z.custom()
+- Implemented ZodSchema.array() method
+
+### zod@1.8
+
+- Introduced z.void()
+- Major overhaul to error handling system, including the introduction of custom error maps
+- Wrote new [error handling guide](./ERROR_HANDLING.md)
+
+### zod@1.7
+
+- Added several built-in validators to string, number, and array schemas
+- Calls to `.refine` now return new instance
+
+### zod@1.5
+
+- Introduces ZodAny and ZodUnknown
+
+### zod@1.4
+
+- Refinement types (`.refine`)
+- Parsing no longer returns deep clone
+
+### zod@1.3
+
+- Promise schemas
+
+### zod@1.2.6
+
+- `.parse` accepts `unknown`
+- `bigint` schemas
+
+### zod@1.2.5
+
+- `.partial` and `.deepPartial` on object schemas
+
+### zod@1.2.3
+
+- Added ZodDate
+
+### zod@1.2.0
+
+- Added `.pick`, `.omit`, and `.extend` on object schemas
+
+### zod@1.1.0
+
+- Added ZodRecord
+
+### zod@1.0.11
+
+- Added `.nonstrict`
+
+### zod@1.0.10
+
+- Added type assertions with `.check`
+
+### zod@1.0.4
+
+- Support for empty tuples
+
+### zod@1.0.2
+
+- Added type assertions
+- Added ZodLiteral
+- Added ZodEnum
+- Improved error reporting
+
+### zod@1.0.0
+
+- Initial release
diff --git a/packages/docs-v3/CODE_OF_CONDUCT.md b/packages/docs-v3/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..2daa233fc0
--- /dev/null
+++ b/packages/docs-v3/CODE_OF_CONDUCT.md
@@ -0,0 +1,132 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual
+identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+- Focusing on what is best not just for us as individuals, but for the overall
+ community
+
+Examples of unacceptable behavior include:
+
+- The use of sexualized language or imagery, and sexual attention or advances of
+ any kind
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email address,
+ without their explicit permission
+- Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+colinmcd94@gmail.com or scott@scotttrinh.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series of
+actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or permanent
+ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within the
+community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.1, available at
+[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][mozilla coc].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][faq]. Translations are available at
+[https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
+[mozilla coc]: https://github.com/mozilla/diversity
+[faq]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
diff --git a/packages/docs-v3/CONTRIBUTING.md b/packages/docs-v3/CONTRIBUTING.md
new file mode 100644
index 0000000000..23afcd926d
--- /dev/null
+++ b/packages/docs-v3/CONTRIBUTING.md
@@ -0,0 +1,85 @@
+# Contributing
+
+> ⚠ The default branch has just been switched to `main` from `master` (as of May 15th, 2024). Follow the following instructions to update your local fork.
+>
+> ```sh
+> git branch -m master main # rename local branch
+> git fetch origin # fetch from remote
+> git branch -u origin/main main # set upstream
+> git remote set-head origin -a # update remote
+> ```
+
+When it comes to open source, there are different ways you can contribute, all
+of which are valuable. Here's few guidelines that should help you as you prepare
+your contribution.
+
+## Initial steps
+
+Before you start working on a contribution, create an issue describing what you want to build. It's possible someone else is already working on something similar, or perhaps there is a reason that feature isn't implemented. The maintainers will point you in the right direction.
+
+
+
+## Development
+
+The following steps will get you setup to contribute changes to this repo:
+
+1. Fork this repo.
+
+2. Clone your forked repo: `git clone git@github.com:{your_username}/zod.git`
+
+3. Run `yarn` to install dependencies.
+
+4. Start playing with the code! You can do some simple experimentation in [`playground.ts`](playground.ts) (see `yarn play` below) or start implementing a feature right away.
+
+## Alternative: VSCode Dev Container setup
+
+For an officially supported isolated dev environment that automatically installs dependencies for you:
+
+1. `F1` in VSCode and start typing `Dev Containers: Clone Repository in Named Container Volume` to run the command.
+2. For the repo, paste `git@github.com:{your_username}/zod.git` if you're using ssh.
+3. Click `Create a new volume...` and name it `zod` and the folder name as `zod`.
+
+Note: if you can't see `Dev Containers` in the `F1` menu, follow [this guide](https://code.visualstudio.com/docs/devcontainers/tutorial) to install the needed extension.
+In the OSS version of VSCode the extension may be not available.
+
+### Commands
+
+**`yarn build`**
+
+- deletes `lib` and re-compiles `src` to `lib`
+
+**`yarn test`**
+
+- runs all Jest tests and generates coverage badge
+
+**`yarn test enum`**
+
+- runs a single test file (e.g. `enum.test.ts`)
+
+**`yarn play`**
+
+- executes [`playground.ts`](playground.ts), watches for changes. useful for experimentation
+
+### Tests
+
+Zod uses Jest for testing. After implementing your contribution, write tests for it. Just create a new file under `src/__tests__` or add additional tests to the appropriate existing file.
+
+Before submitting your PR, run `yarn test` to make sure there are no (unintended) breaking changes.
+
+### Documentation
+
+The Zod documentation lives in the README.md. Be sure to document any API changes you implement.
+
+## License
+
+By contributing your code to the zod GitHub repository, you agree to
+license your contribution under the MIT license.
diff --git a/packages/docs-v3/ERROR_HANDLING.md b/packages/docs-v3/ERROR_HANDLING.md
new file mode 100644
index 0000000000..e41601b0e6
--- /dev/null
+++ b/packages/docs-v3/ERROR_HANDLING.md
@@ -0,0 +1,492 @@
+# Error Handling in Zod
+
+This guide explains Zod's internal error handling system, and the various ways you can customize it for your purposes.
+
+## ZodError
+
+All validation errors thrown by Zod are instances of `ZodError`.
+
+```ts
+class ZodError extends Error {
+ issues: ZodIssue[];
+}
+```
+
+ZodError is a subclass of `Error`; you can create your own instance easily:
+
+```ts
+import * as z from "zod";
+
+const myError = new z.ZodError([]);
+```
+
+Each ZodError has an `issues` property that is an array of `ZodIssues`. Each issue documents a problem that occurred during validation.
+
+## ZodIssue
+
+`ZodIssue` is _not_ a class. It is a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions).
+
+The link above is the best way to learn about the concept. Discriminated unions are an ideal way to represent a data structures that may be one of many possible variants. You can see all the possible variants defined [here](https://github.com/colinhacks/zod/blob/main/src/ZodError.ts). They are also described in the table below if you prefer.
+
+_Every_ ZodIssue has these fields:
+
+| field | type | details |
+| --------- | ---------------------- | ------------------------------------------------------------------------------------------------- |
+| `code` | `z.ZodIssueCode` | You can access this enum with `z.ZodIssueCode`. A full breakdown of the possible values is below. |
+| `path` | `(string \| number)[]` | e.g, `['addresses', 0, 'line1']` |
+| `message` | `string` | e.g. `Invalid type. Expected string, received number.` |
+
+**However** depending on the error code, there may be additional properties as well. Here is a full breakdown of the additional fields by error code:
+
+## ZodIssueCode
+
+| code | additional fields |
+| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| ZodIssueCode.invalid_type | `expected: ZodParsedType` `received: ZodParsedType`
Jump to [this section](#zodparsedtype) for a breakdown of the possible values of ZodParsedType. |
+| ZodIssueCode.unrecognized_keys | `keys: string[]` The list of unrecognized keys |
+| ZodIssueCode.invalid_union | `unionErrors: ZodError[]` The errors thrown by each element of the union. |
+| ZodIssueCode.invalid_enum_value | `options: string[]` The set of acceptable string values for this enum. |
+| ZodIssueCode.invalid_arguments | `argumentsError: ZodError` This is a special error code only thrown by a wrapped function returned by `ZodFunction.implement()`. The `argumentsError` property is another ZodError containing the validation error details. |
+| ZodIssueCode.invalid_return_type | `returnTypeError: ZodError` This is a special error code only thrown by a wrapped function returned by `ZodFunction.implement()`. The `returnTypeError` property is another ZodError containing the validation error details. |
+| ZodIssueCode.invalid_date | _no additional properties_ |
+| ZodIssueCode.invalid_string | `validation: "url" \| "email" \| "uuid"` Which built-in string validator failed |
+| ZodIssueCode.too_small | `type: "string" \| "number" \| "array" \| "set" \| "date"` The type of the data failing validation
`minimum: number` The expected length/value.
`inclusive: boolean` Whether the minimum is included in the range of acceptable values.
`exact: boolean` Whether the size/length is constrained to be an exact value (used to produce more readable error messages). |
+| ZodIssueCode.too_big | `type: "string" \| "number" \| "array" \| "set" \| "date"` The type of the data failing validation
`maximum: number` The expected length/value.
`inclusive: boolean` Whether the maximum is included in the range of acceptable values.
`exact: boolean` Whether the size/length is constrained to be an exact value (used to produce more readable error messages). |
+| ZodIssueCode.not_multiple_of | `multipleOf: number` The value the number should be a multiple of. |
+| ZodIssueCode.custom | `params: { [k: string]: any }` This is the error code throw by refinements (unless you are using `superRefine` in which case it's possible to throw issues of any `ZodIssueCode`). You are able to pass in a `params` object here that is available in your custom error maps (see [ZodErrorMap](#Customizing-errors-with-ZodErrorMap) below for details on error maps) |
+
+
+
+## ZodParsedType
+
+This is an enum used by Zod internally to represent the type of a parsed value. The possible values are:
+
+- `string`
+- `nan`
+- `number`
+- `integer`
+- `float`
+- `boolean`
+- `date`
+- `bigint`
+- `symbol`
+- `function`
+- `undefined`
+- `null`
+- `array`
+- `object`
+- `unknown`
+- `promise`
+- `void`
+- `never`
+- `map`
+- `set`
+
+## A demonstrative example
+
+Here's a sample Person schema.
+
+```ts
+const person = z.object({
+ names: z.array(z.string()).nonempty(), // at least 1 name
+ address: z
+ .object({
+ line1: z.string(),
+ zipCode: z.number().min(10000), // American 5-digit code
+ })
+ .strict(), // do not allow unrecognized keys
+});
+```
+
+Let's pass in some improperly formatted data.
+
+```ts
+try {
+ person.parse({
+ names: ["Dave", 12], // 12 is not a string
+ address: {
+ line1: "123 Maple Ave",
+ zipCode: 123, // zip code isn't 5 digits
+ extra: "other stuff", // unrecognized key
+ },
+ });
+} catch (err) {
+ if (err instanceof z.ZodError) {
+ console.log(err.issues);
+ }
+}
+```
+
+Here are the errors that will be printed:
+
+```ts
+[
+ {
+ code: "invalid_type",
+ expected: "string",
+ received: "number",
+ path: ["names", 1],
+ message: "Invalid input: expected string, received number",
+ },
+ {
+ code: "unrecognized_keys",
+ keys: ["extra"],
+ path: ["address"],
+ message: "Unrecognized key(s) in object: 'extra'",
+ },
+ {
+ code: "too_small",
+ minimum: 10000,
+ type: "number",
+ inclusive: true,
+ path: ["address", "zipCode"],
+ message: "Value should be greater than or equal to 10000",
+ },
+];
+```
+
+As you can see three different issues were identified. Every ZodIssue has a `code` property and additional metadata about the validation failure. For instance the `unrecognized_keys` error provides a list of the unrecognized keys detected in the input.
+
+## Customizing errors with ZodErrorMap
+
+You can customize **all** error messages produced by Zod by providing a custom "error map" to Zod, like so:
+
+```ts
+import { z } from "zod";
+
+const customErrorMap: z.ZodErrorMap = (issue, ctx) => {
+ if (issue.code === z.ZodIssueCode.invalid_type) {
+ if (issue.expected === "string") {
+ return { message: "bad type!" };
+ }
+ }
+ if (issue.code === z.ZodIssueCode.custom) {
+ return { message: `less-than-${(issue.params || {}).minimum}` };
+ }
+ return { message: ctx.defaultError };
+};
+
+z.setErrorMap(customErrorMap);
+```
+
+`ZodErrorMap` is a special function. It accepts two arguments: `issue` and `ctx`. The return type is `{ message: string }`. Essentially the error map accepts some information about the validation that is failing and returns an appropriate error message.
+
+- `issue: Omit`
+
+ As mentioned above, ZodIssue is a discriminated union.
+
+- `ctx: { defaultError: string; data: any }`
+
+ - `ctx.defaultError` is the error message generated by the default error map. If you only want to override the message for a single type of error, you can do that. Just return `{ message: ctx.defaultError }` for everything else.
+
+ - `ctx.data` contains the data that was passed into `.parse`. You can use this to customize the error message.
+
+As in the example, you can modify certain error messages and simply fall back to `ctx.defaultError` otherwise.
+
+## Error map priority
+
+A custom error maps doesn't need to produce an error message for every kind of issue in Zod. Instead, your error map can override certain errors and return `ctx.defaultError` for everything else.
+
+But how is the value of `ctx.defaultError` determined?
+
+Error messages in Zod are generated by passing metadata about a validation issue through a chain of error maps. Error maps with higher priority override messages generated by maps with lower priority.
+
+The lowest priority map is the `defaultErrorMap`, which defined in [`src/errors.ts`](https://github.com/colinhacks/zod/blob/main/src/errors.ts). This produces the default error message for all issues in Zod.
+
+### Global error map
+
+This message is then passed as `ctx.defaultError` into `overrideErrorMap`. This is a global error map you can set with `z.setErrorMap`:
+
+```ts
+const myErrorMap: z.ZodErrorMap = /* ... */;
+z.setErrorMap(myErrorMap);
+```
+
+### Schema-bound error map
+
+The `overrideErrorMap` message is then passed as `ctx.defaultError` into any schema-bound error maps. Every schema can be associated with an error map.
+
+```ts
+z.string({ errorMap: myErrorMap });
+
+// this creates an error map under the hood
+z.string({
+ invalid_type_error: "Invalid name",
+ required_error: "Name is required",
+});
+```
+
+### Contextual error map
+
+Finally, you can pass an error map as a parameter to any `parse` method. This error map, if provided, has highest priority.
+
+```ts
+z.string().parse("adsf", { errorMap: myErrorMap });
+```
+
+## A working example
+
+Let's look at a practical example of of customized error map:
+
+```ts
+import * as z from "zod";
+
+const customErrorMap: z.ZodErrorMap = (error, ctx) => {
+ /*
+ This is where you override the various error codes
+ */
+ switch (error.code) {
+ case z.ZodIssueCode.invalid_type:
+ if (error.expected === "string") {
+ return { message: `This ain't a string!` };
+ }
+ break;
+ case z.ZodIssueCode.custom:
+ // produce a custom message using error.params
+ // error.params won't be set unless you passed
+ // a `params` arguments into a custom validator
+ const params = error.params || {};
+ if (params.myField) {
+ return { message: `Bad input: ${params.myField}` };
+ }
+ break;
+ }
+
+ // fall back to default message!
+ return { message: ctx.defaultError };
+};
+
+z.string().parse(12, { errorMap: customErrorMap });
+
+/* throws:
+ ZodError {
+ errors: [{
+ code: "invalid_type",
+ path: [],
+ message: "This ain't a string!",
+ expected: "string",
+ received: "number",
+ }]
+ }
+*/
+```
+
+## Error handling for forms
+
+If you're using Zod to validate the inputs from a web form, there is a convenient way to "flatten" a ZodError to a rich, structured format that can be easily rendered in your interface.
+
+Consider this example of a simple signup form:
+
+```ts
+const FormData = z.object({
+ name: z.string(),
+ contactInfo: z.object({
+ email: z.string().email(),
+ phone: z.string().optional(),
+ }),
+});
+```
+
+Now lets pass in some invalid data:
+
+```ts
+const result = FormData.safeParse({
+ name: null,
+ contactInfo: {
+ email: "not an email",
+ phone: "867-5309",
+ },
+});
+```
+
+This will throw a ZodError with two issues:
+
+```ts
+if (!result.success) {
+ console.log(result.error.issues);
+}
+/*
+ [
+ {
+ "code": "invalid_type",
+ "expected": "string",
+ "received": "null",
+ "path": ["name"],
+ "message": "Expected string, received null"
+ },
+ {
+ "validation": "email",
+ "code": "invalid_string",
+ "message": "Invalid email",
+ "path": ["contactInfo","email"]
+ }
+ ]
+*/
+```
+
+### Formatting errors
+
+Using the `.format()` method on `ZodError`, we can make this error easier to work with.
+
+```ts
+if (!result.success) {
+ console.log(result.error.format());
+ /*
+ {
+ name: {
+ _errors: ['Expected string, received null']
+ },
+ contactInfo: {
+ email: {
+ _errors: ['Invalid email']
+ }
+ }
+ }
+ */
+}
+```
+
+As you can see, the result is an object that denormalizes the issues array into a nested object. This makes it easier to display error messages in your form interface.
+
+```tsx
+const FormData = z.object({ ... });
+
+function Errors(props: {errors?: string[]}){
+ if(!props.errors?.length) return null;
+ return
+}
+```
+
+### Flattening errors
+
+Because `.format` returns a deeply nested object, the errors are contained within the `_errors` property to avoid key collisions. However this isn't necessary if your object schema is only one level deep.
+
+In this scenario, `.flatten()` may be more convenient.
+
+```ts
+if (!result.success) {
+ console.log(result.error.flatten());
+}
+/*
+ {
+ formErrors: [],
+ fieldErrors: {
+ name: ['Expected string, received null'],
+ contactInfo: ['Invalid email']
+ },
+ }
+*/
+```
+
+The `fieldErrors` key points to an object that groups all issues by key.
+
+The `formErrors` element is a list of issues that occurred on the "root" of the object schema. For instance: if you called `FormData.parse(null)`, `flatten()` would return:
+
+```ts
+const result = FormData.safeParse(null);
+if (!result.success) {
+ result.error.flatten();
+ /*
+ {
+ formErrors: ["Invalid input: expected object, received null"],
+ fieldErrors: {}
+ }
+ */
+}
+```
+
+### Post-processing issues
+
+Both `.flatten()` and `.format()` accept an optional mapping function of `(issue: ZodIssue) => U` to `flatten()`, which can customize how each `ZodIssue` is transformed in the final output.
+
+This can be particularly useful when integrating Zod with form validation, as it allows you to pass back whatever `ZodIssue` specific context you might need.
+
+```ts
+result.error.flatten((issue: ZodIssue) => ({
+ message: issue.message,
+ errorCode: issue.code,
+}));
+/*
+ {
+ formErrors: [],
+ fieldErrors: {
+ name: [
+ {message: "Expected string, received null", errorCode: "invalid_type"}
+ ]
+ contactInfo: [
+ {message: "Invalid email", errorCode: "invalid_string"}
+ ]
+ },
+ }
+*/
+```
+
+### Extract type signature
+
+You can infer the return type signature of `.format()` and `.flatten()` with the following utilities:
+
+```ts
+type FormattedErrors = z.inferFormattedError;
+/*
+ {
+ name?: {_errors?: string[]},
+ contactInfo?: {
+ _errors?: string[],
+ email?: {
+ _errors?: string[],
+ },
+ phone?: {
+ _errors?: string[],
+ },
+ },
+ }
+*/
+
+type FlattenedErrors = z.inferFlattenedErrors;
+/*
+ {
+ formErrors: string[],
+ fieldErrors: {
+ email?: string[],
+ password?: string[],
+ confirm?: string[]
+ }
+ }
+*/
+```
+
+These utilities also accept a second generic argument that corresponds to the result of any `ZodIssue` mapper function.
+
+```ts
+type FormDataErrors = z.inferFlattenedErrors<
+ typeof FormData,
+ { message: string; errorCode: string }
+>;
+
+/*
+ {
+ formErrors: { message: string, errorCode: string }[],
+ fieldErrors: {
+ email?: { message: string, errorCode: string }[],
+ password?: { message: string, errorCode: string }[],
+ confirm?: { message: string, errorCode: string }[]
+ }
+ }
+*/
+```
diff --git a/packages/docs-v3/LICENSE b/packages/docs-v3/LICENSE
new file mode 100644
index 0000000000..2c93bb52b9
--- /dev/null
+++ b/packages/docs-v3/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Colin McDonnell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/docs-v3/MIGRATION.md b/packages/docs-v3/MIGRATION.md
new file mode 100644
index 0000000000..472dea686c
--- /dev/null
+++ b/packages/docs-v3/MIGRATION.md
@@ -0,0 +1,77 @@
+# Migration guide
+
+This is a migration guide to walk you through the process of upgrading to Zod 3.
+
+- If you're upgrading directly from Zod 1, you should read through the list of features + changes in both Zod 2 and Zod 3.
+- If you're upgrading from Zod 2 -> 3, you can skip to the
+
+## Upgrading from Zod 1 → Zod 2
+
+Zod 2 is being retired and will not leave beta. This is due to some unintuitive ramifications of the transformers API: details [here](https://github.com/colinhacks/zod/issues/264).
+
+### New features
+
+- Transformers! These let you provide default values, do casting/coercion, and a lot more. Read more here: [Transformers](https://github.com/colinhacks/zod#transformers)
+- Asynchronous refinements and new .parseAsync and .safeParseAsync methods. Read more here: [Refinements](https://github.com/colinhacks/zod#refinements)
+- Modify unknown key behavior for object schemas: `.strip()` (the default), `.passthrough()`, and `.strict()`
+- New .catchall() method for object schemas: [catchall](https://github.com/colinhacks/zod#catchall)
+
+### Breaking changes
+
+- Object schemas now _strip_ unknown keys by default.
+- Schema parsing now returns a deep clone of the data you pass in (instead of the exact value you pass in)
+- Relatedly, Zod no longer supports cyclical data. Recursive schemas are still supported, but Zod can't properly parse nested objects that contain cycles.
+- Optional and nullable schemas are now represented with the dedicated ZodOptional and ZodNullable classes, instead of using ZodUnion.
+
+## Upgrading from Zod 2 → Zod 3
+
+### New features
+
+- You can now import Zod like `import { z } from 'zod';` instead of using `import * as` syntax.
+- **Structured error messages**. Use the `.format()` method to ZodError to convert the error into a strongly-typed, nested object: [format method](#error-formatting)
+- **Easier unions**. Use the `or` method to ZodType (the base class for all Zod schemas) to easily create union types like `z.string().or(z.number())`
+- **Easier intersections**. Use the `and` method to ZodType (the base class for all Zod schemas) to easily create intersection types
+- **Global error customization**. Use `z.setErrorMap(myErrorMap)` to _globally_ customize the error messages produced by Zod: [setErrorMap](ERROR_HANDLING.md#customizing-errors-with-zoderrormap)
+- **Maps and sets**. Zod now supports [`Map`](#maps) and [`Set`](#set) schemas.
+- **Optional and nullable unwrapping**. ZodOptional and ZodNullable now have a `.unwrap()` method for retrieving the schema they wrap.
+- **A new implementation of transformers**. Details below.
+
+### Breaking changes
+
+- The **minimum TypeScript version** is now _4.1_ (up from 3.7 for Zod 2). Several features have been rewritten to use [recursive conditional types](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#recursive-conditional-types), an incredibly powerful new feature introduced in TS4.1.
+
+- **Transformers syntax**. Previously, creating a transformer required an input schema, an output schema, and a function to transform between them. You created transformers like `z.transform(A, B, func)`, where `A` and `B` are Zod schemas. This is no longer the case. Accordingly:
+
+ The old syntax is no longer available:
+
+ ```ts
+ # not available
+ z.transformer(A, B, func);
+ A.transform(B, func)
+ ```
+
+ Instead, apply transformations by simply using the `.transform()` method that exists on all Zod schemas.
+
+ ```ts
+ z.string().transform((val) => val.length);
+ ```
+
+- Under the hood, all refinements and transformations are executed inside a dedicated "ZodEffects" class. Post-parsing, ZodEffects passes the data through a chain of refinements and transformations, then returns the final value. As such, you can now _interleave_ transformations and refinements. For instance:
+
+ ```ts
+ const test = z
+ .string()
+ .transform((val) => val.length)
+ .refine((val) => val > 5, { message: "Input is too short" })
+ .transform((val) => val * 2);
+
+ test.parse("12characters"); // => 24
+ ```
+
+- **Type guards** (the `.check()` method) have been removed. Type guards interact with transformers in unintuitive ways so they were removed. Use `.safeParse` instead.
+
+- Object merging now behaves differently. If you merge two object schema (`A.merge(B)`), the fields of B will overwrite the fields of A if there are shared keys. This is how the `.extend` method already works. If you're looking to create an intersection of the two types, use `z.intersection(A, B)` or use the new `.and` method (`A.and(B)`).
+
+- **Default values**: default value logic is now implemented inside a `ZodDefault` class, instead of using transformers. (In a previous alpha version of Zod 3, default values were implemented inside the ZodOptional class.)
+
+- There have been small internal changes to the ZodIssue subtypes. See the new subtypes in the [Error Handling guide](ERROR_HANDLING.md). This may impact user who have written a custom error maps. Most users will not be affected.
diff --git a/packages/docs-v3/README.md b/packages/docs-v3/README.md
new file mode 100644
index 0000000000..eebb7ce27a
--- /dev/null
+++ b/packages/docs-v3/README.md
@@ -0,0 +1,3095 @@
+
+
+
Zod
+
+ zod.dev
+
+ TypeScript-first schema validation with static type inference
+
+
+
+
+### Ecosystem
+
+There are a growing number of tools that are built atop or support Zod natively! If you've built a tool or library on top of Zod, tell me about it [on Twitter](https://twitter.com/colinhacks) or [start a Discussion](https://github.com/colinhacks/zod/discussions). I'll add it below and tweet it out.
+
+#### Resources
+
+- [Total TypeScript Zod Tutorial](https://www.totaltypescript.com/tutorials/zod) by [@mattpocockuk](https://twitter.com/mattpocockuk)
+- [Fixing TypeScript's Blindspot: Runtime Typechecking](https://www.youtube.com/watch?v=rY_XqfSHock) by [@jherr](https://twitter.com/jherr)
+
+#### API libraries
+
+- [`tRPC`](https://github.com/trpc/trpc): Build end-to-end typesafe APIs without GraphQL.
+- [`@anatine/zod-nestjs`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-nestjs): Helper methods for using Zod in a NestJS project.
+- [`zod-endpoints`](https://github.com/flock-community/zod-endpoints): Contract-first strictly typed endpoints with Zod. OpenAPI compatible.
+- [`zhttp`](https://github.com/evertdespiegeleer/zhttp): An OpenAPI compatible, strictly typed http library with Zod input and response validation.
+- [`domain-functions`](https://github.com/SeasonedSoftware/domain-functions/): Decouple your business logic from your framework using composable functions. With first-class type inference from end to end powered by Zod schemas.
+- [`@zodios/core`](https://github.com/ecyrbe/zodios): A typescript API client with runtime and compile time validation backed by axios and zod.
+- [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
+- [`tapiduck`](https://github.com/sumukhbarve/monoduck/blob/main/src/tapiduck/README.md): End-to-end typesafe JSON APIs with Zod and Express; a bit like tRPC, but simpler.
+- [`koa-zod-router`](https://github.com/JakeFenley/koa-zod-router): Create typesafe routes in Koa with I/O validation using Zod.
+- [`zod-sockets`](https://github.com/RobinTail/zod-sockets): Zod-powered Socket.IO microframework with I/O validation and built-in AsyncAPI specs
+- [`oas-tszod-gen`](https://github.com/inkognitro/oas-tszod-gen): Client SDK code generator to convert OpenApi v3 specifications into TS endpoint caller functions with Zod types.
+- [`GQLoom`](https://github.com/modevol-com/gqloom): Weave GraphQL schema and resolvers using Zod.
+- [`oRPC`](https://github.com/unnoq/orpc): Typesafe APIs Made Simple
+
+#### Form integrations
+
+- [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
+- [`TanStack Form`](https://github.com/TanStack/form): Headless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, and Lit
+- [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s.
+- [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
+- [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `