npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details


  • User packages



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.


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 🙏

© 2023 – Pkg Stats / Ryan Hefner




A powerful yet simple tool for configuring all your libraries consistently.





A powerful yet simple tool for configuring all your libraries consistently in one place under one configuration hierarchy.

Code Basics

  1. Declare a Configurable wherever you need config values.
  2. Declare a Configuration for Development, Production and/or test
  3. and run configure() when initializing your app.

Configuration Sources

ArtConfig supports reading the artConfigName and artConfig configuration values from many sources:

  1. environment:
    • NodeJS: system variables (e.g. export artConfigName=dev)
    • Browser: query params (e.g. ?artConfigName=dev)
  2. options passed at runtime (e.g. &ArtConfig.configure(artConfigName: dev))
  3. globals (e.g. window.artConfigName = dev;)
  4. Configuration selected by artConfigName
  5. Each Configurable's defaults


npm install art-config



ArtConfig is a hierarchical configuration system. It provides a universal way to configure all libraries and applications in one hierarchical namespace. ArtConfig standardizes how configuration values are collected, normalized and registered with each registered Configurable.

Concept: The ArtConfig Tree

All config managed by ArtConfig is represented in a hierarchy of plain javascript objects. You can access this entire tree by calling: &ArtConfig.getArtConfig()

The paths in this hierarchy are defined by the Neptune Namespaces in which each Configurable is declared.


import &ArtConfig
# This configurable
# source/Any/Path/You/Want/Config.caf
class Config extends Configurable
    foo: :bar

# is accessible at this path:

# Therefor the following asserts will pass:
# (assuming there is only the one Configurable registered)
# (assert.eq is from ArtTestbench and uses deep-equality)

  Any: Path: You: Want: foo: :bar

Concept: Configurable (class to inherit from)

Declare slices of the artConfig tree to be configured. Each Configurable can have default values and post-configure hooks.

# source/MyApp/Config.caf
import &ArtConfig
class Config extends Configurable
    serverUrl:  "https://abc.def"
    apiKey:     null
    apiSecret:  null

  @on configured: ({serverUrl}) ->
    openConnection serverUrl

You can access the config values from elsewhere:

# AnotherFile.caf
import &Config

logInfo = -> console.log config.serverUrl

Note: Configurables depend on NeptuneNamespaces to define their configuration-path. The configuration-path is set to the namespaces hierarchy in which your configurable class is declared. You can call YourConfig.getConfigurationPath() to determine what your config's path is.

Concept: Configuration (class to inherit from)

Configurations are automatically registered. They are selected at configure time via the artConfigName value. There can only be one Configuration for each artConfigName value (e.g. Production, Development, Test, etc...).

class Development extends &ArtConfig.Configuration
  MyApp: # Note, this is the configurable's Configuration-Path, see above
    serverUrl: "http://localhost:3000"

Concept: configure during App Initialization

When your application actually starts, you need to run configure to gather up all the configuration data and route them to the correct Configurables.


Loading Configuration

When using ArtConfig, you need to call configure at some point during your application initialization sequence. This will collect configuration from all the configuration sources (e.g. the environment, the global, the URL params, and any config you pass in explicitly). Configure also selects which config to use.

# most the time you only need this:

# but sometimes you might want to provide some options (e.g. for various Tests)
  artConfigName: :Test
  artConfig: MyApp: serverUrl: "test.bad.url"


The input is a single, options object with these optional fields:

  • artConfigName: string

    can be passed in: as an argument` via process.env via the browser query string

    default: "Development"

    EFFECT: ArtConfig.artConfigName = externalEnvironment.artConfigName || artConfigName

  • artConfig: JSON string OR plain object structure

    can be passed in: as an argument via process.env via the browser query string

    default: {}

    EFFECT: mergeInto ArtConfig.artConfig, deepMerge ConfigRegistry.configs[artConfigName] global.artConfig artConfig externalEnvironment.artConfig

  • onConfig: (artConfig) ->

    gets called as soon as artConfig completes with the final artConfig


callback @artConfig for callback in ConfigRegistry.configurables


import &ArtConfig

# default artConfigName is Development
  artConfig: {}

  artConfigName:  :Production
  artConfig:      verbose: true

  artConfigName:  :Test
  artConfig:      {}

Config Sources

Actual Config data can come from several different places:

  1. Environment:
    • NodeJS: system environment
    • Browser: query params
  2. Options: options passed directly into the configure function
  3. Configurations: Production, Development, Test or other configuration classes declared in your application.
  4. Global: global runtime environment (window / self / global)
  5. Configurable defaults: Configurables have default values

Definition of Terms

  • environment:
    • NodeJS: process.env
    • Browser:, parsed (the current URL's query params)
  • options: the object passed in. e.g. ArtConfig.configure(options)
  • global:
    • NodeJS: global
    • Browser: window

How artConfigName is Selected

The first non-empty string is used from:

  1. environment.artConfigName
  2. options.artConfigName
  3. global.artConfigName

Note: artConfigName are noramlized using ArtStandardLib.upperCamelCase (e.g. Production and production are the same). Shortcuts prod and dev are allowed and are automatically rewritten to production and development.

How artConfig is Generated

Generating ArtConfig.artConfig is the essential purpose of ArtConfig. It is a namespaced hierarchy of arbitrary config values. This hierarchy is simply a deep merging of config values from the following sources. This list is in priority order. Higher priority values override lower priority ones (#1 is the highest priority):

ArtConfig Priority:

  1. environment.artConfig (JSON encoded string)
  2. options.artConfig (plain object data structure)
  3. global.artConfig (plain object data structure)
  4. Configuration (selected from the registered Configurations using artConfigName's value: Production, Development, Test, etc...)
  5. Configurable defaults