npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@buzo/jenv

v1.0.0

Published

JENV - JavaScript Environment Variables with built-in templating, filters, and resolvers

Readme

endpoint-env

Compile API endpoint URLs from environment variables, using parameters, filters, and dynamic expressions.

Define your endpoints as templated strings in process.env, then build real URLs from them at runtime — with type coercion, defaults, string transforms, and live values like dates, timestamps, and UUIDs baked right in.

npm install endpoint-env

Quick Start

const endpoint = require('endpoint-env');

process.env.ENDPOINT_MATCH = 'https://api.example.com/matches/{matchId}';

const url = endpoint.build('match', { matchId: 12345 });

console.log(url);
// https://api.example.com/matches/12345

Endpoints are read from environment variables prefixed with ENDPOINT_ by default. The part of the variable name after the prefix (lowercased) becomes the "scope" you pass to build().

Loading a .env file

endpoint-env uses the official dotenv package for loading .env files, with additional support for variable interpolation.

Pass env: true when constructing an instance to load the default .env file from your current working directory before anything else runs:

const { EndpointEnv } = require('endpoint-env');

const endpoint = new EndpointEnv({
  env: true
});

// process.env is now populated from .env

You can pass the same options dotenv.config() accepts:

const endpoint = new EndpointEnv({
  env: {
    path: '.env.production',
    override: true,
    debug: true
  }
});

A bare path string is shorthand for { path: ... }:

const endpoint = new EndpointEnv({
  env: '.env.production'
});

And you can load multiple files in one go by passing an array:

const endpoint = new EndpointEnv({
  env: [{ path: '.env' }, { path: '.env.local' }]
});

Variable Interpolation

Variable interpolation is enabled by default, allowing you to reference other variables:

# .env
BASE_URL=https://api.example.com
ENDPOINT_USERS=${BASE_URL}/v1/users
ENDPOINT_MATCHES=${BASE_URL}/v1/matches/{matchId}

To disable interpolation:

const endpoint = new EndpointEnv({
  env: {
    path: '.env',
    interpolate: false
  }
});

Standalone dotenv usage

If you just want the loader itself, it's exported directly:

const { config } = require('endpoint-env');

config();                        // loads ./.env
config({ path: '.env.local' });  // loads a specific file

Security Features

Endpoint-env includes a security manager to control access to sensitive data:

const endpoint = new EndpointEnv({
  security: {
    envAllowlist: ['API_KEY', 'BASE_URL'],  // Only allow these env vars
    envDenylist: ['SECRET', 'PASSWORD'],    // Block specific env vars
    maxDepth: 5,                            // Limit nested parameter depth
    maxOutputSize: 1024 * 1024,             // Limit output size (1MB)
    allowCrypto: true,                      // Use crypto for random numbers
    safeMode: true                          // Disable dangerous resolvers
  }
});

Parameters

Wrap a placeholder in curly braces and pass the value in at build time:

ENDPOINT_MATCH=https://api.example.com/matches/{matchId}
endpoint.build('match', { matchId: 50 });
// https://api.example.com/matches/50

Default values

{page:1}

If no value is passed for page, it falls back to 1.

Nested parameters

{team.slug}
endpoint.build('team', { team: { slug: 'man-utd' } });
// resolves team.slug from the nested object

Filters

Chain one or more filters onto a parameter with |:

{name|trim|lowercase}
{title|slug}
{name|replace(_, )}
{title|truncate(20)}
{path|prepend(/api/)}
{file|append(.json)}

Built-in filters

Filter Description lowercase Convert to lowercase uppercase Convert to uppercase trim Trim whitespace capitalize Capitalize first letter slug Generate a URL-safe slug camel camelCase snake snake_case kebab kebab-case replace Replace text prepend Prefix a value append Suffix a value default Fallback when a value is empty truncate Limit string length padStart String.padStart padEnd String.padEnd slice Slice a string repeat Repeat a string urlencode URL-encode a value urldecode URL-decode a value number Coerce to a number, optionally fixed boolean Coerce truthy strings to a boolean split Split a string into an array join Join an array into a string first First element of an array last Last element of an array reverse Reverse a string or array

