Releases: hyperb1iss/next-dynenv
v4.0.6
Released: 2026-04-07
This release focuses on dependency modernization and npm publishing reliability. TypeScript is upgraded to 6.0, all CI infrastructure moves to Node 24 with the latest GitHub Actions, and a new prepack script fixes a packaging bug where raw catalog: protocol references were shipped to npm.
✨ Highlights
npm Compatibility Fix for pnpm Catalog Users
Published packages previously contained raw catalog: protocol references in package.json that npm cannot resolve, breaking npm install next-dynenv. A new scripts/resolve-catalog.mjs prepack script now resolves catalog references from pnpm-workspace.yaml before publishing and restores the original file via postpack. This closes #1.
TypeScript 6.0 Upgrade
The project now builds with TypeScript ^6.0.2, up from 5.9. This brings the latest type-checking improvements and language features to the codebase.
Node 24 and GitHub Actions Refresh
CI, docs, and release workflows all move to Node 24 and the latest action versions. The release workflow also switches to OIDC trusted publishing with npm publish --provenance, replacing the previous npm token-based approach and removing a broken npm install -g npm@latest self-upgrade step.
🔧 Packaging & Publishing
- Added
prepack/postpacklifecycle scripts inpackage.jsonthat back uppackage.json, resolve allcatalog:references to concrete version specifiers, then restore the original after packing - New
scripts/resolve-catalog.mjsparsespnpm-workspace.yamland rewritesdependencies,devDependencies,peerDependencies, andoptionalDependenciesin-place - Moved
reactfromdependenciestodevDependencies— it was already declared as apeerDependency, so shipping it as a direct dependency was unnecessary - Updated
.npmignoreto exclude/scripts,package.json.bak, and.claudefrom the published tarball
⬆️ Dependency Updates
| Package | Previous | Current |
|---|---|---|
typescript |
^5.9.3 | ^6.0.2 |
next |
^16.0.10 | ^16.2.2 |
react / react-dom |
^19.2.0 | ^19.2.4 |
vitest / @vitest/coverage-v8 |
^3.2.4 | ^4.1.2 |
@biomejs/biome |
^2.2.6 | ^2.4.10 |
prettier |
^3.5.3 | ^3.8.1 |
jsdom |
^26.1.0 | ^29.0.2 |
@types/node |
^24.7.2 | ^25.5.2 |
The next update to ^16.2.2 includes a fix for CVE-2025-59471. The Biome config schema in biome.jsonc is updated to match the new 2.4.10 version.
👷 CI & Infrastructure
- All workflows now target Node 24 (was 22)
- GitHub Actions version bumps across all workflows:
actions/checkoutv4 → v6actions/setup-nodev4 → v6pnpm/action-setupv4 → v5actions/upload-artifactv4 → v6actions/download-artifactv4 → v7actions/upload-pages-artifactv3 → v4
- Release workflow: removed the
npm install -g npm@lateststep that was failing with aMODULE_NOT_FOUNDerror forpromise-retryon newer runners - Release workflow:
npm publishnow includes the--provenanceflag for OIDC trusted publishing, providing cryptographic proof of build origin without relying on stored npm tokens
📝 Documentation
- Minor formatting fix in
README.md— removed a stray blank line in the server-side contexts section
Upgrade Notes
- No API changes — this is a drop-in upgrade from v4.0.5
- If you vendor or pin the TypeScript version in your project, note that
next-dynenvnow targets TypeScript 6.0 for its own build; your project can still use its own TypeScript version - The
reactpeer dependency requirement is unchanged; the move fromdependenciestodevDependenciesonly affects the published package metadata
v4.0.5
Full Changelog: v4.0.4...v4.0.5
v4.0.4
Full Changelog: v4.0.3...v4.0.4
v4.0.3
Full Changelog: v4.0.2...v4.0.3
v4.0.2
Release Notes v4.0.2
This release introduces serverOnly() for safe isomorphic access to server secrets and modernizes dependency management with pnpm catalog.
🌟 Highlights
✨ New serverOnly() Function for Isomorphic Server Secrets
Access server-only environment variables without throwing in browser contexts. Unlike env(), the new serverOnly() function gracefully returns a fallback value when called from client code, enabling cleaner isomorphic patterns.
import { serverOnly } from 'next-dynenv'
// Returns actual value on server, fallback on client
const dbUrl = serverOnly('DATABASE_URL', 'postgresql://localhost:5432/dev')
const apiSecret = serverOnly('API_SECRET_KEY') // undefined on clientThis is particularly useful for shared configuration modules with lazy evaluation patterns using Zod schemas.
📦 Centralized Dependency Versions with pnpm Catalog
Dependency versions are now centralized in pnpm-workspace.yaml using the catalog: protocol. This ensures consistent versions across the workspace and simplifies version bumps.
✨ Features
-
serverOnly()function — New export insrc/script/env.tsthat reads non-public environment variables without throwing in browser contexts. Returns the fallback value whenwindowexists, readsprocess.envon the server. -
pnpm catalog support — All dependencies in
package.jsonandtest-app/package.jsonnow usecatalog:references pointing to versions defined inpnpm-workspace.yaml. -
nextmoved to devDependencies — Thenextpackage is only needed for development and testing, not as a runtime dependency of the published package.
🔧 Improvements
-
pnpm version via
packageManagerfield — Upgraded to pnpm 10.26.0 and removed explicitPNPM_VERSIONenv variables from CI workflows. Thepnpm/action-setup@v4action automatically detects the version from thepackageManagerfield inpackage.json. -
Security override cleanup — Removed the
js-yamlsecurity override from pnpm config as the vulnerability in transitive dependencies has been resolved upstream. -
Security overrides for transitive deps — Added pnpm overrides for
glob(>=10.5.0) andbrace-expansion(>=2.0.2) to address security vulnerabilities.
v4.0.1
next-dynenv v4.0.1 ✨
Build once, deploy anywhere. This major release brings full Next.js 15/16 support, a complete rebrand, and powerful new features for type-safe runtime environment variables.
🎯 Highlights
- Next.js 15 & 16 Ready — Full compatibility with the latest Next.js and React 19
- New Identity — Rebranded from
next-runtime-envtonext-dynenv - Type-Safe Parsers — Boolean, number, array, JSON, URL, and enum parsers with full TypeScript inference
- Enhanced Security — XSS protection and frozen
window.__ENVobject - Modern Tooling — ESM-first, Biome + Prettier, Vitest test framework
- Trusted Publishing — OIDC-based npm publishing with provenance
⬆️ Next.js 15/16 Migration
New Dynamic Rendering APIs
Replaced deprecated unstable_noStore with modern Next.js APIs:
// PublicEnvScript & PublicEnvProvider now use:
import { connection } from 'next/server'
await connection()
// env() uses headers() as a side-effect for dynamic rendering
import { headers } from 'next/headers'Async Server Components
All server components are now properly async for React 19:
// Before (Next.js 14)
export function MyComponent() {
const apiUrl = env('API_URL')
return <div>{apiUrl}</div>
}
// After (Next.js 15+)
export async function MyComponent() {
const apiUrl = env('API_URL')
return <div>{apiUrl}</div>
}ESM Package
The package is now native ESM with "type": "module":
{
"type": "module",
"exports": {
".": {
"types": "./build/index.d.ts",
"import": "./build/index.js"
}
}
}🔒 Type-Safe Environment Parsers
New envParsers module for validated, type-safe environment variables:
import { env, envParsers } from 'next-dynenv'
// Boolean parsing
const debug = envParsers.boolean(env('DEBUG')) // true/false
// Number parsing
const port = envParsers.number(env('PORT')) // number
// Array parsing
const hosts = envParsers.array(env('ALLOWED_HOSTS')) // string[]
// JSON parsing with type inference
const config = envParsers.json<AppConfig>(env('CONFIG'))
// URL validation
const apiUrl = envParsers.url(env('API_URL')) // URL object
// ✨ NEW: Enum validation
type Env = 'development' | 'staging' | 'production'
const nodeEnv = envParsers.enum<Env>(env('NODE_ENV'), [
'development', 'staging', 'production'
])Required Variables with requireEnv()
import { requireEnv } from 'next-dynenv'
// Throws if undefined
const apiKey = requireEnv('API_KEY')Default Values
import { env } from 'next-dynenv'
// Returns default if undefined
const timeout = env('TIMEOUT', '5000')🛡️ Security Enhancements
XSS Protection
Script injection is now protected against </script> attacks:
// Malicious input: "</script><script>alert('xss')</script>"
// Safely escaped in the injected script tagFrozen Environment Object
window.__ENV is now frozen to prevent tampering:
// Attempting to modify throws in strict mode
window.__ENV.API_KEY = 'hacked' // ❌ TypeError📦 Package Rebrand
The package has been renamed for clarity and discoverability:
- npm install next-runtime-env
+ npm install next-dynenv- import { env } from 'next-runtime-env'
+ import { env } from 'next-dynenv'🧪 Testing Infrastructure
Vitest Migration
Replaced Jest with Vitest for faster, ESM-native testing:
pnpm test # Run tests
pnpm test:watch # Watch mode
pnpm test:coverage # Coverage reportIntegration Tests
New end-to-end integration test validates the core promise:
pnpm test:integrationVerifies:
- ✓ Runtime values override build-time values
- ✓
window.__ENVinjection works correctly - ✓ Standalone mode fully functional
- ✓ Both script and context provider approaches work
🔧 Modern Tooling
Biome + Prettier
- Biome — Fast Rust-based linting and formatting for TypeScript/JavaScript
- Prettier — Markdown, YAML, and JSON formatting only
- 10x faster linting, unified tooling, 12 fewer dependencies
pnpm lint # Check
pnpm lint:fix # Auto-fixCI/CD Overhaul
- Parallel job execution for faster builds
- Matrix testing across Node 18, 20, 22
- Codecov integration
- GitHub Actions summaries
- Trusted npm publishing with OIDC provenance
📚 Documentation
New VitePress Site
Beautiful documentation with:
- Getting Started guide
- API reference
- Deployment examples (Docker, Kubernetes, Vercel, Netlify)
- Troubleshooting guide
AI-Ready
Added llms.txt generation for AI/LLM contextual understanding.
💔 Breaking Changes
Node.js Requirement
{
"engines": {
"node": ">=20.9.0"
}
}Peer Dependencies
{
"peerDependencies": {
"next": "^15 || ^16",
"react": "^19"
}
}Package Name
Update your imports:
- import { env, PublicEnvScript } from 'next-runtime-env'
+ import { env, PublicEnvScript } from 'next-dynenv'🙏 Attribution
This project is a fork of next-runtime-env by Expatfile.tax LLC. All credit for the original implementation goes to them. This fork exists to provide continued maintenance and Next.js 15+ support.
📋 Full Changelog
Features
- ✨ Migrate to Next.js 15 dynamic rendering APIs
- ✨ Add type-safe env parsers (boolean, number, array, json, url)
- ✨ Add enum parser for validated environment variables
- ✨ Add
requireEnv()for required variables - ✨ Add default value support to
env() - 🔒 Add XSS protection for script injection
- 🔒 Freeze
window.__ENVwithObject.freeze()
Infrastructure
- ⬆️ Upgrade to Next.js 16 with ESM module system
- 📦 Rename package to
next-dynenv - ✅ Migrate from Jest to Vitest
- ⚡ Modernize tooling with Biome + Prettier
- ♻️ Refactor CI workflows for parallel execution
- 🔧 Add pnpm workspace configuration
- 🧪 Add integration test with real Next.js app
Documentation
- 📚 Add VitePress documentation site
- 📝 Comprehensive documentation overhaul
- 📝 Add llms.txt plugin for AI context
- 📝 Improve SEO metadata
Fixes
- 🐛 Fix client-side bundling issue in env-script component
- 🐛 Improve error handling for headers() outside request scope
- 🐛 Fix makeEnvPublic() to prevent double-prefixing
Full Commit History: de82ca4...HEAD