Load and resolve oxfmt configuration files, including explicit JS/TS config paths, and merge supported
.editorconfigsettings for oxfmt.
- 🔍 Auto-discovery - Automatically searches for config files in current and parent directories
- 📦 Multiple formats - Auto-discovers
.oxfmtrc.json,.oxfmtrc.jsonc,oxfmt.config.ts, andoxfmt.config.mts, and also supports explicit.json/.jsonc/.js/.mjs/.cjs/.ts/.mts/.ctsconfig paths - 🧩 EditorConfig fallback - Merges supported
.editorconfigfields into the returned oxfmt config result - 🚫 Ignore resolution - Resolves ignore status with oxfmt CLI-like global + config-scoped semantics
- ⚡ Built-in caching - Caches both file resolution and parsed configs for optimal performance
- 🎯 TypeScript support - Fully typed with comprehensive type definitions
- 🛠️ Flexible API - Support explicit config paths or automatic discovery
npm install load-oxfmt-configyarn add load-oxfmt-configpnpm add load-oxfmt-config
oxfmtis a peer dependency and should be installed alongside this package. Node.js^22.13.0 || >=24is supported.
Load config from current directory or parent directories:
import { loadOxfmtConfig } from 'load-oxfmt-config'
// Automatically searches for oxfmt config files and the nearest .editorconfig
const result = await loadOxfmtConfig()
console.log(result.config) // { printWidth: 80, ... }import { loadOxfmtConfig } from 'load-oxfmt-config'
const result = await loadOxfmtConfig({ cwd: '/path/to/project' })
// Returns one merged static config object
console.log(result.config)
// {
// tabWidth: 2,
// printWidth: 100,
// overrides: [
// { files: ['src/**/*.ts'], options: { printWidth: 120 } }
// ]
// }import { loadOxfmtConfig } from 'load-oxfmt-config'
const result = await loadOxfmtConfig({
cwd: '/path/to/project',
})import { loadOxfmtConfig } from 'load-oxfmt-config'
const result = await loadOxfmtConfig({ cwd: '/path/to/project' })
console.log(result.config) // merged oxfmt options
console.log(result.filepath) // /path/to/project/.oxfmtrc.json (or undefined)
console.log(result.dirname) // /path/to/project (or undefined)import { isOxfmtIgnored } from 'load-oxfmt-config'
const result = await isOxfmtIgnored({
cwd: '/path/to/project',
filepath: '/path/to/project/src/generated/foo.ts',
})
console.log(result)
// { ignored: true, reason: 'config-ignore-patterns' }import { loadOxfmtConfig } from 'load-oxfmt-config'
// Relative path (resolved relative to cwd)
const result = await loadOxfmtConfig({
configPath: 'configs/.oxfmtrc.json',
cwd: '/path/to/project',
})
// Absolute path
const absoluteResult = await loadOxfmtConfig({
configPath: '/absolute/path/to/.oxfmtrc.json',
})import { loadOxfmtConfig } from 'load-oxfmt-config'
// Skip .editorconfig reading entirely
const result = await loadOxfmtConfig({
editorconfig: false,
})import { loadOxfmtConfig } from 'load-oxfmt-config'
// Only look in the cwd directory itself, no upward traversal
const result = await loadOxfmtConfig({
editorconfig: { onlyCwd: true },
})import { loadOxfmtConfig } from 'load-oxfmt-config'
// Search .editorconfig from a custom directory instead of the config file's directory
const result = await loadOxfmtConfig({
editorconfig: {
cwd: '/path/to/editorconfig-dir',
},
})import { loadOxfmtConfig } from 'load-oxfmt-config'
// Force reload from disk, bypassing cache
const result = await loadOxfmtConfig({
useCache: false,
})import { resolveOxfmtrcPath } from 'load-oxfmt-config'
// Only resolve the config file path without loading it
const configPath = await resolveOxfmtrcPath(process.cwd())
console.log(configPath) // '/path/to/.oxfmtrc.json' or undefinedLoad and parse oxfmt configuration files, merge supported .editorconfig fields, and return metadata for the resolved config file.
Parameters:
options- Optional configuration object (LoadOxfmtConfigOptions)
Option fields:
- Type:
string - Default:
process.cwd()
Current working directory for config resolution.
By default config discovery starts here, unless filepath is provided.
- Type:
string - Default:
undefined
Target file path for nested config resolution.
When provided (and configPath is not set), config discovery starts from dirname(filepath) and walks upward to match oxfmt per-file semantics.
- Type:
string - Default:
undefined
Explicit path to the config file:
- Relative path: Resolved relative to
cwd - Absolute path: Used as-is
- When provided: Skips auto-discovery and uses this path directly
- Type:
boolean - Default:
false
Disable nested config lookup.
When true, config discovery is anchored to cwd (or explicit configPath) instead of filepath.
- Type:
boolean - Default:
true
Enable in-memory caching for both path resolution and parsed config contents. When enabled:
- Config file paths are cached to avoid repeated filesystem lookups
- Parsed config objects are cached to avoid re-parsing
- Subsequent calls with the same parameters return cached results instantly
Set to false to force reload from disk on every call.
- Type:
boolean | EditorconfigOption - Default:
true
Control how .editorconfig files are read and merged:
true— Read and merge the nearest.editorconfig, walking up from the config-discovery start directory:dirname(filepath)when nested lookup is enabled andfilepathis provided- otherwise
cwd
false— Disable.editorconfigreading entirely.EditorconfigOption— Enable with additional settings:
| Property | Type | Default | Description |
|---|---|---|---|
onlyCwd |
boolean |
false |
When true, only look for .editorconfig in cwd itself — no upward traversal. |
cwd |
string |
undefined |
Override the directory from which .editorconfig resolution starts, instead of the default lookup directory. |
Returns: Promise<LoadOxfmtConfigResult>
config- Parsed and merged oxfmt configuration objectfilepath- Resolved config absolute path (undefined when not found)dirname- Config directory (undefined when not found)
Throws: Error if config file exists but cannot be parsed.
Resolve the absolute path to oxfmt config file.
Parameters:
cwd- Starting directory for resolutionconfigPath- Optional explicit path (absolute or relative to cwd)
Returns: Promise<string | undefined> - Absolute path to config file, or undefined if not found.
Resolve whether a file should be ignored with oxfmt CLI-like semantics.
Parameters:
options- Required configuration object (IsOxfmtIgnoredOptions)
Option fields:
- Type:
string - Default:
process.cwd()
Current working directory.
Also the base directory for default .prettierignore lookup.
- Type:
string - Default: required
File path to test.
- Type:
string - Default:
undefined
Explicit oxfmt config path.
When provided, nested config lookup is disabled (same as oxfmt CLI -c).
- Type:
string | string[] - Default:
undefined
Ignore files to use instead of the default cwd .prettierignore.
Can be passed multiple times in CLI style.
Explicit ignore paths do not replace .gitignore or .git/info/exclude handling.
- Type:
boolean - Default:
false
Whether node_modules should be included.
- Type:
boolean - Default:
false
Disable nested config lookup.
- Type:
boolean - Default:
true
Whether to use in-memory cache.
- Type:
boolean - Default:
true
Whether to include ignore patterns defined in the resolved config file.
- Type:
boolean - Default:
true
Whether to load the resolved config file during ignore checks.
When false, isOxfmtIgnored() only applies global ignore and skips config loading.
Returns: Promise<IsOxfmtIgnoredResult>
ignored- Whether the file is ignoredreason- One of:default-dirlockfilegitignoregit-info-excludeprettierignoreignore-pathconfig-ignore-patterns
When configPath is not provided, the loader automatically searches for config files:
- Search order: Starts from
dirname(filepath)whenfilepathis provided and nested lookup is enabled; otherwise starts fromcwd, then walks up to parent directories - Supported filenames:
.oxfmtrc.json.oxfmtrc.jsoncoxfmt.config.tsoxfmt.config.mts
- Stops when:
- A valid config file is found
- Reaches the filesystem root
- EditorConfig: The nearest
.editorconfigis resolved from the same start directory and merged into the returned result - Returns: Empty object
{}if no config file is found
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true
}JSON with comments support:
export default {
printWidth: 100,
tabWidth: 2,
}JavaScript and TypeScript config files are executed while loading config. Only load them from repositories you trust.
JavaScript and TypeScript config files must provide a default export whose value is an object.
When configPath is passed explicitly, extensions .json, .jsonc, .ts, .mts, .cts, .js, .mjs, and .cjs are supported. Extensionless paths are also accepted and parsed as JSON.
The loader reads the nearest .editorconfig file and maps the subset of fields that oxfmt supports:
end_of_line→endOfLineindent_style→useTabsindent_size→tabWidthwhenindent_style = spacetab_width→tabWidthmax_line_length→printWidthinsert_final_newline→insertFinalNewlinequote_type→singleQuote
Only [*] is treated as a global section to match oxfmt. Other sections such as [**] and [*.ts] are converted into returned overrides entries.
isOxfmtIgnored() applies two layers:
- Global ignore
- Ignore patterns from the resolved oxfmt config (
ignorePatterns)
Set includeConfigIgnorePatterns: false to skip config ignorePatterns matching.
Set loadConfigForIgnorePatterns: false to skip config loading entirely and keep only global ignore behavior.
Global ignore includes:
- Default ignored directories:
.git,.jj,.sl,.svn,.hg,node_modules - Default lockfiles:
package-lock.json,pnpm-lock.yaml,yarn.lock,MODULE.bazel.lock,bun.lock,deno.lock,composer.lock,Package.resolved,Pipfile.lock,flake.lock,Cargo.lock,Gopkg.lock,pdm.lock,poetry.lock,uv.lock,npm-shrinkwrap.json,bun.lockb - Ignore files:
- Always read
.gitignorefrom the file's directory upward until the git repo boundary - Always read
<repo>/.git/info/excludewhen inside a git repo - If
ignorePathis provided: read those files instead ofcwd/.prettierignore - If
ignorePathis not provided: read.prettierignorefromcwd
- Always read
Notes:
-
node_modulescan be included by passingwithNodeModules: true. -
The default lockfile list mirrors oxfmt documentation intent (
package-lock.json,pnpm-lock.yaml, etc.) and common ecosystem lockfiles. It is not guaranteed to be a complete internal oxfmt list. -
ignorePatternsuse gitignore semantics and are interpreted relative to the resolved oxfmt config directory. Parent-directory (..) path segments are rejected because patterns cannot match files outside that directory. -
includeConfigIgnorePatternsdefaults totrueto preserve current behavior. -
loadConfigForIgnorePatternsdefaults totrueto preserve current behavior. -
Nested config behavior follows oxfmt semantics:
- default: nearest config from target file directory upward
disableNestedConfig: true: resolve fromcwdonlyconfigPath: also disables nested lookup (same intent as CLI-c)- invalid nested config only fails files that resolve to that config (no project-wide pre-scan)
The merged result follows oxfmt's fallback semantics:
- Root and section-specific
.editorconfigvalues provide defaults for unset fields - Root-level values from
.oxfmtrc.json,.oxfmtrc.jsonc,oxfmt.config.ts, oroxfmt.config.mtstake precedence over all.editorconfigvalues - Overrides declared directly in the oxfmt config file have the highest priority
Section-specific .editorconfig entries are represented as generated overrides in the static result. Fields already defined at the oxfmt config root are omitted from those generated overrides, and explicit oxfmt overrides are appended after them.
loadOxfmtConfig() returns a static merged OxfmtOptions shape. That means .editorconfig support is represented as merged root + overrides config data, not as per-file runtime evaluation. In practice this works well for common root settings and section-based overrides, but it is not a full replacement for oxfmt's own file-by-file config resolution.
import { loadOxfmtConfig } from 'load-oxfmt-config'
try {
const result = await loadOxfmtConfig()
console.log(result.config)
} catch (error) {
// Thrown when a resolved config file cannot be parsed or loaded
console.error('Failed to parse oxfmt config:', error.message)
}The caching system maintains two separate caches:
- Path Resolution Cache: Stores resolved config file paths
- Config Content Cache: Stores parsed configuration objects
Cache keys are based on:
cwd+configPathfor path resolution- or
dirname(filepath)+configPathwhenfilepathis provided and nested lookup is enabled - Resolved oxfmt path and resolved
.editorconfigpath for config content
Cache invalidation:
- Failed operations automatically clear their cache entries
- Use
useCache: falseto bypass cache for specific calls - For native ESM config files (
.mjsor.jsunder"type": "module"),useCache: falsecache-busts the entry config file. Imported ESM helper modules still follow Node.js module cache behavior for the current process. - Cache persists for the lifetime of the Node.js process
{ // Formatting options "printWidth": 100, "tabWidth": 2, /* Code style preferences */ "useTabs": false, "semi": true, "singleQuote": true, }