Load ESM configuration files
master.mjs files or .js files in projects where package.json contains "type": "module"), you must use the asynchronous lilconfig().search() API. The synchronous API does not support ESM loading.repository·master·Indexed 41 days ago
https://github.com/antonk52/lilconfigA zero-dependency configuration loader and cosmiconfig alternative. It provides asynchronous (lilconfig) and synchronous (lilconfigSync) APIs to search for and load configuration files from various formats and locations, returning a LilconfigResult containing the parsed config and its filepath. Supports custom loaders for formats like YAML, ESM loading via the async API, and configurable search behaviors including stopDir and packageProp.
.mjs files or .js files in projects where package.json contains "type": "module"), you must use the asynchronous lilconfig().search() API. The synchronous API does not support ESM loading.Install the lilconfig package using npm to use it as a zero-dependency configuration loader.
npm install lilconfigUnlike cosmiconfig, lilconfig does not support YAML files out of the box. To enable YAML support, you must provide a custom loader in the loaders option. You can target specific extensions like .yaml or .yml, or use the noExt key to provide a loader for files with no extension.
import {lilconfig} from 'lilconfig';
import yaml from 'yaml';
function loadYaml(filepath, content) {
return yaml.parse(content);
}
const options = {
loaders: {
'.yaml': loadYaml,
'.yml': loadYaml,
// loader for files with no extension
noExt: loadYaml
}
};
lilconfig('myapp', options)
.search()
.then(result => {
result // {config, filepath}
});The transform function receives a LilconfigResult object. This object represents the found configuration and its metadata.
Structure of LilconfigResult:
config: The parsed configuration object (or null if not found).filepath: The absolute path to the configuration file used (empty string if not found).isEmpty: (Optional) A boolean set to true if the file was found but was empty, and ignoreEmptySearchPlaces was active.When a configuration is successfully found and loaded, the result is returned as a LilconfigResult object. If no configuration is found, the result is null.
Fields:
filepath: The absolute path to the configuration file found.config: The parsed configuration object (type any).isEmpty (optional): A boolean indicating if the configuration file was empty.// Example of a successful LilconfigResult
{
filepath: '/path/to/project/.myconfig.json',
config: { key: 'value' },
isEmpty: false
}
// If not found:
nullLilconfig provides both an asynchronous lilconfig function and a synchronous lilconfigSync function. Both accept a configuration name (the prefix used to search for config files) and an optional options object.
stopDir: A directory where the search should stop.searchPlaces: An array of file patterns to search for (e.g., ['package.json', 'myapp.conf.js']).ignoreEmptySearchPlaces: Boolean indicating whether to ignore empty search locations.LilconfigResultBoth methods return a result object containing:
config: The parsed configuration object.filepath: The absolute path to the configuration file found.import {lilconfig, lilconfigSync} from 'lilconfig';
const options = {
stopDir: '/Users/you/some/dir',
searchPlaces: ['package.json', 'myapp.conf.js'],
ignoreEmptySearchPlaces: false
};
// Asynchronous usage
// Returns Promise<LilconfigResult>
ilconfig('myapp', options).search();
// Synchronous usage
// Returns LilconfigResult
ilconfigSync('myapp', options).load(pathToConfig);When using lilconfig in an ESM-based project, you can explicitly enable ESM mode by setting the esm key to true in your configuration file. This is used in projects where the configuration is exported via export default.
export default {
esm: true,
};When using a configuration file named cached.config.js, you can define custom properties such as iWasCached to verify if the configuration is being loaded from a cached state or a specific file. This is a user-defined configuration object exported via module.exports.
module.exports = {
iWasCached: true,
};You can pass an Options (async) or OptionsSync (sync) object to the lilconfig functions to customize the search and loading behavior.
Key options include:
cache: Boolean to enable/disable caching.stopDir: A directory where the search should stop.searchPlaces: An array of strings representing specific locations to search.ignoreEmptySearchPlaces: Boolean to decide if empty search locations should be ignored.packageProp: A string or array of strings specifying the property name in package.json where the config resides.loaders: A mapping of file extensions to Loader functions.transform: A function to modify the LilconfigResult after it has been loaded.import { lilconfig } from 'lilconfig';
const searcher = lilconfig('my-config', {
cache: true,
stopDir: '/home/user',
searchPlaces: ['./config', '~/.config'],
packageProp: 'lilconfig',
loaders: {
'.custom': (filepath, content) => {
// Custom loader logic
return JSON.parse(content);
}
},
transform: (result) => {
// Modify the loaded config
return { ...result, config: { ...result.config, loadedAt: Date.now() } };
}
});When initializing lilconfig or lilconfigSync, you can pass an options object to customize the behavior:
name: (String) The name of your configuration (e.g., 'babel'). This determines the filenames searched (e.g., .babelrc.json).searchPlaces: (Array<string>) Custom list of file patterns to search for.stopDir: (String) The directory where searching should stop (defaults to os.homedir()).ignoreEmptySearchPlaces: (Boolean) If true, empty files are skipped during search (defaults to true).cache: (Boolean) Enables internal caching for search and load results (defaults to true).transform: (Function) A function applied to the result before it is returned. Receives the LilconfigResult object.packageProp: (String | Array<string>) The property in package.json where the config resides. Supports dot notation or an array of keys (e.g., ['my-app-config'] or 'myApp.config').loaders: (Object) A mapping of file extensions (or noExt for files without extensions) to loader functions.In an ESM-based project, you can provide a CommonJS configuration file named cjs.config.mjs. This specific file demonstrates a configuration where the property iShouldBeESMbutIAmCJS is set to true.
module.exports = {
iShouldBeESMbutIAmCJS: true,
};When using an ESM project configuration, set the esm key to true within your configuration file to explicitly enable ESM mode.
export default {
esm: true,
};