Prettier 20 ๐จ getFileInfo โ Determining if a file needs formatting
prettier.getFileInfo() answers a question that is different from resolveConfig() and different from format(). It does not return formatting options, and it does not format anything. It returns a description of the file: whether it is ignored by .prettierignore or node_modules, and which parser Prettier would infer from the filename or an installed plugin. The return value is an object with an ignored boolean and an inferredParser string (or null) . This is the function an editor integration calls before deciding whether to format on save. It is the gate that prevents Prettier from attempting to format a file it has no parser for, or a file the user explicitly excluded.
The distinction between getFileInfo() and resolveConfig() is the distinction between “should this file be formatted?” and “how should this file be formatted?” The resolveConfig() function returns the options; the getFileInfo() function returns the metadata that determines whether formatting is applicable at all. An editor integration typically calls both: first getFileInfo() to check whether the file is ignored or has an inferable parser, then resolveConfig() to get the options for the format call .
Key point: getFileInfo(filePath, options) returns a Promise that resolves to an object with ignored and inferredParser properties. A file is formattable when ignored is false and inferredParser is not null. The function does not resolve configuration unless resolveConfig: true is passed, and it does not check whether the file’s content is already formatted.
Why getFileInfo exists separately from resolveConfig
The parser inference problem. Prettier determines the parser from the file extension. A .js file uses the Babel parser; a .css file uses the CSS parser; a .md file uses the Markdown parser. When the extension is unfamiliar, Prettier cannot infer a parser, and formatting the file would fail. The inferredParser field is the result of that inference. If it is null, the file is not formattable without an explicit parser option or an installed plugin . The getFileInfo() function exposes this inference so that integrations can check it before attempting to format.
The ignore rules problem. Prettier respects .prettierignore files and ignores node_modules by default. An editor integration that formats on save must not format a file that the project has excluded. The ignored boolean is the result of checking the file against the ignore rules. If ignored is true, the integration should skip the file entirely . The ignorePath option allows the integration to specify a custom ignore file, and the withNodeModules option allows formatting files inside node_modules when necessary .
The plugin parser problem. A file with a .elm extension has no parser in Prettier core. But if prettier-plugin-elm is installed, the plugin registers a parser for that extension, and getFileInfo() returns inferredParser: "elm" instead of null . The plugins option allows the caller to pass plugin paths explicitly, and the resolveConfig option (or useConfig in older versions) allows the function to read the configuration file to discover plugins and overrides . Without these options, the inference is based on Prettier’s built-in parsers only.
The trade-off. The function performs filesystem I/O to read the ignore file and, if resolveConfig is enabled, to find and parse the configuration. It is asynchronous and returns a Promise. An integration that calls it on every keystroke or every file open pays that I/O cost. The caching behavior is not documented in the same way as resolveConfig(), but the underlying config resolution may cache its results. The alternativeโassuming a file is formattable and catching the error from format()โproduces a worse user experience, because the error is surfaced after the attempt rather than prevented before it.
a. The basic usage and the formattable check
The canonical pattern is to call getFileInfo(), check the two fields, and proceed only if the file is formattable. The resolveConfig option enables the function to consider parser overrides and plugins declared in the configuration.
// is-formattable.mjs โ checking whether a file should be formatted
import * as prettier from "prettier";
async function isFormattable(filePath) {
// getFileInfo returns ignored and inferredParser.
// resolveConfig: true allows the function to read .prettierrc
// so that parser overrides and plugins are considered.
const fileInfo = await prettier.getFileInfo(filePath, {
resolveConfig: true,
});
// A file is formattable when it is not ignored
// and Prettier can infer a parser for it.
// The parser may be null if the extension is unknown
// and no plugin provides a parser.
return !fileInfo.ignored && fileInfo.inferredParser !== null;
}
const ok = await isFormattable("src/app.js");
console.log("Formattable:", ok); // true
const notOk = await isFormattable("src/app.elm");
console.log("Formattable:", notOk); // false unless the Elm plugin is installed
The inferredParser is the parser name that Prettier would use if format() were called with the file path. It is a string like "babel", "typescript", "css", or "markdown". It is null when the inference fails . The ignored field is true when the file matches a pattern in .prettierignore or is inside node_modules without withNodeModules .
// format-on-save.mjs โ the editor integration pattern
async function formatOnSave(filePath) {
const fileInfo = await prettier.getFileInfo(filePath, {
resolveConfig: true,
});
// Skip ignored files and files without an inferred parser.
if (fileInfo.ignored || fileInfo.inferredParser === null) {
return null;
}
const options = await prettier.resolveConfig(filePath);
const source = await readFile(filePath, "utf8");
// Pass the inferred parser explicitly.
// The filepath option would also work, but the parser
// from getFileInfo is already resolved.
return prettier.format(source, {
...options,
parser: fileInfo.inferredParser,
filepath: filePath,
});
}
The editor integration pattern uses both functions. The getFileInfo() call is the gate; the resolveConfig() call is the options lookup. The inferredParser from the first call is passed to format() explicitly, which avoids a second inference. The filepath option is still passed because it provides the path for error messages and for any file-specific logic in the parser.
b. The options that control the check
The getFileInfo() function accepts several options that change what it checks. The ignorePath option specifies a custom ignore file. The withNodeModules option allows files inside node_modules to be considered formattable. The plugins option supplies plugin paths for parser inference. The resolveConfig option enables configuration resolution.
// get-file-info-options.mjs โ the options
const fileInfo = await prettier.getFileInfo("node_modules/pkg/file.js", {
// By default, node_modules is ignored.
// Set to true to treat files inside node_modules as formattable.
withNodeModules: true,
// Use a custom ignore file instead of .prettierignore.
ignorePath: ".gitignore",
// Pass plugin paths so that non-core parsers are inferred.
plugins: ["prettier-plugin-elm"],
// Resolve the configuration to consider overrides and plugins.
resolveConfig: true,
});
The resolveConfig option is the one that connects getFileInfo() to the configuration file. Without it, the parser inference uses only the built-in parsers and the plugins option passed explicitly. With it, the function reads the configuration file and considers parser overrides and plugins declared there . The useConfig option was the older name for the same behavior; the current name is resolveConfig .
// get-file-info-ignore.mjs โ checking ignore status only
const fileInfo = await prettier.getFileInfo("dist/bundle.js", {
// No need to resolve configuration just to check ignore status.
resolveConfig: false,
// The default ignore path is .prettierignore.
ignorePath: ".prettierignore",
});
if (fileInfo.ignored) {
console.log("File is ignored by .prettierignore");
}
The ignore check is independent of the parser inference. A file can be ignored even if it has an inferable parser. A .js file inside dist/ matches a common .prettierignore pattern, so ignored is true even though inferredParser is "babel". The integration should skip the file because of the ignore status, not because of the parser.
Complete Example Session
// ============================================
// PART 1: THE BASIC CALL
// ============================================
// get-file-info.mjs
import * as prettier from "prettier";
// getFileInfo is asynchronous and returns a Promise.
// The result has two fields: ignored and inferredParser.
const fileInfo = await prettier.getFileInfo("src/app.js");
console.log(fileInfo);
// { ignored: false, inferredParser: "babel" }
// ============================================
// PART 2: THE IGNORED FILE
// ============================================
// A file inside node_modules is ignored by default.
const nodeModulesInfo = await prettier.getFileInfo(
"node_modules/lodash/lodash.js"
);
console.log(nodeModulesInfo);
// { ignored: true, inferredParser: "babel" }
// The parser is inferable, but the file is ignored.
// The integration should skip it.
// ============================================
// PART 3: THE UNKNOWN EXTENSION
// ============================================
// A file with an extension that Prettier core does not support.
const elmInfo = await prettier.getFileInfo("src/Main.elm");
console.log(elmInfo);
// { ignored: false, inferredParser: null }
// The parser is null, so the file is not formattable
// without an explicit parser or a plugin.
// ============================================
// PART 4: THE PLUGIN OPTION
// ============================================
// Passing the plugin path allows the parser to be inferred.
const elmInfoWithPlugin = await prettier.getFileInfo("src/Main.elm", {
plugins: ["prettier-plugin-elm"],
});
console.log(elmInfoWithPlugin);
// { ignored: false, inferredParser: "elm" }
// ============================================
// PART 5: THE RESOLVE CONFIG OPTION
// ============================================
// If the configuration file declares the plugin,
// resolveConfig: true allows getFileInfo to find it.
// .prettierrc: { "plugins": ["prettier-plugin-elm"] }
const elmInfoWithConfig = await prettier.getFileInfo("src/Main.elm", {
resolveConfig: true,
});
console.log(elmInfoWithConfig);
// { ignored: false, inferredParser: "elm" }
// ============================================
// PART 6: THE CUSTOM IGNORE PATH
// ============================================
// Use a custom ignore file instead of .prettierignore.
const customIgnoreInfo = await prettier.getFileInfo("src/generated/api.ts", {
ignorePath: ".gitignore",
});
console.log(customIgnoreInfo.ignored);
// true if .gitignore lists src/generated/
// ============================================
// PART 7: THE withNodeModules OPTION
// ============================================
// Allow files inside node_modules to be considered formattable.
const withNodeModulesInfo = await prettier.getFileInfo(
"node_modules/my-pkg/index.js",
{ withNodeModules: true }
);
console.log(withNodeModulesInfo);
// { ignored: false, inferredParser: "babel" }
// ============================================
// PART 8: THE FORMATTABLE CHECK
// ============================================
// The combined check: not ignored AND a parser is inferred.
function isFormattable(fileInfo) {
return !fileInfo.ignored && fileInfo.inferredParser !== null;
}
const info = await prettier.getFileInfo("src/app.js");
if (isFormattable(info)) {
// Safe to format.
}
// ============================================
// PART 9: THE EDITOR INTEGRATION FLOW
// ============================================
// The full flow for format-on-save:
// 1. getFileInfo to check ignored and inferredParser.
// 2. resolveConfig to get the options.
// 3. format to produce the output.
// 4. Compare the output to the source to decide whether to write.
async function formatOnSave(filePath) {
const fileInfo = await prettier.getFileInfo(filePath, {
resolveConfig: true,
});
if (fileInfo.ignored || fileInfo.inferredParser === null) {
return; // Skip
}
const options = await prettier.resolveConfig(filePath);
const source = await readFile(filePath, "utf8");
const formatted = await prettier.format(source, {
...options,
parser: fileInfo.inferredParser,
filepath: filePath,
});
if (formatted !== source) {
await writeFile(filePath, formatted, "utf8");
}
}
// ============================================
// PART 10: THE VERIFICATION CHECKLIST
// ============================================
// [ ] getFileInfo is awaited.
// [ ] The ignored field is checked before formatting.
// [ ] The inferredParser field is checked for null.
// [ ] resolveConfig: true is passed if the config declares plugins or overrides.
// [ ] plugins is passed if the plugin is not declared in the config.
// [ ] withNodeModules is set only when node_modules files must be formatted.
The ten parts covered the basic call, the ignored file, the unknown extension, the plugin option, the resolve config option, the custom ignore path, the node_modules option, the formattable check, the editor integration flow, and the verification checklist. The through-line is that getFileInfo is the gate, and the two fields it returns determine whether formatting should be attempted at all.
Quick Reference
The return object
| Field | Type | Meaning |
|---|---|---|
ignored | boolean | True if the file matches ignore rules or is in node_modules |
inferredParser | string | null | The parser name, or null if no parser can be inferred |
Options
| Option | Type | Default | Purpose |
|---|---|---|---|
resolveConfig | boolean | false | Read the config for plugins and overrides |
ignorePath | string | .prettierignore | Custom ignore file |
withNodeModules | boolean | false | Treat node_modules files as formattable |
plugins | string[] | [] | Plugin paths for parser inference |
The formattable check
| Condition | Result |
|---|---|
ignored: true | Skip |
inferredParser: null | Skip |
ignored: false and inferredParser: "babel" | Format |
Best Practices
โ Do This:
// Await the result
const info = await prettier.getFileInfo(filePath); // โ
// Check both fields
if (!info.ignored && info.inferredParser !== null) { /* format */ } // โ
// Pass resolveConfig: true if the config declares plugins
await prettier.getFileInfo(filePath, { resolveConfig: true }); // โ
// Pass plugins explicitly if the config does not declare them
await prettier.getFileInfo("Main.elm", { plugins: ["prettier-plugin-elm"] }); // โ
โ Don’t Do This:
// Use the result without awaiting
const info = prettier.getFileInfo(filePath); // Promise // โ
// Format a file with inferredParser: null
await prettier.format(source, { filepath: "Main.elm" }); // error // โ
// Assume node_modules is formattable
// It is ignored by default. // โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Format fails on an unknown extension | inferredParser is null | Check the field before formatting |
| A plugin parser is not inferred | Plugin not passed and not in config | Pass plugins or resolveConfig: true |
| A file is formatted despite being ignored | The ignored field was not checked | Check ignored before formatting |
node_modules file is not formatted | withNodeModules not set | Pass withNodeModules: true |
| Custom ignore file is not respected | ignorePath not set | Pass the path explicitly |
Real-World Examples
1. Basic call
const info = await prettier.getFileInfo("src/app.js");
// { ignored: false, inferredParser: "babel" }
2. Ignored file
const info = await prettier.getFileInfo("dist/bundle.js");
// { ignored: true, inferredParser: "babel" }
3. Unknown extension
const info = await prettier.getFileInfo("src/Main.elm");
// { ignored: false, inferredParser: null }
4. Plugin inference
await prettier.getFileInfo("src/Main.elm", { plugins: ["prettier-plugin-elm"] });
// { ignored: false, inferredParser: "elm" }
5. Resolve config for plugins
await prettier.getFileInfo("src/Main.elm", { resolveConfig: true });
6. Custom ignore path
await prettier.getFileInfo("src/gen.ts", { ignorePath: ".gitignore" });
7. node_modules file
await prettier.getFileInfo("node_modules/pkg/index.js", { withNodeModules: true });
8. Formattable check
if (!info.ignored && info.inferredParser) { /* format */ }
9. Editor integration gate
const info = await prettier.getFileInfo(filePath, { resolveConfig: true });
if (info.ignored || !info.inferredParser) return;
10. Ignore check only
const info = await prettier.getFileInfo(filePath, { resolveConfig: false });
if (info.ignored) skip();
Visual
The Two Functions, Two Jobs
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ getFileInfo vs resolveConfig โ
โ โ
โ getFileInfo(filePath) resolveConfig(filePath) โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ "Should this file โ โ "How should this โ โ
โ โ be formatted?" โ โ file be formatted?"โ โ
โ โ โ โ โ โ
โ โ ignored: false โ โ semi: true โ โ
โ โ inferredParser: โ โ singleQuote: false โ โ
โ โ "babel" โ โ printWidth: 80 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ The first is the gate. The second is the options. โ
โ An editor calls both before format(). โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Formattable Decision
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WHEN IS A FILE FORMATTABLE? โ
โ โ
โ ignored: false ignored: true โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ inferredParser: โ โ Skip. Do not format.โ โ
โ โ "babel" โ โ โ โ
โ โ โ FORMAT โ โ The file is โ โ
โ โ โ โ excluded. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ inferredParser: null โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Skip. Do not format.โ โ
โ โ โ โ
โ โ No parser for this โ โ
โ โ extension. โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Both conditions must pass. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Parser Inference
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HOW inferredParser IS DETERMINED โ
โ โ
โ filePath: "src/app.js" โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Check the extension โ โ
โ โ against built-in โ โ
โ โ parsers โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ .js โ "babel" โ Found. Return the name. โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ filePath: "src/Main.elm" โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ No built-in parser โ โ
โ โ for .elm โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Check plugins and โ โ
โ โ resolveConfig โ โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ No plugin โ null โ Not formattable. โ
โ โ Plugin โ "elm" โ Formattable. โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Function | prettier.getFileInfo(filePath, options) |
| Return | Promise<{ ignored: boolean, inferredParser: string | null }> |
| Formattable condition | !ignored && inferredParser !== null |
resolveConfig option | Enables config-based parser inference |
ignorePath option | Custom ignore file |
withNodeModules option | Treat node_modules as formattable |
plugins option | Plugin paths for parser inference |
Key takeaways:
getFileInfo()is the gate, not the formatter. It returnsignoredandinferredParser, and those two fields determine whether the file should be formatted at all. It does not return options and does not format anything .- The
inferredParsercan benull. When the file extension is unknown and no plugin provides a parser, the inference fails. Attempting to format the file without an explicit parser or plugin produces an error. Thenullcheck is the prevention . - The
ignoredfield respects.prettierignoreandnode_modules. Files insidenode_modulesare ignored by default. TheignorePathoption allows a custom ignore file, andwithNodeModulesallows formatting files insidenode_moduleswhen necessary . - The
resolveConfigoption connectsgetFileInfoto the configuration. Without it, the parser inference uses only built-in parsers and explicitly passed plugins. With it, the function reads the configuration file and considers plugins and overrides declared there . - The editor integration calls both functions.
getFileInfo()first to check whether the file is formattable, thenresolveConfig()to get the options, thenformat()to produce the output. TheinferredParserfrom the first call is passed toformat()explicitly to avoid a second inference.
Remember: getFileInfo() is the function that prevents Prettier from being called on files it cannot or should not format. The ignored field handles the exclusions; the inferredParser field handles the capability. An integration that skips this check and calls format() directly will produce errors on ignored files and unknown extensions. The function is asynchronous, the result is a Promise, and the two fields are the entire answer. The options exist to customize the ignore rules and to enable plugin-based parser inference. The gate is the function’s purpose.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!