Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

cosmiconfig

cosmiconfig200.4mMIT9.0.0TypeScript support: included

Find and load configuration from a package.json property, rc file, TypeScript module, and more!

load, configuration, config

readme

cosmiconfig

codecov

Cosmiconfig searches for and loads configuration for your program.

It features smart defaults based on conventional expectations in the JavaScript ecosystem. But it's also flexible enough to search wherever you'd like to search, and load whatever you'd like to load.

By default, Cosmiconfig will check the current directory for the following:

  • a package.json property
  • a JSON or YAML, extensionless "rc file"
  • an "rc file" with the extensions .json, .yaml, .yml, .js, .ts, .mjs, or .cjs
  • any of the above two inside a .config subdirectory
  • a .config.js, .config.ts, .config.mjs, or .config.cjs file

For example, if your module's name is "myapp", cosmiconfig will search up the directory tree for configuration in the following places:

  • a myapp property in package.json
  • a .myapprc file in JSON or YAML format
  • a .myapprc.json, .myapprc.yaml, .myapprc.yml, .myapprc.js, .myapprc.ts, .myapprc.mjs, or .myapprc.cjs file
  • a myapprc, myapprc.json, myapprc.yaml, myapprc.yml, myapprc.js, myapprc.ts, myapprc.mjs, or myapprc.cjs file inside a .config subdirectory
  • a myapp.config.js, myapp.config.ts, myapp.config.mjs, or myapp.config.cjs file

Optionally, you can tell it to search up the directory tree using search strategies, checking each of these places in each directory, until it finds some acceptable configuration (or hits the home directory).

Table of contents

Installation

npm install cosmiconfig

Tested in Node 14+.

Usage for tooling developers

If you are an end user (i.e. a user of a tool that uses cosmiconfig, like prettier or stylelint), you can skip down to the end user section.

Create a Cosmiconfig explorer, then either search for or directly load a configuration file.

const { cosmiconfig, cosmiconfigSync } = require('cosmiconfig');
// ...
const explorer = cosmiconfig(moduleName);

// Search for a configuration by walking up directories.
// See documentation for search, below.
explorer.search()
  .then((result) => {
    // result.config is the parsed configuration object.
    // result.filepath is the path to the config file that was found.
    // result.isEmpty is true if there was nothing to parse in the config file.
  })
  .catch((error) => {
    // Do something constructive.
  });

// Load a configuration directly when you know where it should be.
// The result object is the same as for search.
// See documentation for load, below.
explorer.load(pathToConfig).then(/* ... */);

// You can also search and load synchronously.
const explorerSync = cosmiconfigSync(moduleName);

const searchedFor = explorerSync.search();
const loaded = explorerSync.load(pathToConfig);

Result

The result object you get from search or load has the following properties:

  • config: The parsed configuration object. undefined if the file is empty.
  • filepath: The path to the configuration file that was found.
  • isEmpty: true if the configuration file is empty. This property will not be present if the configuration file is not empty.

Asynchronous API

cosmiconfig()

const { cosmiconfig } = require('cosmiconfig');
const explorer = cosmiconfig(moduleName, /* optional */ cosmiconfigOptions)

Creates a cosmiconfig instance ("explorer") configured according to the arguments, and initializes its caches.

moduleName

Type: string. Required.

Your module name. This is used to create the default searchPlaces and packageProp.

If your searchPlaces value will include files, as it does by default (e.g. ${moduleName}rc), your moduleName must consist of characters allowed in filenames. That means you should not copy scoped package names, such as @my-org/my-package, directly into moduleName.

cosmiconfigOptions are documented below. You may not need them, and should first read about the functions you'll use.

explorer.search()

explorer.search([searchFrom]).then(result => { /* ... */ })

Searches for a configuration file. Returns a Promise that resolves with a result or with null, if no configuration file is found.

You can do the same thing synchronously with explorerSync.search().

