Cosmiconfig provides extensive configuration options to customize search behavior, file loading, and result transformation.
Options shared between async and sync APIs:
interface CommonOptions {
/** Package.json property name or path array to search for configuration */
packageProp?: string | Array<string>;
/** Array of places to search for configuration files */
searchPlaces?: Array<string>;
/** Skip empty configuration files during search */
ignoreEmptySearchPlaces?: boolean;
/** Directory to stop searching (defaults to os.homedir()) */
stopDir?: string;
/** Enable or disable caching of results */
cache?: boolean;
}Options for async API extending CommonOptions:
interface Options extends CommonOptions {
/** Custom async loaders for different file extensions */
loaders?: Loaders;
/** Transform function to modify results before returning */
transform?: Transform;
}Options for sync API extending CommonOptions:
interface OptionsSync extends CommonOptions {
/** Custom sync loaders for different file extensions */
loaders?: LoadersSync;
/** Transform function to modify results before returning (sync) */
transform?: TransformSync;
}Specifies which property in package.json to use for configuration.
packageProp?: string | Array<string>;Usage Examples:
import { cosmiconfig } from "cosmiconfig";
// Look for config in package.json under "babel" property
const explorer = cosmiconfig("babel", {
packageProp: "babel"
});
// Look for nested property using array path
const nestedExplorer = cosmiconfig("myapp", {
packageProp: ["config", "myapp"]
});
// This would find configuration in:
// {
// "config": {
// "myapp": {
// "setting": "value"
// }
// }
// }Array of places to search for configuration files.
searchPlaces?: Array<string>;Default Search Places:
For a module named "myapp", the default search places are:
package.json (using packageProp).myapprc.myapprc.json.myapprc.yaml.myapprc.yml.myapprc.js.myapprc.ts.myapprc.mjs.myapprc.cjsmyapp.config.jsmyapp.config.tsmyapp.config.mjsmyapp.config.cjsUsage Examples:
// Custom search places
const explorer = cosmiconfig("myapp", {
searchPlaces: [
"package.json",
".myapprc",
".myapp.json",
"myapp.config.js",
".config/myapp.json"
]
});
// Search only in specific config files
const configOnlyExplorer = cosmiconfig("tool", {
searchPlaces: [
"tool.config.js",
"tool.config.json"
]
});Skip empty configuration files during search.
ignoreEmptySearchPlaces?: boolean;Usage Examples:
// Skip empty config files (default: false)
const explorer = cosmiconfig("myapp", {
ignoreEmptySearchPlaces: true
});
// This will skip files that are empty or contain only whitespace
// and continue searching for non-empty configurationDirectory where searching should stop.
stopDir?: string;Usage Examples:
import path from "path";
// Stop searching at a specific directory
const explorer = cosmiconfig("myapp", {
stopDir: path.resolve("/Users/username/projects")
});
// Stop at project root (common pattern)
const projectExplorer = cosmiconfig("myapp", {
stopDir: path.resolve(process.cwd(), "..")
});Enable or disable caching of results.
cache?: boolean;Usage Examples:
// Disable caching (default: true)
const noCacheExplorer = cosmiconfig("myapp", {
cache: false
});
// Useful during development or testing when config files change frequently
const devExplorer = cosmiconfig("myapp", {
cache: process.env.NODE_ENV !== "development"
});Transform functions allow you to modify configuration results before they are returned.
Async transform function:
type Transform = (CosmiconfigResult: CosmiconfigResult) => Promise<CosmiconfigResult> | CosmiconfigResult;Sync transform function:
type TransformSync = (CosmiconfigResult: CosmiconfigResult) => CosmiconfigResult;Transform Examples:
import { cosmiconfig } from "cosmiconfig";
// Add metadata to configuration
const addMetadataTransform = (result) => {
if (!result) return result;
return {
...result,
config: {
...result.config,
_metadata: {
loadedFrom: result.filepath,
loadedAt: new Date().toISOString()
}
}
};
};
// Validate configuration structure
const validateTransform = (result) => {
if (!result) return result;
if (!result.config.name) {
throw new Error(`Configuration must have a "name" property in ${result.filepath}`);
}
return result;
};
// Apply environment variable substitution
const envTransform = (result) => {
if (!result) return result;
const config = JSON.parse(
JSON.stringify(result.config).replace(
/\$\{(\w+)\}/g,
(_, envVar) => process.env[envVar] || ""
)
);
return { ...result, config };
};
// Use transforms
const explorer = cosmiconfig("myapp", {
transform: addMetadataTransform
});
// Chain multiple transforms
const chainedTransform = async (result) => {
result = await validateTransform(result);
result = await envTransform(result);
result = await addMetadataTransform(result);
return result;
};
const complexExplorer = cosmiconfig("myapp", {
transform: chainedTransform
});import { cosmiconfig } from "cosmiconfig";
import path from "path";
// Comprehensive configuration example
const explorer = cosmiconfig("mycomplex", {
// Search configuration
searchPlaces: [
"package.json",
".mycomplexrc",
".mycomplexrc.json",
".mycomplexrc.yaml",
".mycomplexrc.js",
"mycomplex.config.js",
".config/mycomplex.json"
],
// Package.json property
packageProp: ["tools", "mycomplex"],
// Search behavior
ignoreEmptySearchPlaces: true,
stopDir: path.resolve(process.cwd(), "../.."),
cache: process.env.NODE_ENV !== "test",
// Custom loaders
loaders: {
".json": (filepath, content) => JSON.parse(content),
".yaml": (filepath, content) => require("js-yaml").load(content),
".yml": (filepath, content) => require("js-yaml").load(content),
".js": async (filepath) => {
const module = await import(filepath);
return module.default || module;
},
noExt: (filepath, content) => require("js-yaml").load(content)
},
// Transform function
transform: async (result) => {
if (!result) return result;
// Validate required properties
if (!result.config.name) {
throw new Error(`Configuration must have a "name" property`);
}
// Add computed properties
return {
...result,
config: {
...result.config,
_computed: {
configDir: path.dirname(result.filepath),
isDefaultConfig: result.filepath.includes("package.json")
}
}
};
}
});Configuration options can affect error handling behavior:
// Graceful handling of missing configurations
const explorer = cosmiconfig("optional-tool", {
searchPlaces: ["optional-tool.config.js"],
transform: (result) => {
// Provide defaults if no configuration found
if (!result) {
return {
config: { enabled: false, defaults: true },
filepath: "defaults",
isEmpty: false
};
}
return result;
}
});
// Strict validation
const strictExplorer = cosmiconfig("strict-tool", {
transform: (result) => {
if (!result) {
throw new Error("Configuration is required for strict-tool");
}
const required = ["name", "version", "settings"];
const missing = required.filter(key => !(key in result.config));
if (missing.length > 0) {
throw new Error(
`Missing required configuration properties: ${missing.join(", ")} in ${result.filepath}`
);
}
return result;
}
});