Skip to content

Instantly share code, notes, and snippets.

@CodyReichert
Last active September 26, 2023 05:56
Show Gist options
  • Save CodyReichert/9dbc8bd2a104780b64891d8736682cea to your computer and use it in GitHub Desktop.
Save CodyReichert/9dbc8bd2a104780b64891d8736682cea to your computer and use it in GitHub Desktop.
Configuring Emacs for react, es6, and flow

Configuring Emacs for react, es6, and flow

For a while, JSX and new es6 syntax had flaky support in emacs, but there's been huge work on a lot of packages. Using emacs for JavaScript with React, ES6, and Flow (or Typescript, etc) is really easy and powerful in Emacs these days.

This is how you can work on modern web development projects with full support for tooling like JSX, Flow types, live eslint errors, automatic prettier.js formatting, and more.

Set up web-mode

web-mode provides most of the underlying functionality, so a huge shout-out to the maintainer(s) there.

Install web-mode:

M-x package-install RET web-mode RET

Activate web-mode when editing .js and .js files:

(add-to-list 'auto-mode-alist '("\\.jsx?$" . web-mode)) ;; auto-enable for .js/.jsx files

web-mode supports Flow types out-of-the-box, so no additional configuration is required.

JSX syntax highlighting

To enable JSX syntax highlighting in .js/.jsx files, add this to your emacs configuration:

(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))

Indentation and other settings

Configure indentation and any other preferences in the web-mode-init-hook:

(defun web-mode-init-hook ()
  "Hooks for Web mode.  Adjust indent."
  (setq web-mode-markup-indent-offset 4))
  
(add-hook 'web-mode-hook  'web-mode-init-hook)

Live eslint errors

flycheck can be used to show eslint errors in the current buffer.

Install flycheck-mode:

M-x package-install RET flycheck RET`

Require flycheck before the next block:

(require 'flycheck)

Disable the default jslint:

(setq-default flycheck-disabled-checkers
              (append flycheck-disabled-checkers
                      '(javascript-jshint json-jsonlist)))

Using a global eslint

Enable eslint checker when web-mode is activated:

;; Enable eslint checker for web-mode
(flycheck-add-mode 'javascript-eslint 'web-mode)
;; Enable flycheck globally
(add-hook 'after-init-hook #'global-flycheck-mode)

Using a local eslint from node_modules

To use eslint and a config file from a project's local node_modules, use the following:

Install add-node-modules-path:

M-x package-install RET add-node-modules-path RET
(add-hook 'flycheck-mode-hook 'add-node-modules-path)

Prettier.js automatic formatting

You can enable prettier.js to automatically format your files every time you save:

Install pretter-js-mode:

M-x package-install RET prettier-js-mode RET

Install the add-node-modules-path so you don't need a global prettier:

M-x package-install RET add-node-modules-path RET

Enable prettier-js-mode for files in a project with prettier (this will use the projects .prettierrc):

(defun web-mode-init-prettier-hook ()
  (add-node-modules-path)
  (prettier-js-mode))

(add-hook 'web-mode-hook  'web-mode-init-prettier-hook)

Emmet HTML tag expansion

If you like emmett mode from other editors, you can use it in emacs too:

Install emmit-mode:

M-x package-install RET emmet-mode RET

Enable emmet-mode with web-mode:

(add-hook 'web-mode-hook  'emmet-mode)

And that's it, now Emacs is set up to edit all your JS/ES6/React/Flow or whatever files!

:: Cody Reichert

@coetry
Copy link

coetry commented Nov 7, 2018

thank you for this!

@chuckis
Copy link

chuckis commented Jan 2, 2019

thanks!

@andreyshuster
Copy link

Thank you!

@vnctaing
Copy link

Is this a typo

(defun web-mode-init-prettier-hook ()
  (add-node-modules-path)
  (prettier-js-mode))

(add-hook 'web-mode-hook  'web-mode-init-hook)

shouldn't be

(defun web-mode-init-prettier-hook ()
  (add-node-modules-path)
  (prettier-js-mode))

(add-hook 'web-mode-hook  'web-mode-init-prettier-hook)

Copy link

ghost commented Apr 21, 2019

Add (js2-minor-mode) to web-mode-hook very good!

(defun web-mode-init-hook ()
  ...
  (add-node-modules-path)
  (prettier-js-mode)
  (js2-minor-mode)
  (emmet-mode))
(add-hook 'web-mode-hook  'web-mode-init-hook)

@fselcukcan
Copy link

I cannot find flycheck-mode. There is flycheck is it same?
Also after installing in with the flycheck-mode My emacs cannot start without complaining about .eamcs file errors about flycheck related symbols' values. What am I doing wrong here?

@rwilson4
Copy link

rwilson4 commented Jul 7, 2019

@fselcukcan: I needed to require the flycheck mode before setting the variable:

(require 'flycheck-color-mode-line)
(setq-default flycheck-disabled-checkers
              (append flycheck-disabled-checkers
                      '(javascript-jshint json-jsonlist)))

https://stackoverflow.com/questions/25512527/emacs-symbols-value-as-variable-is-void

@CodyReichert
Copy link
Author

CodyReichert commented Jul 11, 2019

I cannot find flycheck-mode. There is flycheck is it same?

Correct, just flycheck is the right one. @fselcukcan

I needed to require the flycheck mode before setting the variable:

@rwilson4 - thank you, I updated the gist.

@MMaicki
Copy link

MMaicki commented Aug 29, 2019

I have done everything step by step just as you wrote but i get following error :

File is missing: Cannot open load file, No such file or directory, flycheck

My init file looks like this after changes.

(add-to-list 'auto-mode-alist '("\\.jsx?$" . web-mode)) ;; auto-enable for .js/.jsx files
(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))

(require 'flycheck)

(setq-default flycheck-disabled-checkers
              (append flycheck-disabled-checkers
                      '(javascript-jshint json-jsonlist)))
(add-hook 'flycheck-mode-hook 'add-node-modules-path)
(add-hook 'web-mode-hook  'emmet-mode)

And it seems that whole JS syntax highlighting is broken now, i use Spacemacs btw.

@sunilw
Copy link

sunilw commented Jan 4, 2020

(defun web-mode-init-hook ()
...
(add-node-modules-path)
(prettier-js-mode)
(js2-minor-mode)
(emmet-mode))
(add-hook 'web-mode-hook 'web-mode-init-hook)

What should be in the place of the '...'?

@CodyReichert
Copy link
Author

File is missing: Cannot open load file, No such file or directory, flycheck

@MMaicki - hmm, do you have the flycheck package installed? M-x package-install -> Enter -> flycheck?

@sunilw - I think they just meant you can keep any other configuration options for web-mode in that block. like indent-offset

@MMaicki
Copy link

MMaicki commented Mar 19, 2020

@CodyReichert I've totally forgot about this... 😄

@evinasgu
Copy link

Great gist! Thx! :)

@t829702
Copy link

t829702 commented Feb 11, 2021

how do you set js-indent-offset to 2 ?

@a1l8e9x
Copy link

a1l8e9x commented May 6, 2021

how do you set js-indent-offset to 2 ?
(setq web-mode-code-indent-offset 2)

@2brownc
Copy link

2brownc commented Jun 16, 2022

Cannot find prettier-js-mode on MELPA. Using prettier-js with no issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment