JSPM

  • Created
  • Published
  • Downloads 1244
  • Score
    100M100P100Q106042F
  • License Apache-2.0

Type-safe config for TypeScript. Read typed values from any source, process.env, .env files, Cloudflare Workers bindings, browser bundles, or any object you supply. Zero runtime dependencies, one API across Node, Bun, Deno, Workers, and the browser. TC39 accessor decorators (legacy decorators at envapt/legacy), converters, and Standard Schema (zod/valibot/arktype) validation.

Package Exports

  • envapt
  • envapt/browser
  • envapt/config
  • envapt/legacy
  • envapt/workerd

Readme

envapt logo

envapt

The apt way to read typed config.
Read config from any source as real typed values, with zero runtime dependencies.

npm downloads jsr CI License


envapt returns config as the type you asked for instead of the string | undefined you get raw, with a fallback that removes undefined from the return type. It reads from whatever source you bind. On Node, Bun, and Deno that is process.env and your .env files, bound on import. On Cloudflare Workers, in the browser, or for a secrets object you fetched at boot, you bind the source with Envapter.useSource(...).

import { Envapter } from 'envapt';

const port = Envapter.getNumber('PORT', 3000); // number, not string | undefined

Read the docs →

What you get

  • Typed values. A fallback removes undefined from the return type. Built-in converters cover numbers, booleans, bigint, JSON, URLs, regular expressions, dates, durations, and arrays, or pass your own function or a Standard Schema validator (zod, valibot, arktype).
  • Any source. A source is any object with a readVars() method, so you can bind process.env, a Cloudflare Workers binding, a browser bundle, or a secrets payload you fetched from a store at boot. On Node, Bun, and Deno one binds on import.
  • Zero runtime dependencies. The reader, converters, and built-in .env parser are self-contained, so nothing is added to your dependency tree.
  • Runs on Node, Bun, Deno, Cloudflare Workers, and the browser. Node >=20, Bun >=1.3, Deno >=2.5 (ESM and CJS). The Workers and browser builds resolve through the package exports conditions.
  • .env loading built in on Node. The default Node source adds a per-environment file cascade, ${VAR} templates, and strict / required checks. Off Node there is no filesystem, so you bind another source with Envapter.useSource(...) and read with the same typed API.

Install

npm install envapt
pnpm add envapt
yarn add envapt
bun add envapt
deno add jsr:@materwelon/envapt

Quick start

Read values functionally with Envapter, or bind them to class fields with the @Envapt decorator. Both share the same parsing, converters, and cache.

Functional

Read a value from any call site, in JavaScript or TypeScript. No build step. On Node the source is bound for you. On Workers and in the browser, call Envapter.useSource(...) first.

import { Envapter, Converters } from 'envapt';

const port = Envapter.getNumber('PORT', 3000);
const origins = Envapter.getUsing('ALLOWED_ORIGINS', Converters.array(), []);

On Cloudflare Workers, env is importable at module scope, so bind it once in a config module; in the browser, seed a ManualEnvSource from the object your bundler injects.

import { env } from 'cloudflare:workers';
import { Envapter, WorkerEnvSource } from 'envapt';

Envapter.useSource(new WorkerEnvSource(env));

export const apiToken = Envapter.get('API_TOKEN');

Decorator

Bind a value to a class field with a TC39 accessor decorator. No experimentalDecorators flag, and it runs on Bun and Deno from .ts directly.

import { EnvNum, Converters } from 'envapt';

class Config {
    @EnvNum('PORT', 3000)
    static accessor port: number;
}

The legacy (experimentalDecorators) decorators are exported from envapt/legacy.

Agent skill

Install the envapt agent skill so AI coding tools use the correct API:

npx skills add materwelonDhruv/envapt

Built by @materwelonDhruv · Apache 2.0