runenv-sdk
v0.1.1
Published
Node.js SDK for Runenv — load, manage, and push environment secrets directly in your application
Readme
runenv-sdk
Node.js SDK for Runenv — Load and manage secrets directly from your code.
Installation
npm install runenv-sdkRequirements
- Node.js 18 or later
- CommonJS (
require) and ESM (import) are both supported
Quick Start
import { Runenv } from 'runenv-sdk'
const runenv = new Runenv({
token: process.env.RUNENV_TOKEN!,
project: 'my-app',
environment: 'production',
serverUrl: 'https://your-runenv-server.com',
})
// Load all secrets into process.env
await runenv.load()
// Get a single secret
const dbUrl = await runenv.get('DATABASE_URL')
// Get a required secret (throws if not found)
const apiKey = await runenv.getOrThrow('API_KEY')
// Get multiple secrets at once
const { DATABASE_URL, REDIS_URL } = await runenv.getMany(
'DATABASE_URL',
'REDIS_URL'
)Push Secrets
// Upload secrets from code
await runenv.push({
DATABASE_URL: 'postgres://user:pass@host/db',
REDIS_URL: 'redis://localhost:6379',
API_KEY: 'sk_live_xxx',
})
// → { created: 2, updated: 1, total: 3 }Express Middleware
import express from 'express'
import { Runenv } from 'runenv-sdk'
const app = express()
const runenv = new Runenv({
token: process.env.RUNENV_TOKEN!,
project: 'my-api',
})
// Load secrets before all requests (once, then cached)
app.use(runenv.middleware())
app.get('/', (req, res) => {
// process.env.DATABASE_URL is now available!
res.json({ status: 'ok' })
})NestJS Integration
import { ConfigModule } from '@nestjs/config'
import { Runenv } from 'runenv-sdk'
@Module({
imports: [
ConfigModule.forRoot({
load: [
Runenv.nestConfig({
token: process.env.RUNENV_TOKEN!,
project: 'my-nestjs-app',
environment: 'production',
}),
],
}),
],
})
export class AppModule {}Watch for Changes
// Poll every 60 seconds for secret changes
const unwatch = runenv.watch(
(secrets) => {
console.log('🔄 Secrets updated!', Object.keys(secrets))
// e.g. reconnect database, refresh config, etc.
},
{ interval: 60 }
)
// Stop watching
unwatch()Initialize from Environment Variables
export RUNENV_TOKEN=rtk_xxxxxxxxxxxx
export RUNENV_PROJECT=my-app
export RUNENV_ENV=production
export RUNENV_API_URL=https://your-server.com
export RUNENV_SERVER_URL=https://your-server.comRunenv.fromEnv() reads RUNENV_TOKEN, RUNENV_PROJECT, RUNENV_ENV, and either RUNENV_API_URL or RUNENV_SERVER_URL.
import { Runenv } from 'runenv-sdk'
const runenv = Runenv.fromEnv()
await runenv.load()Functional API
import { loadSecrets, pushSecrets } from 'runenv-sdk'
// One-liner load
const secrets = await loadSecrets({
token: 'rtk_...',
project: 'my-app',
})
// One-liner push
await pushSecrets(
{ token: 'rtk_...', project: 'my-app' },
{ DATABASE_URL: 'postgres://...' }
)Packaging
require('runenv-sdk')for CommonJS runtimesimport { Runenv } from 'runenv-sdk'for ESM runtimes- Published package contents are limited to
dist/,README.md, andpackage.json
Validation
npm testverifies both CommonJS and ESM package entrypoints- Tests cover transient fetch failure recovery in
Runenv.load() npm pack --dry-runis validated to keep the published package minimal
API Reference
new Runenv(options)
| Option | Type | Default | Description |
| ------------- | -------- | ---------------------- | ---------------------------------- |
| token | string | required | Service token (rtk_...) or JWT |
| project | string | required | Project name |
| environment | string | "development" | Environment name |
| serverUrl | string | "https://runenv.dev" | Server URL |
| resolve | boolean | true | Resolve ${REF} references |
| cacheTtl | number | 300 | Cache TTL in seconds (0 = disable) |
| retries | number | 2 | Number of retries on failure |
| debug | boolean | false | Enable debug logging |
| logger | function | console | Custom logger function |
Methods
| Method | Returns | Description |
| ------------------ | ------------------------------ | -------------------------------- |
| load(override?) | Promise<Secrets> | Load secrets into process.env |
| get(key) | Promise<string \| undefined> | Get a single secret |
| getOrThrow(key) | Promise<string> | Get a secret (throws if missing) |
| getMany(...keys) | Promise<Partial<Secrets>> | Get multiple secrets at once |
| has(key) | Promise<boolean> | Check if a secret exists |
| keys() | Promise<string[]> | List all secret keys |
| push(secrets) | Promise<PushResult> | Upload secrets (upsert) |
| fetchSecrets() | Promise<Secrets> | Fetch all secrets from server |
| watch(cb, opts?) | () => void | Watch for changes (polling) |
| middleware() | Express middleware | Express/Connect middleware |
| clearCache() | void | Clear the secrets cache |
Static Methods
| Method | Description |
| ---------------------------- | -------------------------------- |
| Runenv.fromEnv(overrides?) | Create instance from env vars |
| Runenv.nestConfig(options) | NestJS ConfigModule async loader |
License
MIT
