Overview
The EnvManager class provides a unified API for accessing environment variables across Node.js and browser environments. It automatically detects the runtime and uses the appropriate method to access environment variables.
Import
import { EnvManager } from 'bytekit';
Usage
Basic Usage
const env = new EnvManager();
// Get environment variable
const apiUrl = env.get('API_URL');
if (apiUrl) {
console.log('API URL:', apiUrl);
}
// Get required environment variable (throws if missing)
try {
const apiKey = env.require('API_KEY');
console.log('API Key loaded');
} catch (error) {
console.error('Missing required API_KEY');
}
// Check environment
if (env.isProd()) {
console.log('Running in production');
}
With Vite
// In Vite projects, environment variables are exposed via import.meta.env
const env = new EnvManager();
// Access Vite environment variables
const apiUrl = env.get('VITE_API_URL');
const mode = env.get('MODE'); // 'development' or 'production'
With Next.js
// Next.js exposes environment variables via process.env
const env = new EnvManager();
// Access Next.js public environment variables
const publicApiUrl = env.get('NEXT_PUBLIC_API_URL');
// Check if production
if (env.isProd()) {
// Production-specific logic
}
Configuration Class
class AppConfig {
private env = new EnvManager();
get apiUrl(): string {
return this.env.require('API_URL');
}
get apiKey(): string {
return this.env.require('API_KEY');
}
get debug(): boolean {
return this.env.get('DEBUG') === 'true';
}
get isProd(): boolean {
return this.env.isProd();
}
get logLevel(): string {
return this.env.get('LOG_LEVEL') ?? 'info';
}
}
const config = new AppConfig();
export default config;
Validation
class ConfigValidator {
private env = new EnvManager();
validate() {
const required = ['API_URL', 'API_KEY', 'DATABASE_URL'];
const missing: string[] = [];
for (const key of required) {
if (!this.env.get(key)) {
missing.push(key);
}
}
if (missing.length > 0) {
throw new Error(
`Missing required environment variables: ${missing.join(', ')}`
);
}
}
getConfig() {
this.validate();
return {
apiUrl: this.env.require('API_URL'),
apiKey: this.env.require('API_KEY'),
databaseUrl: this.env.require('DATABASE_URL')
};
}
}
API Reference
Methods
get
Get an environment variable value.
Environment variable name
Environment variable value, or undefined if not found
const apiUrl = env.get('API_URL');
if (apiUrl) {
// Use apiUrl
}
require
Get a required environment variable, throwing an error if not found.
Environment variable name
Environment variable value
Throws: Error if environment variable is not defined
try {
const apiKey = env.require('API_KEY');
// Use apiKey
} catch (error) {
console.error('API_KEY is required');
}
isProd
Check if running in production environment.
True if NODE_ENV or MODE is ‘production’
if (env.isProd()) {
// Production-specific code
console.log('Running in production');
} else {
// Development-specific code
console.log('Running in development');
}
Runtime Detection
The EnvManager automatically detects the runtime environment:
- Browser: Uses
import.meta.env (Vite, modern bundlers)
- Node.js: Uses
process.env
// Works in both environments
const env = new EnvManager();
const value = env.get('MY_VAR');
// Browser: reads from import.meta.env.MY_VAR
// Node.js: reads from process.env.MY_VAR
Vite
Vite exposes environment variables with VITE_ prefix:
# .env
VITE_API_URL=https://api.example.com
VITE_API_KEY=abc123
const env = new EnvManager();
const apiUrl = env.get('VITE_API_URL');
Next.js
Next.js exposes public variables with NEXT_PUBLIC_ prefix:
# .env.local
NEXT_PUBLIC_API_URL=https://api.example.com
API_SECRET=secret123
const env = new EnvManager();
const apiUrl = env.get('NEXT_PUBLIC_API_URL'); // Available in browser
// API_SECRET only available in Node.js server-side code
Node.js
All environment variables are accessible:
# .env
API_URL=https://api.example.com
API_KEY=abc123
DATABASE_URL=postgres://...
const env = new EnvManager();
const apiUrl = env.get('API_URL');
const dbUrl = env.require('DATABASE_URL');
Use Cases
Application Configuration
class Config {
private static env = new EnvManager();
static readonly API_URL = Config.env.require('API_URL');
static readonly API_KEY = Config.env.require('API_KEY');
static readonly TIMEOUT = parseInt(Config.env.get('TIMEOUT') ?? '5000');
static readonly DEBUG = Config.env.get('DEBUG') === 'true';
static readonly IS_PROD = Config.env.isProd();
}
export default Config;
Feature Flags
class FeatureFlags {
private env = new EnvManager();
isEnabled(feature: string): boolean {
const value = this.env.get(`FEATURE_${feature.toUpperCase()}`);
return value === 'true' || value === '1';
}
}
const flags = new FeatureFlags();
if (flags.isEnabled('new_ui')) {
// Show new UI
}
Environment-Specific Behavior
class Logger {
private env = new EnvManager();
log(message: string) {
if (this.env.isProd()) {
// Production: send to logging service
this.sendToService(message);
} else {
// Development: log to console
console.log(message);
}
}
}
Best Practices
- Validate early: Check required variables at app startup
- Use require(): For critical variables to fail fast
- Provide defaults: Use
?? for optional variables with defaults
- Type conversion: Parse numbers/booleans explicitly
- Prefix public vars: Follow platform conventions (VITE_, NEXT_PUBLIC_)
Security
Never expose secrets in browser environment variables. Only use public prefixes (VITE_, NEXT_PUBLIC_) for non-sensitive data.
// ❌ Bad: exposing secret in browser
VITE_API_SECRET=secret123
// ✅ Good: keep secrets server-side
API_SECRET=secret123 // Not exposed to browser
// ✅ Good: public config in browser
VITE_API_URL=https://api.example.com