T3 Type Safe Environmental Variables in Next.js 14
My GitHub
Tell me you’ve misconfigured environmental variables before in a Next.js application without telling me; we’ve all been there, done that.
The purpose of this article is to educate you on the fantastic t3-oss/env-nextjs library, which hoards a variety of features designed to mitigate misconfiguration issues.
The library contains built-in functionality to make your environmental variables type-safe, which reduces errors due to spelling, as well as validation via the zod library, which allows you to verify that an environmental variable is in your desired format; providing you with a user-friendly message if your variables don’t comply with your rules.
So without further ado, lets get into it!
Table of Contents
- Project Setup
- Package Installation.
- Defining Environmental Variables in
.env.local - Configuring
next.config.mjs - Creating The Validation Schema File
- Testing
Project Setup
To setup a Next.js project, please check out the instructions here. The installation process generally consists of running the following command in the terminal.
npx create-next-app@latestPackage Installation
In your terminal, type the following command to install the t3-oss/env-nextjs package along with zod, the well-known validation library.
pnpm add @t3-oss/env-nextjs zod
yarn add @t3-oss/env-nextjs zod
npm install @t3-oss/env-nextjs zodDefining Environmental Variables
In the root of your Next.js project, create a file called .env.local and fill it with the following test data:
# we define a valid and erroneous variable
# for testing purposes later
VALID_VARIABLE=random-key
ERROR_VARIABLE=Configuring next.config.mjs
- Find the
next.config.jsfile that should’ve been automatically generated post-project setup. - Rename
next.config.jstonext.config.mjs. This step is important because thet3–osspackage only works with ES6importsyntax rather thanrequire()syntax. - Copy the following code inside
next.config.mjs:
// we will create this file later... Be sure to use your
// personal file path if it differs from mine.
import "./src/env.mjs"
/** @type {import('next').NextConfig} */
const nextConfig = {
// your config options...
}
export default nextConfigThis step ensures that the env.mjs file that we create later is available to validate the environmental variables at compile/build time.
Creating The Validation Schema File
Now lets create that env.mjs file I’ve been ranting about.
- create a file called
env.mjsin either the root of your project or inside thesrc/directory if you’ve configured yourNext.jsproject to include this. - copy the following code:
import { createEnv } from "@t3-oss/env-nextjs"
import { z } from "zod"
export const env = createEnv({
// include the NEXT_PUBLIC prefix to use
// client-side environmental variables
client: {
},
server: {
VALID_VARIABLE: z.string().min(1),
ERROR_VARIABLE: z.string().min(1)
},
runtimeEnv: {
VALID_VARIABLE: process.env.VALID_VARIABLE,
ERROR_VARIABLE: process.env.ERROR_VARIABLE
},
})- We have validated our
serverenvironmental variables by ensuring it’s a string with a minimum of 1 character. - The
runtimeEnvmaps the validated variables to the actual environmental variables (process.env) to validate before runtime.
Testing
Finally, run the application using npm run dev and inspect the console:

Notice the error message stating ❌Invalid environment variables, this message is very clear and concise; it tells us the problem is with the ERROR_VARIABLE, and that it must contain at least 1 character according to our validation schema.
Once your variables are valid, feel free to use them in your Next.js application as you wish. Here is an example displaying the environmental variable to the user (DON’T DO THIS IN YOUR REAL APPLICATION!).
import {env} from 'path/to/your/env.mjs'
const page = async () => {
// Logs the validated type-safe
// environmental variable to the console.
return (
<main>
{env.VALID_VARIABLE}
</main>
)
}
export default pageIt’s similar to using process.env but without the process part, just remember to import the env schema into your files to get type-safety for your variables.
We are done! I hope you’ve enjoyed this eventful journey that we’ve embarked on together, from validating environmental variables in your Next.js applications, to ensuring type-safety so that misspelling variables is a thing of the past.
If you have any questions or concerns, please do let me know in the comments, and as always, stay tuned! 👍






