Skip to content

Commit b13d46b

Browse files
Support all standard schema libraries (#299)
Co-authored-by: juliusmarminge <julius0216@outlook.com>
1 parent 8798e3f commit b13d46b

File tree

25 files changed

+977
-68
lines changed

25 files changed

+977
-68
lines changed

.changeset/fair-rats-hammer.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@t3-oss/env-nextjs": minor
3+
"@t3-oss/env-core": minor
4+
"@t3-oss/env-nuxt": minor
5+
---
6+
7+
feat!: support standard schema
8+
9+
Validators can now be any validator that supports [Standard Schema](https://github.com/standard-schema/standard-schema),
10+
for example Zod & Valibot.
11+
12+
This feature comes with some breaking changes:
13+
14+
- If using Zod, the minimum required version is now 3.24.
15+
- `onValidationError` now gets `StandardSchemaV1.Issue[]` instead of `ZodError`

.github/workflows/main.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ jobs:
5151
uses: actions/checkout@v4
5252
- uses: ./.github/setup
5353

54-
- run: bun test
54+
- run: bun turbo run build --filter=@t3-oss/env*
55+
- run: bun test

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ export const GET = (req: Request) => {
7676

7777
## Roadmap
7878

79-
- [ ] Bring your own validation library - currently only supports Zod.
79+
- [x] Bring your own validation library - now supports any [Standard Schema library](https://github.com/standard-schema/standard-schema?tab=readme-ov-file#what-schema-libraries-implement-the-spec)

bun.lock

+24-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@
5757
"vite": "^6.0.1",
5858
},
5959
},
60+
"examples/astro-valibot": {
61+
"name": "@examples/astro-valibot",
62+
"dependencies": {
63+
"@astrojs/solid-js": "^5.0.4",
64+
"@t3-oss/env-core": "workspace:*",
65+
"astro": "^5.1.9",
66+
"solid-js": "^1.9.4",
67+
"valibot": "^1.0.0-beta.14",
68+
},
69+
"devDependencies": {
70+
"vite": "^6.0.1",
71+
},
72+
},
6073
"examples/nextjs": {
6174
"name": "@examples/nextjs",
6275
"dependencies": {
@@ -91,14 +104,16 @@
91104
"devDependencies": {
92105
"bunchee": "^6.3.2",
93106
"typescript": "^5.7.3",
107+
"valibot": "^1.0.0-beta.14",
94108
"zod": "^3.24.1",
95109
},
96110
"peerDependencies": {
97111
"typescript": ">=5.0.0",
98-
"zod": "^3.0.0",
112+
"zod": "^3.24.0",
99113
},
100114
"optionalPeers": [
101115
"typescript",
116+
"zod",
102117
],
103118
},
104119
"packages/nextjs": {
@@ -114,10 +129,11 @@
114129
},
115130
"peerDependencies": {
116131
"typescript": ">=5.0.0",
117-
"zod": "^3.0.0",
132+
"zod": "^3.24.0",
118133
},
119134
"optionalPeers": [
120135
"typescript",
136+
"zod",
121137
],
122138
},
123139
"packages/nuxt": {
@@ -133,10 +149,11 @@
133149
},
134150
"peerDependencies": {
135151
"typescript": ">=5.0.0",
136-
"zod": "^3.0.0",
152+
"zod": "^3.24.0",
137153
},
138154
"optionalPeers": [
139155
"typescript",
156+
"zod",
140157
],
141158
},
142159
},
@@ -343,6 +360,8 @@
343360

344361
"@examples/astro": ["@examples/astro@workspace:examples/astro"],
345362

363+
"@examples/astro-valibot": ["@examples/astro-valibot@workspace:examples/astro-valibot"],
364+
346365
"@examples/nextjs": ["@examples/nextjs@workspace:examples/nextjs"],
347366

348367
"@examples/nuxt": ["@examples/nuxt@workspace:examples/nuxt"],
@@ -2459,6 +2478,8 @@
24592478

24602479
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
24612480

2481+
"valibot": ["valibot@1.0.0-beta.14", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA=="],
2482+
24622483
"validate-html-nesting": ["validate-html-nesting@1.2.2", "", {}, "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg=="],
24632484

24642485
"validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="],

docs/src/app/docs/core/page.mdx

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ npm install @t3-oss/env-core zod
2020

2121
<Callout>
2222

23+
Although we'll use Zod as examples throughout these docs, you can use any validator that supports [Standard Schema](https://github.com/standard-schema/standard-schema).
24+
25+
</Callout>
26+
27+
<Callout>
28+
2329
`@t3-oss/env-core` requires a minimum of `typescript@5.0.0`.
2430

2531
</Callout>

