Gathering detailed insights and metrics for schema-env
Gathering detailed insights and metrics for schema-env
Gathering detailed insights and metrics for schema-env
Gathering detailed insights and metrics for schema-env
env-schema
Validate your env variables using Ajv and dotenv
convict
Featureful configuration management library for Node.js (nested structure, schema validation, etc.)
env-vars-validator
A library who will validate your environment variables from AJV schema.
env-schema-cli
The enhanced CLI and a programmatic wrapper around env-schema environment variables validator against JSON Schema.
npm install schema-env
Typescript
Module System
Min. Node Version
Node Version
NPM Version
71
Supply Chain
99.4
Quality
84
Maintenance
100
Vulnerability
100
License
TypeScript (97.07%)
JavaScript (2.93%)
Total Downloads
1,547
Last Day
1
Last Week
9
Last Month
49
Last Year
1,547
MIT License
6 Stars
26 Commits
1 Watchers
4 Branches
1 Contributors
Updated on May 15, 2025
Latest Version
2.1.6
Package Id
schema-env@2.1.6
Unpacked Size
125.66 kB
Size
29.63 kB
File Count
9
NPM Version
10.2.4
Node Version
20.11.0
Published on
May 15, 2025
Cumulative downloads
Total Downloads
Last Day
-75%
1
Compared to previous day
Last Week
-10%
9
Compared to previous week
Last Month
-80.7%
49
Compared to previous month
Last Year
0%
1,547
Compared to previous year
Ever tried to build a LEGO set without the right pieces or with confusing instructions? Your app can feel the same way if its "environment variables" (special settings it needs to run) are wrong!
schema-env
is like a super-helpful assistant that checks these settings for your Node.js app before it even starts. It makes sure everything is A-OK, so your app can run smoothly and reliably.
schema-env
makes your app safer by checking its settings (like API keys, port numbers) against a rulebook (your Zod schema or custom adapter) right at the start. It can read settings from.env
files, special files for development/production, and even secret vaults! If something's wrong, it tells you immediately.
Think of environment variables as little notes you give your app:
PORT=3000
(Tells your app which door to use for web traffic)API_KEY=supersecret123
(A secret password to talk to another service)NODE_ENV=development
(Tells your app if it's in "practice mode" or "live mode")If these notes are missing, misspelled, or have the wrong kind of info (like text where a number should be), your app might get confused, crash, or even worse, do something unexpected!
schema-env
helps by:
schema-env
what notes your app expects and what they should look like.This makes your app:
.env
Files: Automatically loads settings from .env
files – a common way to store them..env.development
), "production" (.env.production
), etc.FULL_URL = ${BASE_URL}/api
).schema-env
knows which one to use.1. Install schema-env
and zod
(our default rulebook maker):
1npm install schema-env zod 2# or 3yarn add schema-env zod
2. Create Your Rulebook (envSchema.ts
):
Tell schema-env
what settings your app needs.
1// envSchema.ts 2import { z } from "zod"; // Zod helps us make the rules! 3 4export const envSchema = z.object({ 5 // Rule 1: NODE_ENV should be "development" or "production". Default to "development". 6 NODE_ENV: z.enum(["development", "production"]).default("development"), 7 8 // Rule 2: PORT should be a number. If not given, use 3000. 9 PORT: z.coerce.number().default(3000), 10 11 // Rule 3: GREETING_MESSAGE must be text, and you *must* provide it! 12 GREETING_MESSAGE: z.string().min(1, "Oops! You forgot the greeting message!"), 13}); 14 15// This creates a TypeScript type for our validated settings - super handy! 16export type Env = z.infer<typeof envSchema>;
3. Write Down Your App's Settings (.env
file):
Create a file named .env
in the main folder of your project.
1# .env 2GREETING_MESSAGE="Hello from schema-env!" 3PORT="8080"
(Notice we didn't put NODE_ENV
here? Our rulebook says it defaults to "development"!)
4. Tell schema-env
to Check Everything (in your app's main file, like index.ts
or server.ts
):
1// index.ts 2import { createEnv } from "schema-env"; 3import { envSchema, Env } from "./envSchema.js"; // Use .js for modern JavaScript modules 4 5let settings: Env; // This will hold our correct settings 6 7try { 8 // Time for the magic check! 9 settings = createEnv({ schema: envSchema }); 10 console.log("✅ Hooray! All settings are correct!"); 11} catch (error) { 12 console.error("❌ Oh no! Something's wrong with the settings."); 13 // schema-env already printed the detailed error messages for us! 14 process.exit(1); // Stop the app, because settings are bad. 15} 16 17// Now you can safely use your settings! 18console.log(`The app says: ${settings.GREETING_MESSAGE}`); 19console.log(`Running in ${settings.NODE_ENV} mode on port ${settings.PORT}.`); 20 21// Go ahead and start your amazing app! 22// startMyApp(settings);
If you run this and your .env
file is missing GREETING_MESSAGE
or PORT
is not a number, schema-env
will tell you!
If you have a setting NODE_ENV
(like in our example), schema-env
is extra smart:
NODE_ENV=development
, it will also try to load settings from a file named .env.development
.NODE_ENV=production
, it will look for .env.production
.Settings in these specific files will override settings from the main .env
file.
Want API_URL
to be ${HOSTNAME}/api
? Easy!
First, tell schema-env
you want to do this:
1settings = createEnv({ 2 schema: envSchema, // Your usual rulebook 3 expandVariables: true, // Set this to true! 4});
Then, in your .env
file:
1HOSTNAME="http://mycoolsite.com" 2API_URL="${HOSTNAME}/v1/data"
schema-env
will figure out API_URL
should be http://mycoolsite.com/v1/data
.
.env
FilesSometimes you want a base set of settings and then some local ones that only you use.
1settings = createEnv({ 2 schema: envSchema, 3 dotEnvPath: [".env.defaults", ".env.local"], // Checks .env.defaults, then .env.local 4});
Later files in the list override earlier ones. And the "mood" specific file (like .env.development
) still gets checked after all of these!
createEnvAsync
)Some settings, like database passwords, are too secret for .env
files. You might keep them in a "secrets manager" (like AWS Secrets Manager, HashiCorp Vault, etc.). schema-env
can fetch these before it checks all your rules!
1// mySecretFetcher.ts 2import type { SecretSourceFunction } from "schema-env"; 3 4export const fetchMyDatabasePassword: SecretSourceFunction = async () => { 5 console.log("🤫 Asking the secret vault for the DB password..."); 6 // In real life, you'd use a library here to talk to your secrets manager. 7 // We'll pretend it takes a moment: 8 await new Promise((resolve) => setTimeout(resolve, 50)); 9 return { 10 DB_PASSWORD: "ultra-secret-password-from-vault", 11 }; 12};
Then, in your app:
1// index.ts 2import { createEnvAsync } from "schema-env"; // Note: createEnvAsync! 3import { envSchema, Env } from "./envSchema.js"; // Your schema needs to expect DB_PASSWORD 4import { fetchMyDatabasePassword } from "./mySecretFetcher.js"; 5 6async function startAppSafely() { 7 let settings: Env; 8 try { 9 settings = await createEnvAsync({ 10 // await is important here! 11 schema: envSchema, 12 secretsSources: [fetchMyDatabasePassword], // Add your secret fetchers here 13 }); 14 console.log("✅ Secrets fetched and all settings are correct!"); 15 // console.log(`DB Password's first letter: ${settings.DB_PASSWORD[0]}`); // Be careful logging secrets! 16 } catch (error) { 17 console.error( 18 "❌ Oh no! Something went wrong with settings (maybe secrets?)." 19 ); 20 process.exit(1); 21 } 22 // startMyApp(settings); 23} 24 25startAppSafely();
If your team already uses another library like Joi or Yup to define rules, you can tell schema-env
to use that instead of Zod!
You'll need to create a small "adapter" that teaches schema-env
how to talk to your chosen library. This involves implementing the ValidatorAdapter
interface provided by schema-env
.
To use a custom validation library (like Joi, Yup, or your own):
ValidatorAdapter<TResult>
interface from schema-env
. This adapter will:
ValidationResult<TResult>
object, which tells schema-env
if validation succeeded (and the typed data) or failed (with standardized error details).createEnv
or createEnvAsync
using the validator
option. You'll also need to provide the expected result type as a generic argument (e.g., createEnv<undefined, MyCustomEnvType>({ validator: myAdapter })
).For a complete, runnable example showing how to create and use a custom adapter with Joi, please see the examples/custom-adapter-joi/
directory in this repository. It includes:
_ A Joi schema definition (env.joi.ts
).
_ The Joi adapter implementation (joi-adapter.ts
). * An example of how to use it (index.ts
).
This demonstrates the flexibility of schema-env
in integrating with various validation workflows.
If a setting is defined in multiple places, here's who wins (highest number wins):
For createEnv
(the simpler one):
.env
file(s) (and expanded if you turned that on).For createEnvAsync
(the one for secrets):
.env
file(s) (expanded if on).secretsSources
(the secret vaults).createEnv(options)
async createEnvAsync(options)
schema
: Your Zod rulebook. (Use this OR validator
)validator
: Your custom rulebook checker. (Use this OR schema
)dotEnvPath
: Which .env
file(s) to read. (e.g., './.env.custom'
or ['./.env.base', './.env.local']
). Defaults to just ./.env
. Can be false
to load no .env
files.expandVariables
: true
or false
to turn on smart links in .env
files. (Defaults to false
)secretsSources
: (Only for createEnvAsync
) A list of functions that go fetch your secrets.That's awesome! We'd love your help.
No vulnerabilities found.