Let's say your module name is goldengrahams so you initialized with const explorer = cosmiconfig('goldengrahams');. Here's how your default search() will work:

  • Starting from process.cwd() (or some other directory defined by the searchFrom argument to search()), look for configuration objects in the following places:
    1. A goldengrahams property in a package.json file.
    2. A .goldengrahamsrc file with JSON or YAML syntax.
    3. A .goldengrahamsrc.json, .goldengrahamsrc.yaml, .goldengrahamsrc.yml, .goldengrahamsrc.js, .goldengrahamsrc.ts, .goldengrahamsrc.mjs, or .goldengrahamsrc.cjs file. (To learn more about how JS files are loaded, see "Loading JS modules".)
    4. A goldengrahamsrc, goldengrahamsrc.json, goldengrahamsrc.yaml, goldengrahamsrc.yml, goldengrahamsrc.js, goldengrahamsrc.ts, goldengrahamsrc.mjs, or goldengrahamsrc.cjs file in the .config subdirectory.
    5. A goldengrahams.config.js, goldengrahams.config.ts, goldengrahams.config.mjs, or goldengrahams.config.cjs file. (To learn more about how JS files are loaded, see "Loading JS modules".)
  • If none of those searches reveal a configuration object, continue depending on the current search strategy:
    • If it's none (which is the default if you don't specify a stopDir option), stop here and return/resolve with null.
    • If it's global (which is the default if you specify a stopDir option), move up one directory level and try again, recursing until arriving at the configured stopDir option, which defaults to the user's home directory.
      • After arriving at the stopDir, the global configuration directory (as defined by env-paths without prefix) is also checked, looking at the files config, config.json, config.yaml, config.yml, config.js, config.ts, config.cjs, and config.mjs in the directory ~/.config/goldengrahams/ (on Linux; see env-paths documentation for other OSs).
    • If it's project, check whether a package.json file is present in the current directory, and if not, move up one directory level and try again, recursing until there is one.
  • If at any point a parsable configuration is found, the search() Promise resolves with its result (or, with explorerSync.search(), the result is returned).
  • If no configuration object is found, the search() Promise resolves with null (or, with explorerSync.search(), null is returned).
  • If a configuration object is found but is malformed (causing a parsing error), the search() Promise rejects with that error (so you should .catch() it). (Or, with explorerSync.search(), the error is thrown.)

If you know exactly where your configuration file should be, you can use load(), instead.

The search process is highly customizable. Use the cosmiconfig options searchPlaces and loaders to precisely define where you want to look for configurations and how you want to load them.

searchFrom

Type: string. Default: process.cwd().

A filename. search() will start its search here.

If the value is a directory, that's where the search starts. If it's a file, the search starts in that file's directory.

explorer.load()

explorer.load(loadPath).then(result => { /* ... */ })

Loads a configuration file. Returns a Promise that resolves with a result or rejects with an error (if the file does not exist or cannot be loaded).

Use load if you already know where the configuration file is and you just need to load it.

explorer.load('load/this/file.json'); // Tries to load load/this/file.json.

If you load a package.json file, the result will be derived from whatever property is specified as your packageProp. package.yaml will work as well if you specify these file names in your searchPlaces.

You can do the same thing synchronously with explorerSync.load().

explorer.clearLoadCache()

Clears the cache used in load().

explorer.clearSearchCache()

Clears the cache used in search().

explorer.clearCaches()

Performs both clearLoadCache() and clearSearchCache().

Synchronous API

cosmiconfigSync()

const { cosmiconfigSync } = require('cosmiconfig');
const explorerSync = cosmiconfigSync(moduleName, /* optional */ cosmiconfigOptions)

Creates a synchronous cosmiconfig instance ("explorerSync") configured according to the arguments, and initializes its caches.

See cosmiconfig().

explorerSync.search()

const result = explorerSync.search([searchFrom]);

Synchronous version of explorer.search().

Returns a result or null.

explorerSync.load()

const result = explorerSync.load(loadPath);

Synchronous version of explorer.load().

Returns a result.

explorerSync.clearLoadCache()

Clears the cache used in load().

