This Emacs package provides a function, prettier-js-prettify
, which formats the current buffer using Prettier. It also exports a minor mode, prettier-js-mode
, which calls prettier-js-prettify
on save.
Despite the "-js" in its name, this package actually supports more than just JavaScript. It works with any language that Prettier supports! List here.
Ensure that the prettier
program is installed:
which prettier
If prettier
is not installed already, you can install it using npm install -g prettier
or via your package manager.
Alternatively, if your project uses Prettier (i.e. it's a devDependency
in your package.json
), then you'll be able to use the executable installed via npm install
, instead.
This package uses the diff
program under the hood to reliably identify formatting changes made by Prettier. On macOS and GNU/Linux, diff
should already be installed. On other platforms, you should install/configure GNU's diff implementation.
Windows
On Windows, install via Chocolatey:
- Follow the Chocolatey install instructions: https://chocolatey.org/install
- Open an Admin PowerShell session
- Install the
diff
program:choco install diffutils
Also, make sure that the correct version of diff
is accessible from your system path; sometimes, multiple conflicting diff
executables may be installed.
BSD systems (OpenBSD, FreeBSD)
On BSD systems (like OpenBSD, FreeBSD), the default diff
program may not support some GNU diff features that this package requires, such as --strip-trailing-cr
. To resolve this:
- Install GNU diff (often called
gdiff
orgnudiff
):- On OpenBSD:
pkg_add gdiff
- On FreeBSD:
pkg install diffutils
- On OpenBSD:
- Configure this package to use the GNU diff implementation:
(Use the appropriate command name for your system, which might be
(setq prettier-js-diff-command "gdiff")
gdiff
,gnudiff
, orgd
)
Depending on how the programs are installed, node
, prettier
, and/or diff
may be missing on Emacs' exec-path
. When attempting to format a buffer, this could result in errors such as:
- "Node executable not found"
- "Could not find prettier executable"
An easy solution to this issue is to install and use exec-path-from-shell
. Add to your init file:
(exec-path-from-shell-initialize)
First require the package:
(require 'prettier-js)
Or use use-package
(available in Emacs 29.1 and above):
(use-package prettier-js)
Then you can hook into any modes where you want to format with Prettier:
(add-hook 'js-mode-hook 'prettier-js-mode)
(add-hook 'web-mode-hook 'prettier-js-mode)
You can also enable use of your project's Prettier (instead of the system one):
(setq prettier-js-use-modules-bin t)
This uses node_modules/.bin/prettier
. Make sure to run npm install
from your project directory so that the command is available there.
Say that you only want to use Prettier with certain projects. Instead of configuring Emacs with (add-hook 'some-mode-hook 'prettier-js-mode)
, you could check for the presence of a config file:
(defun maybe-use-prettier ()
"Enable `prettier-js-mode' if an rc file is located."
(if (locate-dominating-file default-directory ".prettierrc")
(prettier-js-mode +1)))
(add-hook 'js-mode-hook 'maybe-use-prettier)
Alternatively, say that you want to use Prettier everywhere by default, except for when editing files in certain directories. Use (add-hook 'some-mode-hook 'prettier-js-mode)
, and in directories where you want Prettier disabled, add a .dir-locals.el
file with the following contents:
((nil . ((eval . (prettier-js-mode 0)))))
To adjust the CLI args used for the prettier
command, you can customize the prettier-js-args
variable. This may be useful for controlling specific program behaviors; for instance:
(setq prettier-js-args '("--no-editorconfig"))
While it's possible to control formatting options with flags like --single-quote
, it's usually better to use a configuration file.
web-mode
is a popular mode for editing .js
and .jsx
files, but it is used to edit other template files too. If you want to hook prettier-js-mode
into web-mode
for .js
and .jsx
files only, you can define a helper function like this:
(defun enable-minor-mode (my-pair)
"Enable minor mode if filename match the regexp.
MY-PAIR is a cons cell (regexp . minor-mode)."
(if (buffer-file-name)
(if (string-match (car my-pair) buffer-file-name)
(funcall (cdr my-pair)))))
And then hook into web-mode
like this:
(add-hook 'web-mode-hook #'(lambda ()
(enable-minor-mode
'("\\.jsx?\\'" . prettier-js-mode))))
If you want to mostly eliminate the overhead of running the prettier
command on every file save (improving performance slightly), you could try using prettierd
to run Prettier as a daemon.
(setq prettier-js-command "prettierd")
Note that this may come at the expense of a bit more complexity in terms of configuring/managing the daemon.
M-x prettier-js-prettify
formats the current buffer. Inorg-mode
, it formats all the code blocks in the buffer.M-x prettier-js-prettify-region
formats the current regionM-x prettier-js-prettify-code-block
formats the code block at point (inorg-mode
)
This package is customizable via Emacs' easy customization interface:
M-x customize-group prettier-js
prettier-js-command
is theprettier
executable to useprettier-js-diff-command
is thediff
executable to useprettier-js-args
are the args passed to the prettier commandprettier-js-use-modules-bin
enables use ofnode_modules/.bin/prettier
(your project's Prettier version)prettier-js-show-errors
customizes where to display the error output (buffer
,echo
ornil
)prettier-js-width-mode
customizes the width when formatting buffer contents (window
,fill
ornil
)