Examples
Real-world examples for different frameworks and use cases.
Next.js (App Router)
Next.js App Router
// app/config/env.ts
import { env } from "@liahus/safe-env";
export const ENV = env({
DATABASE_URL: "string:url",
NEXTAUTH_SECRET: "string:min=32:secret",
NEXTAUTH_URL: "string:url",
NODE_ENV: "enum:development,production,test",
});
// Use it anywhere in your app
// app/api/users/route.ts
import { ENV } from "@/app/config/env";
export async function GET() {
// ENV is fully typed!
const dbUrl = ENV.DATABASE_URL;
// ...
}Next.js (Pages Router)
Next.js Pages Router
// lib/env.ts
import { env } from "@liahus/safe-env";
export const ENV = env({
DATABASE_URL: "string:url",
API_KEY: "string:min=20:secret",
NODE_ENV: "enum:development,production,test",
});
// Use in pages or API routes
// pages/api/hello.ts
import { ENV } from "@/lib/env";
export default function handler(req, res) {
res.json({ env: ENV.NODE_ENV });
}Express
Express
// config/env.ts
import { env } from "@liahus/safe-env";
export const ENV = env({
PORT: "number:default=3000",
DATABASE_URL: "string:url",
JWT_SECRET: "string:min=32:secret",
NODE_ENV: "enum:development,production,test",
});
// server.ts
import express from "express";
import { ENV } from "./config/env";
const app = express();
app.listen(ENV.PORT, () => {
console.log(`Server running on port ${ENV.PORT}`);
console.log(`Environment: ${ENV.NODE_ENV}`);
});Fastify
Fastify
// config/env.ts
import { env } from "@liahus/safe-env";
export const ENV = env({
PORT: "number:default=3000",
HOST: "string:default=0.0.0.0",
DATABASE_URL: "string:url",
JWT_SECRET: "string:min=32:secret",
});
// server.ts
import Fastify from "fastify";
import { ENV } from "./config/env";
const fastify = Fastify({ logger: true });
fastify.listen({ port: ENV.PORT, host: ENV.HOST }, (err) => {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});NestJS
NestJS
// src/config/env.config.ts
import { env } from "@liahus/safe-env";
export const ENV = env({
PORT: "number:default=3000",
DATABASE_URL: "string:url",
JWT_SECRET: "string:min=32:secret",
NODE_ENV: "enum:development,production,test",
});
// Use in modules
// src/app.module.ts
import { Module } from "@nestjs/common";
import { ENV } from "./config/env.config";
@Module({
// ...
})
export class AppModule {
constructor() {
console.log(`Server running on port ${ENV.PORT}`);
}
}Testing
Testing
// tests/setup.ts
import { env } from "@liahus/safe-env";
// Create test environment
export const testEnv = env(
{
DATABASE_URL: "string:url",
API_KEY: "string:min=10",
PORT: "number:default=3000",
},
{
env: {
DATABASE_URL: "https://test-db.example.com",
API_KEY: "test-api-key-12345",
PORT: "8080",
},
}
);
// Use in tests
// tests/api.test.ts
import { testEnv } from "./setup";
describe("API", () => {
it("should use test environment", () => {
expect(testEnv.DATABASE_URL).toBe("https://test-db.example.com");
expect(testEnv.PORT).toBe(8080);
});
});With dotenv
With dotenv
// Load .env file first
import "dotenv/config";
import { env } from "@liahus/safe-env";
// Now process.env is populated from .env file
export const ENV = env({
DATABASE_URL: "string:url",
PORT: "number:default=3000",
JWT_SECRET: "string:min=32:secret",
});
// .env file:
// DATABASE_URL=https://db.example.com
// PORT=3000
// JWT_SECRET=your-secret-key-hereComplex Schema
Complex Schema
import { env } from "@liahus/safe-env";
const ENV = env({
// Database
DATABASE_URL: "string:url:secret",
DATABASE_POOL_SIZE: "number:min=1:default=10",
// API
API_URL: "string:url",
API_KEY: "string:min=32:secret",
API_TIMEOUT: "number:min=1000:default=5000",
// Authentication
JWT_SECRET: "string:min=32:secret",
JWT_EXPIRES_IN: "string:default=7d",
SESSION_SECRET: "string:min=32:secret",
// Environment
NODE_ENV: "enum:development,production,test",
LOG_LEVEL: "enum:debug,info,warn,error:default=info",
// Server
PORT: "number:min=1:default=3000",
HOST: "string:default=0.0.0.0",
CORS_ORIGIN: "string:url",
// Feature Flags
ENABLE_ANALYTICS: "enum:true,false:default=false",
ENABLE_CACHE: "enum:true,false:default=true",
});
// All fully typed and validated!Error Handling in Production
Production Error Handling
import { env, EnvValidationError } from "@liahus/safe-env";
let ENV: ReturnType<typeof env>;
try {
ENV = env({
DATABASE_URL: "string:url",
PORT: "number:default=3000",
JWT_SECRET: "string:min=32:secret",
});
} catch (error) {
if (error instanceof EnvValidationError) {
// Log error (secrets are already masked)
console.error("❌ Environment validation failed:");
console.error(error.message);
// Exit with error code
process.exit(1);
}
throw error;
}
// ENV is guaranteed to be valid here
export { ENV };