Home > Web Front-end > JS Tutorial > body text

Why you should always add type safety to your environment variables?

Mary-Kate Olsen
Release: 2024-09-24 06:25:02
Original
552 people have browsed it

A little background

If you have been coding for a while, you know the importance of environment variables and the role it plays, and also the pain of figuring out a bug which was caused just because a damn env variable wasn’t set in your project, lol!

Earlier this year, I worked at an product based startup as a Full stack developer intern. As the project grew, the number of env variables also grew. And, everybody was working on separate features on separate branches, so we had no idea if someone introduced some new env variable in their branch which later got merged into the main branch. This created problems when I tried to deploy my branches, I had know idea that a new env var has been added to the the project.

Then, later I got introduced to T3 stack and it had a brilliant solution for adding type safety to env variables. I didn’t even know such a solution even existed. It’s always feels good to learn something new when you least expect it. T3 stack uses zod and @t3-oss/env-nextjs package to add type safety to your applications which I liked very much. After that, I made a commitment to always type-safe my env variables no matter what.

If you’re starting a new project, or already working in a team, I’d highly recommend you to please add type safety to your envs. Adding just this will save you your efforts for figuring out problems in your codebase.

Here’ how you can add it to your project. It’s fairly simple.

What is zod?

Zod is a lightweight, fast, schema declaration and validation library. A schema can be anything from a simple string, number to complex object type.

Basic usage

import {z} from 'zod';

const myBoolean = z.boolean();

myBoolean.parse('true'); // throws error
myBoolean.parse(true) // valid

Copy after login

Creating a nested object schema

import { z } from 'zod';

const userSchema = z.object({
    name: z.string(),
    age: z.number(),
    address: z.object({
        house_no: z.string(),
        locality: z.string(),
        city: z.string(),
        state: z.string(),
    })
});
Copy after login

You can create a simple object schema or create nested objects schema.

What is t3-oss/env-nextjs?

It is simply a package which will help us add type safety to env variables

Let’s create type-safe env variables

Create a env.js file at the root of your project.

import {createEnv} from "@t3-oss/env-nextjs"; import {z} from "zod";

export const env = createEnv({
  /*
   * Serverside Environment variables, not available on the client.
   * Will throw if you access these variables on the client.
   */
  server: {
    DB_URI: z.string().url(),
  },
  /*
   * Environment variables available on the client (and server).
   *
   * You'll get type errors if these are not prefixed with NEXT_PUBLIC_.
   */
  client: {
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
  },
  /*
   * Due to how Next.js bundles environment variables on Edge and Client,
   * we need to manually destructure them to make sure all are included in bundle.
   *
   * You'll get type errors if not all variables from `server` & `client` are included here.
   */
  runtimeEnv: {
    DB_URI: process.env.DATABASE_URL,
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
      process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
  },
});
Copy after login

Usage

import {env} from '@/env';

const CLERK_PUBLISHABLE_KEY = env.NEXT_PUBLISHABLE_KEY;

Copy after login

If you hover your cursor above NEXT_PUBLISHABLE_KEY, you can see that that value is typed as string, that means our env variables are typed now.

We’ve added type safe env variables, but this will not run on every build time. we have to import our newly created file into our next.config.js file. You can use unjs/jiti package for that.

First, install the jiti pacakge from npm.

import { fileURLToPath } from "node:url";
import createJiti from "jiti";
const jiti = createJiti(fileURLToPath(import.meta.url));

jiti("./app/env");
Copy after login

When working with import.meta.url, it provides the URL of the file you are currently working in. However, it includes a file:/// prefix, which you might not want. To remove that prefix, you can use the fileURLToPath function from the node:url module.

For example:

import {fileURLToPath} from 'node:url';

// Convert the file URL to a path
const filename = fileURLToPath(import.meta.url);

Copy after login

Now, if you do not have the required env variables, you will see an error like this -

Why you should always add type safety to your environment variables?

How to add type-safety to env variables in Node.js Projects?

import dotenv from "dotenv";
import { z } from "zod";

dotenv.config();

const schema = z.object({
  MONGO_URI: z.string(),
  PORT: z.coerce.number(),
  JWT_SECRET: z.string(),
  NODE_ENV: z
    .enum(["development", "production", "test"])
    .default("development"),
});

const parsed = schema.safeParse(process.env);

if (!parsed.success) {
  console.error(
    "❌ Invalid environment variables:",
    JSON.stringify(parsed.error.format(), null, 4)
  );
  process.exit(1);
}

export default parsed.data;

Copy after login

In Node.js projects we're going to be simply creating a zod schema and parsing it against our process.env in order to check whether all the env variables are set or not.

Usage

import express from "express";
import env from "./env";

const app = express();
const PORT = env.PORT || 5000; // PORT is type safe here....

app.listen(PORT, () => {
console.log("Connected to server on PORT ${PORT}");
connectDB();
});

Copy after login

That’s how you add type safety to your env variables. I hope you learnt something new in this tutorial.

Happy Coding!! ?

The above is the detailed content of Why you should always add type safety to your environment variables?. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!