ArkEnv

How to load environment variables

Learn environment variables management in different environments and deployment scenarios.

Local development

Using .env files

The most common way to manage environment variables during development is using .env files:

.env
DATABASE_HOST=localhost
DATABASE_PORT=5432
NODE_ENV=development
API_KEY=your-secret-key
LOG_LEVEL=debug

Best practices for .env files

  1. Document required variables Create a .env.example file to document required variables:

    .env.example
    DATABASE_HOST=localhost
    DATABASE_PORT=5432
    NODE_ENV=development
    API_KEY=your-secret-key-here
    LOG_LEVEL=info
  2. Gitignore configuration Add these patterns to your .gitignore:

    .gitignore
    .env
    .env.*
    !.env.example
  3. Environment-specific files Use different files for different environments:

    • .env.development - Development settings
    • .env.test - Test environment settings
    • .env.production - Production defaults (if needed)

Loading environment variables

Using dotenv

The simplest way to load environment variables is using the dotenv package:

src/index.ts
import 'dotenv/config';
// or
import * as dotenv from 'dotenv';
dotenv.config();

Framework-specific solutions

Many frameworks have built-in support for environment variables:

Next.js

Vite

Express

src/app.ts
import express from 'express';
import dotenv from 'dotenv';

dotenv.config();
const app = express();

Nest.js

src/app.module.ts
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
})

Runtime arguments

You can also supply variables when running your application:

DATABASE_HOST=localhost DATABASE_PORT=5432 npm start

Production deployment

Cloud platforms

AWS

  • Use AWS Systems Manager Parameter Store for non-sensitive values
  • Use AWS Secrets Manager for sensitive values
  • Set environment variables in ECS Task Definitions or Lambda configurations

Google Cloud Platform

  • Use Cloud Secret Manager for sensitive values
  • Set environment variables in Cloud Run or App Engine configurations

Azure

  • Use Azure Key Vault for sensitive values
  • Configure App Settings in Azure App Service

Container environments

Docker

Dockerfile
ENV NODE_ENV=production
docker-compose.yml
services:
  app:
    environment:
      - NODE_ENV=production
      - DATABASE_HOST=db

Kubernetes

deployment.yaml
spec:
  containers:
    - name: app
      env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database-host

Traditional hosting

  • Set environment variables through the hosting platform's dashboard
  • Use deployment scripts to configure environment variables
  • Consider using configuration management tools

Security best practices

  1. Never commit sensitive values

    • Keep .env files out of version control
    • Use secrets management services in production
  2. Use different values per environment

    • Don't share sensitive credentials between environments
    • Use environment-specific configurations
  3. Access control

    • Limit access to production environment variables
    • Use role-based access control for secrets management
  4. Encryption

    • Encrypt sensitive values at rest
    • Use secure channels for transmitting secrets

Validation and typesafety

ArkEnv helps ensure your environment variables are valid:

src/config/env.ts
import  from 'arkenv';

export const  = ({
  // Required variables with validation
  : "string.host",
  : "number.port",
  
  // Boolean values (accepts "true"/"false" strings, converts to boolean)
  : "boolean",
  
  // Optional variables with defaults
  : "'debug' | 'info' | 'warn' | 'error' = 'info'",
  
  // Optional variables
  "FEATURE_FLAGS?": 'string[]'
});

Configuration options

ArkEnv supports several configuration options to customize its behavior:

Validator mode

Choose between ArkType (default) or Standard Schema validators:

src/config/env.ts
import  from 'arkenv';
import {  } from 'zod';

// ArkType mode (default) - requires ArkType to be installed
const  = ({
  : "number.port",
  : "string.host",
});

// Standard mode - works without ArkType
const  = (
  {
    : ..().().(0).(65535),
    : .().(),
  },
  { : "standard" }
);

Coercion

Control automatic type conversion (only available in ArkType mode):

src/config/env.ts
import  from 'arkenv';

// Coercion enabled (default)
const  = ({
  : "number.port", // "3000" becomes 3000
});

// Coercion disabled
const  = (
  {
    : "number.port",
  },
  { : false } // Must be a number; strings (like those from process.env) will fail
);

Note

Since process.env values are always strings, using coerce: false with numeric or boolean schemas will cause validation to fail unless you provide a custom env source containing the expected literal types.


### Custom environment source

Provide a custom environment object:

```typescript title="src/config/env.ts" twoslash
import arkenv from 'arkenv';

const env = arkenv(
  {
    PORT: "number.port",
  },
  {
    env: {
      PORT: "3000",
      // ... other variables
    },
  }
);

Array format

Control how arrays are parsed (only available in ArkType mode):

src/config/env.ts
import  from 'arkenv';

// Comma-separated (default)
const  = (
  {
    : "string[]",
  },
  {
    : { : "web, app, api" },
    : "comma",
  }
);

// JSON format
const  = (
  {
    : "string[]",
  },
  {
    : { : '["web", "app"]' },
    : "json",
  }
);

For more details on configuration options, see the coercion documentation and Standard Schema integration guide.

Common patterns

Configuration factory

Create a configuration factory to handle different environments:

src/config/index.ts
import  from 'arkenv';

const  = () => {
  const  = ({
    : "'development' | 'test' | 'production'",
    : "string.host",
    : "number.port",
  });

  return {
    : . === 'production',
    : {
      : .,
      : .,
    }
  };
};

export const  = ();

Feature flags

Use environment variables for feature flags:

src/config/features.ts
import  from 'arkenv';

export const  = ({
  "ENABLE_BETA_FEATURES": 'boolean = false',
  "MAINTENANCE_MODE": 'boolean = false',
  "ALLOWED_ORIGINS": 'string[]'
});

Troubleshooting

Common issues

  1. Missing variables

    • Check if .env file exists
    • Verify variable names match exactly
    • Ensure variables are loaded before use
  2. Type errors

    • Verify variable types match schema
    • Check for typos in variable names
    • Ensure all required variables are provided
  3. Loading order

    • Load environment variables before importing config
    • Consider using a bootstrap file
    • Check framework-specific loading behavior