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

graphile-config

v1.0.0

Published

Standard plugin interface and helpers to be used across the Graphile stack.

Readme

graphile-config

GitHub Sponsors Discord chat room Follow Follow

PRERELEASE: this is pre-release software; use at your own risk. This will likely change a lot before it's ultimately released.

graphile-config provides a standard plugin interface and helpers that can be used across the entire of the Graphile suite. Primarily users will only use this as import type Plugin from 'graphile-config'; so that they can export plugins.

This package provides two interfaces: Plugin and Preset (alias Config).

Plugin

A plugin is responsible for adding capabilities to a Graphile package. Each Graphile package will register its own "scope" within the plugin's spec; commonly these scopes may contain capabilities such as 'hooks' or 'events' which this package attempts to standardize.

A Graphile Plugin is an object with the following properties:

  • name (string): The name of the plugin, this must be unique and will be used for capabilities such as skipPlugins
  • version (string): a semver-compliant version for the plugin, this would normally match the version in the package.json but does not need to (e.g. if the module in question contains multiple plugins)
  • description (optional string): human-readable description of the plugin in CommonMark (markdown) format.
  • provides (optional string[]): an optional list of "feature labels" that this plugin provides, this is primarily used to govern the order in which the plugin (and its hooks and events) are executed. Feature labels must be unique within the list of loaded plugins, for example two different plugins should not both provide subscriptions. If unspecified, defaults to the plugin name.
  • after (optional string[]): indicates that this plugin should be loaded after the named features (if present)
  • before (optional string[]): indicates that this plugin should be loaded before the named features (if present)

In addition to the properties above, plugins may also contain properties for each of the supported scopes, for example there may be a postgraphile scope for PostGraphile, or a worker scope for Graphile Worker. The value for each of these scopes will be an object, but the contents of that object are defined by the projects in question.

NOTE: Currently this plugin system is only intended for Graphile usage (and thus we do not need to "reserve" keys), but should you find it useful for other projects please reach out via GitHub issues and we can discuss what's necessary to make this more universal. Should you decide to not heed this advice, please at least make sure that the "scopes" you add are namespaced in a way to avoid future conflicts with features we may wish to add.

Preset

A preset bundles together a list of plugins, and options for various of the "scopes". You may use more than one preset at a time, and presets may also compose (extend) other presets. When a library is passed a list of presets it results in a resolved preset (a preset that has no "extends") using the ResolvePresets algorithm; broadly all the extends are resolved in order, the plugins specified are merged as a set (each plugin will only be included once) and the options are merged via object merging such that the options specified last win.

NOTE: if you compose two presets (PresetA and PresetB) that both extends the same underlying preset (BASE) and apply some overrides, then the overrides in PresetA will be overridden by re-applying the BASE preset again. For this reason, presets that are expected to be combined with other presets should not extends common/shared presets, instead the end-user should be expected to add these presets themselves.

NOTE: the order of presets is significant.

ResolvePresets(presets):

  1. Let {finalPreset} be an empty preset.
  2. For each {preset} in {presets}:
    1. Let {resolvedPreset} be {ResolvePreset(preset)}.
    2. Let {finalPreset} be {MergePreset(finalPreset, resolvedPreset)}.
  3. Return {finalPreset}.

ResolvePreset(preset):

  1. Let {presets} be the list specified in the {extends} property of {preset} (or an empty list if none specified).
  2. Let {basePreset} be {ResolvePresets(presets)}.
  3. Return {MergePreset(basePreset, preset)}.

MergePreset(basePreset, extendingPreset):

  1. Let {finalPreset} be an empty preset.
  2. Assert: {basePreset} has an empty or non-existent {extends} property.
  3. Let {plugins} be the list of plugins defined in {basePreset} union the list of plugins in {extendingPreset}.
  4. Let the list of plugins for {finalPreset} be {plugins}.
  5. Let {scopes} be the list of scopes defined in {basePreset} union the list of scopes in {extendingPreset}.
  6. For each {scope} in {scopes}:
    1. Let {baseScope} be the {scope} in {basePreset}.
    2. Let {extendingScope} be the {scope} in {extendingPreset}.
    3. If {baseScope} and {extendingScope} both exist:
      1. Let {scope} in {finalPreset} be the result of merging {baseScope} and {extendingScope} akin to Object.assign({}, baseScope, extendingScope).
    4. Else: let {scope} in {finalPreset} be whichever of {baseScope} and {extendingScope} actually exist.
  7. Return {finalPreset}.

IMPORTANT: the default name must not be used as a top-level key in a preset to enable compatibility with the various ESM emulations.

Crowd-funded open-source software

To help us develop this software sustainably, we ask all individuals and businesses that use it to help support its ongoing maintenance and development via sponsorship.

Click here to find out more about sponsors and sponsorship.

And please give some love to our featured sponsors 🤩:

* Sponsors the entire Graphile suite

Supporting TypeScript ESM

You can specify a graphile.config.ts file; but if that uses export default and your TypeScript is configured to export ESM then you'll get an error telling you that you cannot require an ES Module:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /path/to/graphile.config.ts
require() of ES modules is not supported.
require() of /path/to/graphile.config.ts from /path/to/node_modules/graphile-config/dist/loadConfig.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /path/to/package.json.

Or, in newer versions, an error saying unknown file extension:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /path/to/graphile.config.ts

To solve this, use the experimental loaders API to add support for TS ESM via the ts-node/esm loader:

export NODE_OPTIONS="$NODE_OPTIONS --loader ts-node/esm"

Then run your command again.