ArkType

Validate environment variables with @arkenv/core and ArkType.

Edit on GitHub

ArkType strings can describe a port or a host without wrapping each key. ArkEnv's core engine takes those DSL strings, adds number.port and string.host, and coerces strings before validation.

arktype is a required peer of @arkenv/core. How this engine differs from Zod and Valibot is in Validators.

Installation

Install @arkenv/core and its peer arktype. The peer is required. @arkenv/core itself has no runtime dependencies.

npm install @arkenv/core arktype

Define your schema

Put the schema in env.ts and import { env } where the process starts. A missing key or a value that fails the schema throws ArkEnvError at that import, before the rest of the app runs. DSL strings cover the common keys. Reach for compiled type() when you need a morph or a function default.

./env.ts
import  from "@arkenv/core";

export const  = ({
  DATABASE_URL: "string",
  PORT: "number.port = 3000",
  DEBUG: "boolean = false",
  : "'development' | 'production' | 'test' = 'development'",
});

Automatic coercion

Environment variables arrive as strings. ArkEnv reads the compiled ArkType schema's JSON Schema and coerces those strings into numbers, booleans, and arrays before validation, so PORT is a number in application code.

./env.ts
import  from "@arkenv/core";

export const  = (
  {
    PORT: "number.port",
    DEBUG: "boolean",
    TAGS: "string[]",
  },
  {
    : {
      PORT: "8080",
      DEBUG: "true",
      TAGS: "web, api",
    },
  },
);

.PORT; // number
.DEBUG; // boolean
.TAGS; // string[]

To disable automatic string conversion and preserve raw strings for custom morphs, pass { coerce: false }. Learn more in Coercion.

Defaults and optionals

ArkType syntax supports inline default values and optional properties:

PatternBehavior
= 'value' / = 3000Fallback value when the variable is undefined
string | undefined or string?Optional environment variable
emptyAsUndefined: trueConverts empty strings ("") to undefined so defaults trigger

For specialized validators like string.host and number.port, see Keywords. To build complex custom schemas or morphs, see Defining types.

Next steps