envey
TypeScript icon, indicating that this package has built-in type declarations

3.0.1 • Public • Published

envey

CI status license npm version

Envey is a library designed to simplify the process of managing and validating environment variables in JavaScript applications. It provides a fully type-safe solution for defining and parsing configuration schemas, leveraging the power of Zod's excellent type system and validation features.

Works everywhere: Node.js, Cloudflare Workers, browsers, React Native, and any JavaScript runtime.

As of v2.6.0, it also supports nested objects. See nested objects for more details.

Why

I was looking for something like convict, but with the type safety and validation features of Zod. Hence, I decided to create this library.

Installation

pnpm i -E zod envey

Usage

import { z } from 'zod/v4'
import { createConfig } from 'envey'

const result = createConfig(
    {
        databaseUrl: {
            env: 'DATABASE_URL',
            format: z.string(),
        },
        port: {
            env: 'PORT',
            format: z.coerce.number().int().positive().max(65535),
        },
    },
    { validate: true },
)

if (!result.success) {
    console.error(result.error.issues)
    // Handle error
}

const { config } = result
//    ^? {
//           readonly databaseUrl: string;
//           readonly port: number;
//       }

Supports schema type inference, similar to Zod's infer:

const schema = {
    logLevel: {
        env: 'LOG_LEVEL',
        format: z.enum([
            'fatal',
            'error',
            'warn',
            'info',
            'debug',
            'trace',
            'silent',
        ]),
    },
} satisfies EnveySchema

type Config = InferEnveyConfig<typeof schema>
//   ^? {
//          readonly logLevel:  "fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent"
//      }

Custom environment variables

By default, createConfig reads environment variables from process.env. However, you can provide a custom environment object as the third parameter. This is particularly useful for:

  • Non-Node.js environments (Cloudflare Workers, browsers, React Native)
  • Testing with mock environment variables
  • Multi-tenant applications with different configurations
import { z } from 'zod/v4'
import { createConfig } from 'envey'

const schema = {
    apiKey: {
        env: 'API_KEY',
        format: z.string(),
    },
    port: {
        env: 'PORT',
        format: z.coerce.number().default(3000),
    },
} satisfies EnveySchema

// Default behavior - uses process.env (Node.js)
const config1 = createConfig(schema, { validate: true })

// Custom environment object
const customEnv = {
    API_KEY: 'custom-api-key',
    PORT: '8080',
}
const config2 = createConfig(schema, { validate: true }, customEnv)

// Works in Cloudflare Workers (no process.env)
const config3 = createConfig(schema, { validate: true }, {
    API_KEY: env.API_KEY, // Cloudflare Workers env binding
    PORT: '3000',
})

// Testing with mock data
const config4 = createConfig(schema, { validate: true }, {
    API_KEY: 'test-key',
    // PORT not provided - will use default value
})

Environment compatibility:

  • Node.js: Automatically uses process.env when available
  • Cloudflare Workers: Provide custom env object (no process.env available)
  • Browsers/React Native: Provide custom env object or empty object for defaults
  • Testing: Mock environment variables without affecting process.env

Nested objects

import { z } from 'zod/v4'
import { createConfig } from 'envey'

const result = createConfig(
    {
        postgres: {
            host: {
                env: 'PG_HOST',
                format: z.string().default('localhost'),
            },
            port: {
                env: 'PG_PORT',
                format: z.coerce.number().int().positive().max(65535).default(5432),
            }
            user: {
                env: 'PG_USER',
                format: z.string().default('postgres'),
            },
            password: {
                env: 'PG_PASSWORD',
                format: z.string().min(1),
            },
            database: {
                env: 'PG_DATABASE',
                format: z.string().min(1),
            },
        }
    },
    { validate: true },
)

if (!result.success) {
    console.error(result.error.issues)
    // Handle error
}

const { postgres } = result.config
//    ^? {
//           readonly host: string;
//           readonly port: number;
//           readonly user: string;
//           readonly password: string;
//           readonly database: string;
//       }

License

MIT

Package Sidebar

Install

npm i envey

Weekly Downloads

13

Version

3.0.1

License

MIT

Unpacked Size

56.3 kB

Total Files

23

Last publish

Collaborators

  • samialdury