Type-safe environment variable access for ReScript with automatic runtime detection.
Part of the ReScript Full Stack ecosystem.
Part of the ReScript Full Stack ecosystem.
rescript-env provides a type-safe, cross-runtime API for accessing environment variables in ReScript applications. It automatically detects whether your code is running in Deno, Bun, or Node.js and uses the appropriate APIs.
| Problem | Solution |
|---|---|
Environment variables are stringly-typed |
Returns |
No built-in type coercion |
|
Runtime differences (Deno vs Node) |
Automatic runtime detection and API selection |
Missing required config crashes apps |
|
Boilerplate for dev/prod checks |
Built-in |
// Required configuration - throws if missing
let databaseUrl = Env.getExn("DATABASE_URL")
// Optional with default
let port = Env.getOr("PORT", "3000")
// Type-safe coercion
let maxConnections = Env.getInt("MAX_CONNECTIONS") // option<int>
let debugMode = Env.getBool("DEBUG") // option<bool>
let timeout = Env.getFloat("TIMEOUT_SECONDS") // option<float>
// Environment detection
if Env.isDevelopment() {
Console.log("Running in development mode")
}
// Check existence
if Env.has("API_KEY") {
// API key is configured
}let get: string => option<string>Returns Some(value) if the environment variable is set, None otherwise.
switch Env.get("API_KEY") {
| Some(key) => authenticateWith(key)
| None => Console.log("No API key configured")
}let getOr: (string, string) => stringReturns the environment variable value or the provided default.
let host = Env.getOr("HOST", "localhost")
let port = Env.getOr("PORT", "8080")let getInt: string => option<int>Parses the environment variable as an integer.
let port = Env.getInt("PORT")->Option.getOr(3000)
let workers = Env.getInt("WORKERS")->Option.getOr(4)let getFloat: string => option<float>Parses the environment variable as a float.
let timeout = Env.getFloat("TIMEOUT_SECONDS")->Option.getOr(30.0)let getBool: string => option<bool>Parses the environment variable as a boolean. Recognises:
-
True values:
"true","1","yes","on" -
False values:
"false","0","no","off"
let debug = Env.getBool("DEBUG")->Option.getOr(false)
let enableMetrics = Env.getBool("ENABLE_METRICS")->Option.getOr(true)let set: (string, string) => unitSets an environment variable.
Env.set("NODE_ENV", "test")let has: string => boolChecks if an environment variable is set.
if Env.has("REDIS_URL") {
initializeRedisCache()
}let isDevelopment: unit => boolReturns true if NODE_ENV, DENO_ENV, or ENV is "development" or "dev".
let isProduction: unit => boolReturns true if NODE_ENV, DENO_ENV, or ENV is "production" or "prod".
Create a dedicated configuration module that validates all required env vars at startup:
// src/Config.res
let database = {
"url": Env.getExn("DATABASE_URL"),
"maxConnections": Env.getInt("DB_MAX_CONNECTIONS")->Option.getOr(10),
"timeout": Env.getFloat("DB_TIMEOUT")->Option.getOr(30.0),
}
let server = {
"host": Env.getOr("HOST", "0.0.0.0"),
"port": Env.getInt("PORT")->Option.getOr(3000),
}
let features = {
"debug": Env.getBool("DEBUG")->Option.getOr(false),
"metrics": Env.getBool("ENABLE_METRICS")->Option.getOr(true),
}// Validate all required env vars at startup
let validateConfig = () => {
let required = ["DATABASE_URL", "SECRET_KEY", "API_ENDPOINT"]
let missing = required->Array.filter(name => !Env.has(name))
if Array.length(missing) > 0 {
Console.error("Missing required environment variables:")
missing->Array.forEach(name => Console.error(` - ${name}`))
Process.exit(1)
}
}rescript-env automatically detects the JavaScript runtime:
| Runtime | Detection | API Used |
|---|---|---|
Deno |
|
|
Node.js / Bun |
|
|
Browser / Unknown |
Neither exists |
Returns |
# Install dependencies and build
deno task build
# Watch mode for development
deno task dev
# Clean build artifacts
deno task cleanrescript-env/
├── src/
│ ├── Env.res # Implementation
│ └── Env.resi # Public interface
├── deno.json # Deno configuration
├── rescript.json # ReScript compiler config
├── README.adoc # This file
├── ROADMAP.adoc # Future plans
├── CHANGELOG.adoc # Version history
└── LICENCE # AGPL-3.0-or-laterThis library is part of the ReScript Full Stack ecosystem:
| Library | Purpose |
|---|---|
Environment variable access (this library) |
|
Ecosystem overview and integration |
|
More coming soon… |
See ROADMAP.adoc |
See CONTRIBUTING.md for guidelines.
SPDX-License-Identifier: AGPL-3.0-or-later
Copyright © 2025 Hyperpolymath
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.