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 🙏

© 2025 – Pkg Stats / Ryan Hefner

ganzu

v0.0.9

Published

Organized configuration

Downloads

1,077

Readme

Ganzu

Load configuration from multiple sources, with support for predefined environments.

Usage

When using Ganzu, you define the configuration that you want to load, and separately define the sources that it should come from. By splitting this up, it allows you to use different loading strategies in different environments, such as using fixed values in testing, generated values in development, and environment variables in production.

To define a configuration, make a plain JS object that uses g to define each field:

import { g } from 'ganzu';

const Config = {
  port: g.number(),
  databaseUrl: g.string(),
};

Then define your sources:

import { EnvSource } from 'ganzu';

const sources = [new EnvSource()];

and finally load the configuration:

import { loadConfig } from 'ganzu';

const config = await load(Config, sources);

The result will be a plain JS object with the same structure as the definition, but with the values filled in from the sources. Ganzu provides automatic type inference for the configuration object, so the types of the fields will be inferred from the definition.

To get a concrete version of the type, you can use Infer:

import { Infer } from 'ganzu';

const Config = { /* ... */ };
type Config = Infer<typeof Config>;

Field configuration

Configurations are made up of several fields, each of which can be configured in several ways. Fields are required by default.

  • .default() sets a default value for a field if one isn't found in any source.
  • .constant() sets a value for a field that will not be overridden by any source.
  • .optional() is an alias for .default(null), and the type of the field must allow null.
  • .alias() provides an extra name that will be used when searching for values in a source. It may be repeated.

Fields are immutable, so calling these methods returns a new instance with the change applied, leaving the original unmodified. That also means these methods are chainable.

Configuration Environments

Since the configuration objects are plain JS objects, they can be manipulated at runtime, and specifically you can define multiple configurations, and choose one dynamically based on where your code is running.

For example, consider a service that needs to load a value from an S3 bucket. In production the name of the bucket to use comes from an environment variable. In development however, everyone will use the same mock bucket name. Configuring this as an environment variable for each developer can be tedious, especially if new values are introduced.

To handle this situation, define two configurations. The second definition should build off the first using the spread operator (...) and customize each field as needed. Because fields are immutable, configuring them won't affect the base configuration.

const BaseConfig = {
  port: g.number(),
  bucketName: g.string(),
}

const DevConfig = {
  ...BaseConfig,
  bucketName: BaseConfig.bucketName.default("mock-bucket"),
};

Now, when you load your configuration, you can choose which of these values to use.

const template = shouldUseDev() ? DevConfig : BaseConfig;
const config = loadConfig(template, sources);

In this way, you can adapt your configuration system to each environment without having to give up flexibility.

Sources

Besides EnvSource, this package also provides FixedSource, which loads its values from a JS object. It's primarily useful in tests.

Other sources can be defined by implementing the Source interface. See ganzu-json and ganzu-yaml for examples on how to do that.

To find more sources, see the ganzu-source tag on NPM.