explorerSync.clearSearchCache()

Clears the cache used in search().

explorerSync.clearCaches()

Performs both clearLoadCache() and clearSearchCache().

cosmiconfigOptions

Type: Object.

Possible options are documented below.

searchStrategy

Type: string Default: global if stopDir is specified, none otherwise.

The strategy that should be used to determine which directories to check for configuration files.

  • none: Only checks in the current working directory.
  • project: Starts in the current working directory, traversing upwards until a package.{json,yaml} file is found.
  • global: Starts in the current working directory, traversing upwards until the configured stopDir (or the current user's home directory if none is given). Then, if no configuration is found, also look in the operating system's default configuration directory (according to env-paths without prefix), where a different set of file names is checked:
[
  `config`,
  `config.json`,
  `config.yaml`,
  `config.yml`,
  `config.js`,
  `config.ts`,
  `config.cjs`,
  `config.mjs`
]

searchPlaces

Type: Array<string>. Default: See below.

An array of places that search() will check in each directory as it moves up the directory tree. Each place is relative to the directory being searched, and the places are checked in the specified order.

Default searchPlaces:

For the asynchronous API, these are the default searchPlaces:

[
  'package.json',
  `.${moduleName}rc`,
  `.${moduleName}rc.json`,
  `.${moduleName}rc.yaml`,
  `.${moduleName}rc.yml`,
  `.${moduleName}rc.js`,
  `.${moduleName}rc.ts`,
  `.${moduleName}rc.mjs`,
  `.${moduleName}rc.cjs`,
  `.config/${moduleName}rc`,
  `.config/${moduleName}rc.json`,
  `.config/${moduleName}rc.yaml`,
  `.config/${moduleName}rc.yml`,
  `.config/${moduleName}rc.js`,
  `.config/${moduleName}rc.ts`,
  `.config/${moduleName}rc.mjs`,
  `.config/${moduleName}rc.cjs`,
  `${moduleName}.config.js`,
  `${moduleName}.config.ts`,
  `${moduleName}.config.mjs`,
  `${moduleName}.config.cjs`,
];

For the synchronous API, the only difference is that .mjs files are not included. See "Loading JS modules" for more information.

Create your own array to search more, fewer, or altogether different places.

Every item in searchPlaces needs to have a loader in loaders that corresponds to its extension. (Common extensions are covered by default loaders.) Read more about loaders below.

package.json is a special value: When it is included in searchPlaces, Cosmiconfig will always parse it as JSON and load a property within it, not the whole file. That property is defined with the packageProp option, and defaults to your module name.

package.yaml (used by pnpm) works the same way.

Examples, with a module named porgy:

// Disallow extensions on rc files:
['package.json', '.porgyrc', 'porgy.config.js']
// Limit the options dramatically:
['package.json', '.porgyrc']
// Maybe you want to look for a wide variety of JS flavors:
[
  'porgy.config.js',
  'porgy.config.mjs',
  'porgy.config.ts',
  'porgy.config.coffee'
]
// ^^ You will need to designate a custom loader to tell
// Cosmiconfig how to handle `.coffee` files.
// Look within a .config/ subdirectory of every searched directory:
[
  'package.json',
  '.porgyrc',
  '.config/.porgyrc',
  '.porgyrc.json',
  '.config/.porgyrc.json'
]

loaders

Type: Object. Default: See below.

An object that maps extensions to the loader functions responsible for loading and parsing files with those extensions.

Cosmiconfig exposes its default loaders on the named export defaultLoaders and defaultLoadersSync.

Default loaders:

const { defaultLoaders, defaultLoadersSync } = require('cosmiconfig');

console.log(Object.entries(defaultLoaders));
// [
//   [ '.mjs', [Function: loadJs] ],
//   [ '.cjs', [Function: loadJs] ],
//   [ '.js', [Function: loadJs] ],
//   [ '.ts', [Function: loadTs] ],
//   [ '.json', [Function: loadJson] ],
//   [ '.yaml', [Function: loadYaml] ],
//   [ '.yml', [Function: loadYaml] ],
//   [ 'noExt', [Function: loadYaml] ]
// ]

console.log(Object.entries(defaultLoadersSync));
// [
//   [ '.cjs', [Function: loadJsSync] ],
//   [ '.js', [Function: loadJsSync] ],
//   [ '.ts', [Function: loadTsSync] ],
//   [ '.json', [Function: loadJson] ],
//   [ '.yaml', [Function: loadYaml] ],
//   [ '.yml', [Function: loadYaml] ],
//   [ 'noExt', [Function: loadYaml] ]
// ]

(YAML is a superset of JSON; which means YAML parsers can parse JSON; which is how extensionless files can be either YAML or JSON with only one parser.)

If you provide a loaders object, your object will be merged with the defaults. So you can override one or two without having to override them all.

Keys in loaders are extensions (starting with a period), or noExt to specify the loader for files without extensions, like .myapprc.

Values in loaders are a loader function (described below) whose values are loader functions.

The most common use case for custom loaders value is to load extensionless rc files as strict JSON, instead of JSON or YAML (the default). To accomplish that, provide the following loaders value:

{
  noExt: defaultLoaders['.json'];
}

If you want to load files that are not handled by the loader functions Cosmiconfig exposes, you can write a custom loader function or use one from NPM if it exists.

Use cases for custom loader function:

  • Allow configuration syntaxes that aren't handled by Cosmiconfig's defaults, like JSON5, INI, or XML.
  • Parse JS files with Babel before deriving the configuration.

Custom loader functions have the following signature:

// Sync
type SyncLoader = (filepath: string, content: string) => Object | null

// Async
type AsyncLoader = (filepath: string, content: string) => Object | null | Promise<Object | null>

Cosmiconfig reads the file when it checks whether the file exists, so it will provide you with both the file's path and its content. Do whatever you need to, and return either a configuration object or null (or, for async-only loaders, a Promise that resolves with one of those). null indicates that no real configuration was found and the search should continue.

A few things to note:

  • If you use a custom loader, be aware of whether it's sync or async: you cannot use async customer loaders with the sync API (cosmiconfigSync()).
  • Special JS syntax can also be handled by using a require hook, because defaultLoaders['.js'] just uses require. Whether you use custom loaders or a require hook is up to you.

Examples:

// Allow JSON5 syntax:
cosmiconfig('foo', {
  loaders: {
    '.json': json5Loader
  }
});

// Allow a special configuration syntax of your own creation:
cosmiconfig('foo', {
  loaders: {
    '.special': specialLoader
  }
});

// Allow many flavors of JS, using custom loaders:
cosmiconfig('foo', {
  loaders: {
    '.coffee': coffeeScriptLoader
  }
});

// Allow many flavors of JS but rely on require hooks:
cosmiconfig('foo', {
  loaders: {
    '.coffee': defaultLoaders['.js']
  }
});

packageProp

Type: string | Array<string>. Default: `${moduleName}`.

Name of the property in package.json (or package.yaml) to look for.

Use a period-delimited string or an array of strings to describe a path to nested properties.

For example, the value 'configs.myPackage' or ['configs', 'myPackage'] will get you the "myPackage" value in a package.json like this:

{
  "configs": {
    "myPackage": {"option":  "value"}
  }
}

If nested property names within the path include periods, you need to use an array of strings. For example, the value ['configs', 'foo.bar', 'baz'] will get you the "baz" value in a package.json like this:

{
  "configs": {
    "foo.bar": {
      "baz": {"option":  "value"}
    }
  }
}

If a string includes period but corresponds to a top-level property name, it will not be interpreted as a period-delimited path. For example, the value 'one.two' will get you the "three" value in a package.json like this:

{
  "one.two": "three",
  "one": {
    "two": "four"
  }
}

stopDir

Type: string. Default: Absolute path to your home directory.

Directory where the search will stop.

cache

Type: boolean. Default: true.

If false, no caches will be used. Read more about "Caching" below.

transform

Type: (Result) => Promise<Result> | Result.

A function that transforms the parsed configuration. Receives the result.

If using search() or load() (which are async), the transform function can return the transformed result or return a Promise that resolves with the transformed result. If using cosmiconfigSync, search() or load(), the function must be synchronous and return the transformed result.

The reason you might use this option — instead of simply applying your transform function some other way — is that the transformed result will be cached. If your transformation involves additional filesystem I/O or other potentially slow processing, you can use this option to avoid repeating those steps every time a given configuration is searched or loaded.

ignoreEmptySearchPlaces

Type: boolean. Default: true.

By default, if search() encounters an empty file (containing nothing but whitespace) in one of the searchPlaces, it will ignore the empty file and move on. If you'd like to load empty configuration files, instead, set this option to false.

Why might you want to load empty configuration files? If you want to throw an error, or if an empty configuration file means something to your program.

Loading JS modules

Your end users can provide JS configuration files as ECMAScript modules (ESM) under the following conditions:

With cosmiconfig's asynchronous API, the default searchPlaces] include .js, .ts, .mjs, and .cjs files. Cosmiconfig loads all these file types with the [dynamic import function.

With the synchronous API, JS configuration files are always treated as CommonJS, and .mjs files are ignored, because there is no synchronous API for the dynamic import function.

Caching

As of v2, cosmiconfig uses caching to reduce the need for repetitious reading of the filesystem or expensive transforms. Every new cosmiconfig instance (created with cosmiconfig()) has its own caches.

To avoid or work around caching, you can do the following:

Differences from rc

rc serves its focused purpose well. cosmiconfig differs in a few key ways — making it more useful for some projects, less useful for others:

  • Looks for configuration in some different places: in a package.json property, an rc file, a .config.js file, and rc files with extensions.
  • Built-in support for JSON, YAML, and CommonJS formats.
  • Stops at the first configuration found, instead of finding all that can be found up the directory tree and merging them automatically.
  • Options.
  • Asynchronous by default (though can be run synchronously).

Usage for end users

When configuring a tool, you can use multiple file formats and put these in multiple places.

Usually, a tool would mention this in its own README file, but by default, these are the following places, where {NAME} represents the name of the tool:

package.json
.{NAME}rc
.{NAME}rc.json
.{NAME}rc.yaml
.{NAME}rc.yml
.{NAME}rc.js
.{NAME}rc.ts
.{NAME}rc.cjs
.config/{NAME}rc
.config/{NAME}rc.json
.config/{NAME}rc.yaml
.config/{NAME}rc.yml
.config/{NAME}rc.js
.config/{NAME}rc.ts
.config/{NAME}rc.mjs
.config/{NAME}rc.cjs
{NAME}.config.js
{NAME}.config.ts
{NAME}.config.mjs
{NAME}.config.cjs

The contents of these files are defined by the tool. For example, you can configure prettier to enforce semicolons at the end of the line using a file named .config/prettierrc.yml:

semi: true

Additionally, you have the option to put a property named after the tool in your package.json file, with the contents of that property being the same as the file contents. To use the same example as above:

{
  "name": "your-project",
  "dependencies": {},
  "prettier": {
    "semi": true
  }
}

This has the advantage that you can put the configuration of all tools (at least the ones that use cosmiconfig) in one file.

You can also add a cosmiconfig key within your package.json file or create one of the following files to configure cosmiconfig itself:

.config/config.json
.config/config.yaml
.config/config.yml
.config/config.js
.config/config.ts
.config/config.cjs

The following properties are currently actively supported in these places:

cosmiconfig:
  # adds places where configuration files are being searched
  searchPlaces:
    - .config/{name}.yml
  # to enforce a custom naming convention and format, don't merge the above with the tool-defined search places
  # (`true` is the default setting)
  mergeSearchPlaces: false

Note: technically, you can overwrite all options described in cosmiconfigOptions here, but everything not listed above should be used at your own risk, as it has not been tested explicitly. The only exceptions to this are the loaders property, which is explicitly not supported at this time, and the searchStrategy property, which is intentionally disallowed.

You can also add more root properties outside the cosmiconfig property to configure your tools, entirely eliminating the need to look for additional configuration files:

cosmiconfig:
  searchPlaces: []

prettier:
  semi: true

Imports

Wherever you put your configuration (the package.json file, a root config file or a package-specific config file), you can use the special $import key to import another file as a base.

For example, you can import from an npm package (in this example, @foocorp/config).

.prettierrc.base.yml in said npm package could define some company-wide defaults:

printWidth: 120
semi: true
tabWidth: 2

And then, the .prettierrc.yml file in the project itself would just reference that file, optionally overriding the defaults with project-specific settings:

$import: node_modules/@foocorp/config/.prettierrc.base.yml
# we want more space!
printWidth: 200

It is possible to import multiple base files by specifying an array of paths, which will be processed in declaration order; that means that the last entry will win if there are conflicting properties.

It is also possible to import file formats other than the importing format as long as they are supported by the loaders specified by the developer of the tool you're configuring.

$import: [first.yml, second.json, third.config.js]

Contributing & Development

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

And please do participate!

changelog

Changelog

9.0.0

  • Added searchStrategy option:
    • The none value means that cosmiconfig does not traverse any directories upwards.
      • Breaking change: This is the default value if you don't pass a stopDir option, which means that cosmiconfig no longer traverses directories by default, and instead just looks in the current working directory.
        • If you want to achieve maximum backwards compatibility without adding an explicit stopDir, add the searchStrategy: 'global' option.
    • The project value means that cosmiconfig traverses upwards until it finds a package.json (or .yaml) file.
    • The global value means that cosmiconfig traverses upwards until the passed stopDir, or your home directory if no stopDir is given.
  • Breaking change: Meta config files (i.e. config.js and similar) are not looked for in the current working directory anymore. Instead, it looks in the .config subfolder.
  • Breaking change: When defining searchPlaces in a meta config file, the tool-defined searchPlaces are merged into this. Users may specify mergeSearchPlaces: false to disable this.
  • Added support for a special $import key which will import another configuration file
    • The imported file will act as a base file - all properties from that file will be applied to the configuration, but can be overridden by the importing file
    • For more information, read the import section of the README
  • Added searching in OS conventional folders (XDG compatible on Linux, %APPDATA% on Windows, Library/Preferences on macOS) for searchStrategy: 'global'
  • Fixed crash when trying to load a file that is not readable due to file system permissions
  • Fixed wrong ERR_REQUIRE_ESM error being thrown when there is an issue loading an ESM file

8.3.6

  • Ignore search place if accessing it causes ENOTDIR (i.e. if access of a subpath of a file is attempted)

8.3.5

  • Fixed regression in transform option

8.3.4

  • Fixed crash in older node versions

8.3.3

  • Added back node 14 compat to package.json

8.3.2

  • Fixed some issues with TypeScript config loading

8.3.1

  • Fixed crash when stopDir was given but undefined

8.3.0

  • Add support for TypeScript configuration files

8.2.0

  • Add support for ECMAScript modules (ESM) to the asynchronous API. End users running Node versions that support ESM can provide .mjs files, or .js files whose nearest parent package.json file contains "type": "module".
    • ${moduleName}rc.mjs and ${moduleName}.config.mjs are included in the default searchPlaces of the asynchronous API.
    • The synchronous API does not support ECMAScript modules, so does not look for .mjs files.
    • To learn more, read "Loading JS modules".

8.1.3

  • Fixed: existence of meta config breaking default loaders

8.1.2

  • Fixed: generation of TypeScript types going to the wrong output path

8.1.1

  • Fixed: meta config overriding original options completely (now merges correctly)

8.1.0

  • Added: always look at .config.{yml,yaml,json,js,cjs} file to configure cosmiconfig itself, and look for tool configuration in it using packageProp (similar to package.json)

8.0.0

No major breaking changes! We dropped support for Node 10 and 12 -- which you're probably not using. And we swapped out the YAML parser -- which you probably won't notice.

  • Breaking change: Drop support for Node 10 and 12.

  • Breaking change: Use npm package js-yaml to parse YAML instead of npm package yaml.

  • Added: Loader errors now include the path of the file that was tried to be loaded.

7.1.0

  • Added: Additional default searchPlaces within a .config subdirectory (without leading dot in the file name)

7.0.1

  • Fixed: If there was a directory that had the same name as a search place (e.g. "package.json"), we would try to read it as a file, which would cause an exception.

7.0.0

  • Breaking change: Add ${moduleName}rc.cjs and ${moduleName}.config.cjs to the default searchPlaces, to support users of "type": "module" in recent versions of Node.
  • Breaking change: Drop support for Node 8. Now requires Node 10+.

6.0.0

  • Breaking change: The package now has named exports. See examples below.

  • Breaking change: Separate async and sync APIs, accessible from different named exports. If you used explorer.searchSync() or explorer.loadSync(), you'll now create a sync explorer with cosmiconfigSync(), then use explorerSync.search() and explorerSync.load().

    // OLD: cosmiconfig v5
    import cosmiconfig from 'cosmiconfig';
    
    const explorer = cosmiconfig('example');
    const searchAsyncResult = await explorer.search();
    const loadAsyncResult = await explorer.load('./file/to/load');
    const searchSyncResult = explorer.searchSync();
    const loadSyncResult = explorer.loadSync('./file/to/load');
    
    // NEW: cosmiconfig v6
    import { cosmiconfig, cosmiconfigSync } from 'cosmiconfig';
    
    const explorer = cosmiconfig('example');
    const searchAsyncResult = await explorer.search();
    const loadAsyncResult = await explorer.load('./file/to/load');
    
    const explorerSync = cosmiconfigSync('example');
    const searchSyncResult = explorerSync.search();
    const loadSyncResult = explorerSync.load('./file/to/load');
  • Breaking change: Remove support for Node 4 and 6. Requires Node 8+.

  • Breaking change: Use npm package yaml to parse YAML instead of npm package js-yaml.

  • Breaking change: Remove cosmiconfig.loaders and add named export defaultLoaders that exports the default loaders used for each extension.

    import { defaultLoaders } from 'cosmiconfig';
    
    console.log(Object.entries(defaultLoaders));
    // [
    //   [ '.js', [Function: loadJs] ],
    //   [ '.json', [Function: loadJson] ],
    //   [ '.yaml', [Function: loadYaml] ],
    //   [ '.yml', [Function: loadYaml] ],
    //   [ 'noExt', [Function: loadYaml] ]
    // ]
  • Migrate from Flowtype to Typescript.

  • Lazy load all default loaders.

5.2.1

  • Chore: Upgrade js-yaml to avoid npm audit warning.

5.2.0

  • Added: packageProp values can be arrays of strings, to allow for property names that include periods. (This was possible before, but not documented or deliberately supported.)
  • Chore: Replaced the lodash.get dependency with a locally defined function.
  • Chore: Upgrade js-yaml to avoid npm audit warning.

5.1.0

  • Added: packageProp values can include periods to describe paths to nested objects within package.json.

5.0.7

  • Fixed: JS loader bypasses Node's require cache, fixing a bug where updates to .js config files would not load even when Cosmiconfig was told not to cache.

5.0.6

  • Fixed: Better error message if the end user tries an extension Cosmiconfig is not configured to understand.

5.0.5

  • Fixed: load and loadSync work with paths relative to process.cwd().

5.0.4

  • Fixed: rc files with .js extensions included in default searchPlaces.

5.0.3

  • Docs: Minor corrections to documentation. Released to update package documentation on npm.

5.0.2

  • Fixed: Allow searchSync and loadSync to load JS configuration files whose export is a Promise.

5.0.1

The API has been completely revamped to increase clarity and enable a very wide range of new usage. Please read the readme for all the details.

While the defaults remain just as useful as before — and you can still pass no options at all — now you can also do all kinds of wild and crazy things.

  • The loaders option allows you specify custom functions to derive config objects from files. Your loader functions could parse ES2015 modules or TypeScript, JSON5, even INI or XML. Whatever suits you.
  • The searchPlaces option allows you to specify exactly where cosmiconfig looks within each directory it searches.
  • The combination of loaders and searchPlaces means that you should be able to load pretty much any kind of configuration file you want, from wherever you want it to look.

Additionally, the overloaded load() function has been split up into several clear and focused functions:

  • search() now searches up the directory tree, and load() loads a configuration file that you don't need to search for.
  • The sync option has been replaced with separate synchronous functions: searchSync() and loadSync().
  • clearFileCache() and clearDirectoryCache() have been renamed to clearLoadCache() and clearSearchPath() respectively.

More details:

  • The default JS loader uses require, instead of require-from-string. So you could use require hooks to control the loading of JS files (e.g. pass them through esm or Babel). In most cases it is probably preferable to use a custom loader.
  • The options rc, js, and rcExtensions have all been removed. You can accomplish the same and more with searchPlaces.
  • The default searchPlaces include rc files with extensions, e.g. .thingrc.json, .thingrc.yaml, .thingrc.yml. This is the equivalent of switching the default value of the old rcExtensions option to true.
  • The option rcStrictJson has been removed. To get the same effect, you can specify noExt: cosmiconfig.loadJson in your loaders object.
  • packageProp no longer accepts false. If you don't want to look in package.json, write a searchPlaces array that does not include it.
  • By default, empty files are ignored by search(). The new option ignoreEmptySearchPlaces allows you to load them, instead, in case you want to do something with empty files.
  • The option configPath has been removed. Just pass your filepaths directory to load().
  • Removed the format option. Formats are now all handled via the file extensions specified in loaders.

(If you're wondering with happened to 5.0.0 ... it was a silly publishing mistake.)

4.0.0

  • Licensing improvement: updated parse-json from 3.0.0 to 4.0.0(see sindresorhus/parse-json#12).
  • Changed: error message format for JSON parse errors(see #101). If you were relying on the format of JSON-parsing error messages, this will be a breaking change for you.
  • Changed: set default for searchPath as process.cwd() in explorer.load.

3.1.0

  • Added: infer format based on filePath

3.0.1

  • Fixed: memory leak due to bug in require-from-string.
  • Added: for JSON files, append position to end of error message.

3.0.0

  • Removed: support for loading config path using the --config flag. cosmiconfig will not parse command line arguments. Your application can parse command line arguments and pass them to cosmiconfig.
  • Removed: argv config option.
  • Removed: support for Node versions < 4.
  • Added: sync option.
  • Fixed: Throw a clear error on getting empty config file.
  • Fixed: when a options.configPath is package.json, return the package prop, not the entire JSON file.

2.2.2

  • Fixed: options.configPath and --config flag are respected.

2.2.0, 2.2.1

  • 2.2.0 included a number of improvements but somehow broke stylelint. The changes were reverted in 2.2.1, to be restored later.

2.1.3

  • Licensing improvement: switched from json-parse-helpfulerror to parse-json.

2.1.2

  • Fixed: bug where an ENOENT error would be thrown is searchPath referenced a non-existent file.
  • Fixed: JSON parsing errors in Node v7.

2.1.1

  • Fixed: swapped graceful-fs for regular fs, fixing a garbage collection problem.

2.1.0

  • Added: Node 0.12 support.

2.0.2

  • Fixed: Node version specified in package.json.

2.0.1

  • Fixed: no more infinite loop in Windows.

2.0.0

  • Changed: module now creates cosmiconfig instances with load methods (see README).
  • Added: caching (enabled by the change above).
  • Removed: support for Node versions <4.

1.1.0

  • Add rcExtensions option.

1.0.2

  • Fix handling of require()'s within JS module configs.

1.0.1

  • Switch Promise implementation to pinkie-promise.

1.0.0

  • Initial release.