Expressions

Use ${...} for dynamic, parameter-free values:

${date}
${date(+5)}
${date(-2m)}
${timestamp}
${uuid}
${random(1,100)}
${env(API_KEY)}
${hostname}
${platform}
${arch}
${year}
${month}
${day}
${quarter}
${weekday}
${time}
${datetime}

There's also a shorthand for pulling in another environment variable directly:

$HOST
$HOST:fallback.example.com

Both $ENV shorthand and ${env(...)} are inserted as-is, without URL-encoding, since they're typically trusted values like a hostname.

Registering your own filters and resolvers

endpoint.registerFilter('shout', value => String(value).toUpperCase() + '!');
{value|shout}
endpoint.registerResolver('season', () => '2026-2027');
${season}

Both can be async — use endpoint.buildAsync() instead of endpoint.build() when any registered filter or resolver returns a promise.

Plugins

Bundle related filters/resolvers together and install them as a unit:

endpoint.use(env => {
  env.registerFilter('hello', value => 'Hello ' + value);
});

Two plugins ship with the package:

const endpoint = require('endpoint-env');

endpoint.use(endpoint.builtinPlugins.date);   // adds ${isoDate}, ${unix}
endpoint.use(endpoint.builtinPlugins.debug);  // adds ${debug}, |json, |length

Discovering and validating endpoints

endpoint.list();        // ['match', 'fixtures', 'search', ...]
endpoint.has('match');  // true

endpoint.validate('match');  // true, or an error message
endpoint.validateAll();      // { match: true, fixtures: true, ... }

endpoint.preload();          // compiles every configured endpoint up front

Validation and build errors point directly at the problem in the template:

Unknown filter 'nope' on parameter 'name'.

https://api.com/{name|nope}
                ^^^^^^^^^^^

Caching, freezing, and encoding

endpoint.clearCache();
endpoint.stats();
endpoint.freeze(); // prevents any further registerFilter/registerResolver/use calls
const { create } = require('endpoint-env');

// Disable URL-encoding entirely
const raw = create({ encode: false });

// Or supply your own encoder
const custom = create({
  encode(value) {
    return value;
  }
});

Multiple instances

The default export is a ready-to-use singleton. For isolated configuration (a different prefix, cache size, or encoder), create your own instance:

const { create } = require('endpoint-env');

const endpoint = create({
  prefix: 'MYAPP_',
  cacheSize: 50
});

Errors

All errors share a common base class and carry structured details:

const { errors } = require('endpoint-env');

try {
  endpoint.build('match');
} catch (err) {
  if (err instanceof errors.MissingParameterError) {
    // handle missing parameter
  }
}

Available error types: EndpointEnvError, ParserError, ValidationError, MissingParameterError, FilterError, ResolverError, ConfigurationError, PluginError, LimitError.

CLI

endpoint-env list
endpoint-env validate
endpoint-env preload
endpoint-env stats
endpoint-env build match '{"matchId":12345}'

API reference

build(scope, params?, context?)       Build a URL synchronously
buildAsync(scope, params?, context?)  Build a URL, awaiting async filters/resolvers
compile(scope)                        Parse and validate a template, returning its tokens
has(scope)                            Check whether a scope is configured
list()                                List all configured scope names
validate(scope)                       Validate a single scope
validateAll()                         Validate every configured scope
preload()                             Compile every configured scope up front
clearCache()                          Clear the compiled-template cache
stats()                               Inspect filters, resolvers, plugins, and cache state
freeze()                              Lock the instance against further registration
registerFilter(name, handler)
unregisterFilter(name)
registerResolver(name, handler)
unregisterResolver(name)
use(plugin)                           Install a plugin function
removePlugin(name)
config(options?)                      Load a .env file into process.env (standalone, like dotenv)
parse(source)                         Parse a .env-formatted string into an object
interpolate(value, env?)              Interpolate variables in a string

License

MIT © Brytest

See the LICENSE file for details.

MIT License

Copyright (c) 2026 Brytest

Permission is hereby granted...