docs/src/app/docs/customization/page.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ import { createEnv } from "@t3-oss/env-core";
3434
export const env = createEnv({
3535
// ...
3636
// Called when the schema validation fails.
37-
onValidationError: (error: ZodError) => {
37+
onValidationError: (issues: StandardSchemaV1.Issue[]) => {
3838
console.error(
3939
"❌ Invalid environment variables:",
40-
error.flatten().fieldErrors
40+
issues
4141
);
4242
throw new Error("Invalid environment variables");
4343
},

docs/src/app/docs/nextjs/page.mdx

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ pnpm add @t3-oss/env-nextjs zod
1919

2020
<Callout>
2121

22+
Although we'll use Zod as examples throughout these docs, you can use any validator that supports [Standard Schema](https://github.com/standard-schema/standard-schema).
23+
24+
</Callout>
25+
26+
<Callout>
27+
2228
`@t3-oss/env-nextjs` requires a minimum of `typescript@5.0.0`.
2329

2430
</Callout>

docs/src/app/docs/nuxt/page.mdx

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ pnpm add @t3-oss/env-nuxt zod
2020

2121
<Callout>
2222

23+
Although we'll use Zod as examples throughout these docs, you can use any validator that supports [Standard Schema](https://github.com/standard-schema/standard-schema).
24+
25+
</Callout>
26+
27+
<Callout>
28+
2329
`@t3-oss/env-core` requires a minimum of `typescript@5`.
2430

2531
</Callout>

examples/astro-valibot/.env

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PORT=3000
2+
PUBLIC_API_URL=http://localhost:3000
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from "astro/config";
2+
3+
import solidJs from "@astrojs/solid-js";
4+
5+
// https://astro.build/config
6+
export default defineConfig({
7+
integrations: [solidJs()],
8+
});

examples/astro-valibot/package.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@examples/astro-valibot",
3+
"type": "module",
4+
"private": true,
5+
"scripts": {
6+
"build": "astro build",
7+
"dev": "astro dev",
8+
"preview": "astro preview",
9+
"start": "astro dev"
10+
},
11+
"dependencies": {
12+
"@astrojs/solid-js": "^5.0.4",
13+
"@t3-oss/env-core": "workspace:*",
14+
"astro": "^5.1.9",
15+
"solid-js": "^1.9.4",
16+
"valibot": "^1.0.0-beta.14"
17+
},
18+
"devDependencies": {
19+
"vite": "^6.0.1"
20+
}
21+
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { env } from "./t3-env";
2+
3+
export function ClientComponent() {
4+
// Try changing PUBLIC_API_URL to PORT - the component will throw
5+
return <div>Client API Url:{env.PUBLIC_API_URL}</div>;
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
import { ClientComponent } from "../counter";
3+
import { env } from "../t3-env";
4+
---
5+
6+
<html lang="en">
7+
<head>
8+
<meta charset="utf-8" />
9+
<meta name="viewport" content="width=device-width" />
10+
<meta name="generator" content={Astro.generator} />
11+
<title>Astro</title>
12+
</head>
13+
<body>
14+
<h1>Astro</h1>
15+
<p>PORT: {env.PORT}</p>
16+
<ClientComponent client:only />
17+
</body>
18+
</html>

examples/astro-valibot/src/t3-env.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createEnv } from "@t3-oss/env-core";
2+
import { string } from "valibot";
3+
4+
export const env = createEnv({
5+
server: {
6+
PORT: string(),
7+
},
8+
client: {
9+
PUBLIC_API_URL: string(),
10+
},
11+
// Astro bundles all environment variables so
12+
// we don't need to manually destructure them
13+
runtimeEnv: import.meta.env,
14+
// process is not available in Astro, so we must set this explicitly
15+
skipValidation: import.meta.env.SKIP_ENV_VALIDATION === "development",
16+
clientPrefix: "PUBLIC_",
17+
});

examples/astro-valibot/tsconfig.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "astro/tsconfigs/strictest",
3+
"compilerOptions": {
4+
"allowJs": true,
5+
"checkJs": true,
6+
"jsx": "preserve",
7+
"jsxImportSource": "solid-js",
8+
"types": ["astro/client"]
9+
},
10+
"include": ["src", "astro.config.mjs"]
11+
}

packages/core/package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,20 @@
2929
},
3030
"peerDependencies": {
3131
"typescript": ">=5.0.0",
32-
"zod": "^3.0.0"
32+
"zod": "^3.24.0"
3333
},
3434
"peerDependenciesMeta": {
3535
"typescript": {
3636
"optional": true
37+
},
38+
"zod": {
39+
"optional": true
3740
}
3841
},
3942
"devDependencies": {
4043
"bunchee": "^6.3.2",
4144
"typescript": "^5.7.3",
42-
"zod": "^3.24.1"
45+
"zod": "^3.24.1",
46+
"valibot": "^1.0.0-beta.14"
4347
}
4448
}

0 commit comments

Comments
 (0)