Complete guide to setting up and configuring Conf instances with all available options for storage location, validation, encryption, and behavior customization.
Creates a new Conf instance with the specified configuration options.
/**
* Creates a new configuration store
* @param options - Configuration options for the store
*/
constructor(options?: Partial<Options<T>>): Conf<T>;Usage Examples:
import Conf from "conf";
// Basic configuration with project name
const config = new Conf({ projectName: "my-app" });
// With TypeScript typing
interface AppConfig {
username: string;
theme: "light" | "dark";
notifications: boolean;
}
const typedConfig = new Conf<AppConfig>({
projectName: "my-app",
defaults: {
theme: "light",
notifications: true
}
});Options that define the basic behavior and storage of the configuration.
interface CoreOptions<T> {
/**
* Required unless `cwd` is specified.
* Used to determine config file location following OS conventions.
*/
projectName?: string;
/**
* Name of the config file (without extension).
* Useful for multiple config files per project.
* @default "config"
*/
configName?: string;
/**
* Default values for config items.
* Overrides `default` values in schema.
*/
defaults?: Readonly<T>;
/**
* Custom config directory path.
* Overrides projectName-based location.
* You most likely don't need this.
*/
cwd?: string;
/**
* Config file extension.
* @default "json"
*/
fileExtension?: string;
/**
* Project directory suffix to avoid conflicts.
* @default "nodejs"
*/
projectSuffix?: string;
}Usage Examples:
// Multiple config files for different environments
const devConfig = new Conf({
projectName: "my-app",
configName: "development",
defaults: { debug: true }
});
const prodConfig = new Conf({
projectName: "my-app",
configName: "production",
defaults: { debug: false }
});
// Custom file extension for shareable configs
const userPrefs = new Conf({
projectName: "my-app",
configName: "preferences",
fileExtension: "prefs"
});Options for JSON Schema validation to ensure data integrity.
interface ValidationOptions<T> {
/**
* JSON Schema for validating config data.
* Define as object where each key is a property name
* and each value is a JSON schema for that property.
*/
schema?: Schema<T>;
/**
* Top-level schema properties excluding `properties` field.
*/
rootSchema?: Omit<JSONSchema, 'properties'>;
/**
* Options passed to AJV validator.
* allErrors and useDefaults are true by default.
*/
ajvOptions?: AjvOptions;
/**
* Clear config if reading causes SyntaxError.
* Good for unimportant data that may get corrupted.
* @default false
*/
clearInvalidConfig?: boolean;
}
type Schema<T> = {[Property in keyof T]: ValueSchema};
type ValueSchema = JSONSchema;Usage Examples:
interface UserConfig {
name: string;
age: number;
email: string;
preferences: {
theme: string;
notifications: boolean;
};
}
const config = new Conf<UserConfig>({
projectName: "user-app",
schema: {
name: {
type: "string",
minLength: 1,
default: "Anonymous"
},
age: {
type: "number",
minimum: 0,
maximum: 150
},
email: {
type: "string",
format: "email"
},
preferences: {
type: "object",
properties: {
theme: {
type: "string",
enum: ["light", "dark"],
default: "light"
},
notifications: {
type: "boolean",
default: true
}
}
}
},
rootSchema: {
additionalProperties: false
}
});
// This will throw a validation error
config.set("age", -5); // Error: Config schema violation: `age` should be >= 0Options for encryption, file permissions, and storage format customization.
interface SecurityOptions<T> {
/**
* Encryption key for config file obfuscation (not security).
* Helps deter users from manually editing config files.
*/
encryptionKey?: string | Uint8Array | NodeJS.TypedArray | DataView;
/**
* File permission mode for config file.
* @default 0o666
*/
configFileMode?: number;
/**
* Custom serialization function.
* @default value => JSON.stringify(value, null, '\t')
*/
serialize?: Serialize<T>;
/**
* Custom deserialization function.
* @default JSON.parse
*/
deserialize?: Deserialize<T>;
}
type Serialize<T> = (value: T) => string;
type Deserialize<T> = (text: string) => T;Usage Examples:
import yaml from "js-yaml";
// Encrypted config for obfuscation
const secretConfig = new Conf({
projectName: "secure-app",
encryptionKey: "my-secret-key-not-for-security"
});
// YAML format instead of JSON
const yamlConfig = new Conf({
projectName: "yaml-app",
fileExtension: "yaml",
serialize: yaml.dump,
deserialize: yaml.load
});
// Restrictive file permissions (user-only access)
const privateConfig = new Conf({
projectName: "private-app",
configFileMode: 0o600
});Options that control how the configuration store behaves.
interface BehaviorOptions {
/**
* Enable nested property access via dot notation.
* @default true
*/
accessPropertiesByDotNotation?: boolean;
/**
* Watch config file for external changes.
* Useful when multiple processes modify the same file.
* @default false
*/
watch?: boolean;
}Usage Examples:
// Disable dot notation - treat dots as literal key characters
const literalConfig = new Conf({
projectName: "literal-app",
accessPropertiesByDotNotation: false
});
literalConfig.set("foo.bar.baz", "value");
console.log(literalConfig.get("foo.bar.baz")); // => "value"
// Enable file watching for multi-process scenarios
const watchedConfig = new Conf({
projectName: "multi-process-app",
watch: true
});
watchedConfig.onDidAnyChange((newValue, oldValue) => {
console.log("Config changed externally:", { newValue, oldValue });
});Options for handling version-based configuration migrations.
interface MigrationOptions<T> {
/**
* Project version - required if using migrations.
* Used to determine which migrations to run.
*/
projectVersion?: string;
/**
* Migration handlers keyed by version or semver range.
* Each handler receives the store instance.
*/
migrations?: Migrations<T>;
/**
* Callback executed before each migration step.
* Useful for logging or preparing migration data.
*/
beforeEachMigration?: BeforeEachMigrationCallback<T>;
}
type Migrations<T> = Record<string, (store: Conf<T>) => void>;
type BeforeEachMigrationCallback<T> = (store: Conf<T>, context: BeforeEachMigrationContext) => void;
interface BeforeEachMigrationContext {
fromVersion: string;
toVersion: string;
finalVersion: string;
versions: string[];
}Usage Examples:
const migratingConfig = new Conf({
projectName: "evolving-app",
projectVersion: "2.1.0",
beforeEachMigration: (store, context) => {
console.log(`Migrating from ${context.fromVersion} to ${context.toVersion}`);
},
migrations: {
"1.0.0": (store) => {
// Migrate to v1.0.0 - add debug flag
store.set("debug", false);
},
"1.5.0": (store) => {
// Migrate to v1.5.0 - restructure settings
const oldTheme = store.get("theme");
store.delete("theme");
store.set("ui.theme", oldTheme || "light");
},
">=2.0.0": (store) => {
// Migrate to v2.x.x - upgrade settings format
store.set("version", 2);
store.set("migrated", true);
}
}
});interface Options<T extends Record<string, any>> {
// Core options
projectName?: string;
configName?: string;
defaults?: Readonly<T>;
cwd?: string;
fileExtension?: string;
projectSuffix?: string;
// Validation options
schema?: Schema<T>;
rootSchema?: Omit<JSONSchema, 'properties'>;
ajvOptions?: AjvOptions;
clearInvalidConfig?: boolean;
// Security options
encryptionKey?: string | Uint8Array | NodeJS.TypedArray | DataView;
configFileMode?: number;
serialize?: Serialize<T>;
deserialize?: Deserialize<T>;
// Behavior options
accessPropertiesByDotNotation?: boolean;
watch?: boolean;
// Migration options
projectVersion?: string;
migrations?: Migrations<T>;
beforeEachMigration?: BeforeEachMigrationCallback<T>;
}