Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@coetry coetry commented Nov 7, 2018

thank you for this!

@chuckis

This comment has been minimized.

Copy link

@chuckis chuckis commented Jan 2, 2019

thanks!

@andreyshuster

This comment has been minimized.

Copy link

@andreyshuster andreyshuster commented Mar 2, 2019

Thank you!

@vnctaing

This comment has been minimized.

Copy link

@vnctaing vnctaing commented Mar 11, 2019

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)
@ghost

This comment has been minimized.

Copy link

@ghost 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

This comment has been minimized.

Copy link

@fselcukcan fselcukcan commented Jun 2, 2019

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

This comment has been minimized.

Copy link

@rwilson4 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

This comment has been minimized.

Copy link
Owner Author

@CodyReichert 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

This comment has been minimized.

Copy link

@MMaicki 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

This comment has been minimized.

Copy link

@sunilw 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

This comment has been minimized.

Copy link
Owner Author

@CodyReichert CodyReichert commented Mar 19, 2020

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

This comment has been minimized.

Copy link

@MMaicki MMaicki commented Mar 19, 2020

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

@evinasgu

This comment has been minimized.

Copy link

@evinasgu evinasgu commented May 13, 2020

Great gist! Thx! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.