Getting the Prettier API to Format Code in the Same Way as the CLI

For some time now I've struggled to get the Prettier Node API to format code in the same way as the CLI does. What I mean by that is when running the Prettier CLI with a Prettier config file, it would format the code as expected. However, when I would try to run the Node API on the same file, it wouldn't quite format the code in the same way.

# CLI works as expected
npx prettier --write path_to_file
// Node API wasn't formatting correctly
const prettier = require('prettier');
prettier.format(code, ...options);

After a lot of trial and error, I was finally able to figure out the required steps in order to get it to work.

First, using the Node API requires that you pass the parser option. I had always struggled to figure out which parser to use as Prettier doesn't seem to list the defaults (especially when trying to format JSON). It turns out that if you pass the filepath option, Prettier will infer the parser option for you. This wasn't stated clearly enough for me to understand in the docs.

The reason it uses filepath instead of using something like file extension is because the Prettier config file can have overrides that are triggered based on the filepath.

prettier.format(code, {
  filepath: 'path_to_file'
});

The next thing I had to do was figure out how to import the Prettier config. I would have assumed the format function would load it automatically, but that was not the case. Instead we have to load it ourselves and pass it as options into the function using the resolveConfig function.

const filepath = 'path_to_file';
const config = prettier.resolveConfig.sync(filepath);
prettier.format(code, {
  filepath,
  ...config
});

Lastly, in order to correctly format JSON you have to stringify it first. Not only that, but you also might need to use the space option when you stringify in order for Prettier to output newlines correctly. Otherwise Prettier will try to put object properties on a single line if they don't exceed the line width setting.

const filepath = 'path_to_file';
const config = prettier.resolveConfig.sync(filepath);
const code = JSON.stringify(data, null, 2);
prettier.format(code, {
  filepath,
  ...config
});

With that, I was able to get the API and the CLI to be consistent in how the code was formatted.