Setting up Emacs

as a Javascript


environment for

Fun or Profit

I’ve been doing a lot of Javascript lately, which has naturally led to a whole lot of trips down the .emacs rabbit-hole

So, here are the steps you need to turn OOTB Emacs into the perfect environment for working on Javascript:



First up, you’re going to want decent auto-completion, so install the straightforwardly named auto-complete-mode. Due to some mode-name aliasing that goes on in the Emacs23 javascript mode, You’ll need to make sure it can find the relevant Javascript dictionary so

cd path/to/auto-complete/dict
ln -s javascript-mode js-mode

and then add to your .emacs:

(add-to-list 'load-path "~/path-to/auto-complete")
; Load the default configuration
(require 'auto-complete-config)
; Make sure we can find the dictionaries
(add-to-list 'ac-dictionary-directories "~/emacs/auto-complete/dict")
; Use dictionaries by default
(setq-default ac-sources (add-to-list 'ac-sources 'ac-source-dictionary))
(global-auto-complete-mode t)
; Start auto-completion after 2 characters of a word
(setq ac-auto-start 2)
; case sensitivity is important when finding matches
(setq ac-ignore-case nil)

You now have auto-completion for all variable names in all open Javascript buffers, as well as for standard syntax words (setTimeout, parseInt, onFocus etc).


Not content with that, we’ll also want some kind of intelligent snippet package right – how many times do you really want to type all those semicolons and curly braces? Once is good for me.

The excellent Yasnippet provides this (check out the youtube demo if you’ve not come across it before)

Once you’ve got that downloaded and installed, you’ll want some Javascript snippets to load in, the ones I use, for standard Javascript and jQuery can be downloaded from here, and then the directory provided by that tarfile needs to go in yasnippet/snippets/text-mode

So for our .emacs:

(add-to-list 'load-path "~/path/to/yasnippet")
;; Load the library
(require 'yasnippet)
;; Load the snippet files themselves
(yas/load-directory "~/path/to/yasnippet/snippets/text-mode")
;; Let's have snippets in the auto-complete dropdown
(add-to-list 'ac-sources 'ac-source-yasnippet)

Syntax Checking


One of the problems with Javascript programming is that the feedback loop for syntax errors is *slow* – if you’re working with the web you have to wait for a whole pageload. So we’ll want on-the-fly error checking.

Kevin Turner originally wrote Lintnode, which runs a lighthweight node.js server that passes your file to Douglas Crockford’s JSLint to integrate with Flymake – the Emacs solution for on-the-fly syntax checking. The fork I’m currently maintaining at Github contains some enhancements such as automatic initialization and JSLint options passed from Emacs that the original has yet to merge in. Given that JSLint frequently complains about things that you might like it to er, not complain about, the ability to change the options with the lintnode-jslint-excludes variable makes this far more useable.


Install node.js and npm (The package manager for node)

Get lintnode and the dependencies

git clone
cd lintnode
npm install express connect-form haml underscore

Then we need this in our .emacs:

(add-to-list 'load-path "~/path/to/lintnode")
(require 'flymake-jslint)
;; Make sure we can find the lintnode executable
(setq lintnode-location "~/path/to/lintnode")
;; JSLint can be... opinionated
(setq lintnode-jslint-excludes (list 'nomen 'undef 'plusplus 'onevar 'white))
;; Start the server when we first open a js file and start checking
(add-hook 'js-mode-hook
          (lambda ()

Syntax errors will now be given a red background without having to leave the comfort of Emacs.

Even better, if we install the Flymake Cursor package, we get the error message in the minibuffer when the cursor is on a line with an error.

Easy Mistake!

Get the source from and then add to your .emacs:

(add-to-list 'load-path "~/emacs/minor-modes")
;; Nice Flymake minibuffer messages
(require 'flymake-cursor)


As Jesse and Magnar point out in the comments, it’s probably a better idea to not exclude ‘undef from the jslint errors, but rather to declare global variables at the top of your .js file

 /*global $ */

This way you can let jslint know about other libraries you are using, but still get the checks for undefined variables in your own code.

Code folding

Underscore outline

Especially if you’re dealing with large projects, the ability to hide portions of code can be great for maintaining focus. Emacs comes with this built in, but you have to enable it, so returning to our .emacs:

(add-hook 'js-mode-hook
          (lambda ()
            ;; Scan the file for nested code blocks
            ;; Activate the folding mode
            (hs-minor-mode t)))

This means that when your cursor is in the function…

var Foo = 42;
addFoo = function(num){
    // Let's add the meaning of life to
    // our `num` - it'll be fun!
    var meaningful;
    meaningful = num + Foo;

… and you M-x hs-hide-block, the function turns into:

Var Foo = 42;
addFoo = function(num){...};

To my taste the default keybinding of C-c @ C-h to hide blocks is somewhat perverse, so I’d recommend this in your .emacs:

;; Show-hide
(global-set-key (kbd "") 'hs-show-block)
(global-set-key (kbd "") 'hs-show-all)
(global-set-key (kbd "") 'hs-hide-block)
(global-set-key (kbd "") 'hs-hide-all)


Javascript Console

Having a REPL for the language you’re working with close to hand is basically required for me to enjoy working with it. Now that we’ve installed node.js, though, we can have us a Javascript console inside Emacs with js-comint

Once you’ve grabbed the file, your .emacs should have:

(add-to-list 'load-path "~/path/to/js-comint")
(require 'js-comint)
;; Use node as our repl
(setq inferior-js-program-command "node")
(setq inferior-js-mode-hook
      (lambda ()
        ;; We like nice colors
        ;; Deal with some prompt nonsense
        (add-to-list 'comint-preoutput-filter-functions
                     (lambda (output)
                       (replace-regexp-in-string ".*1G\.\.\..*5G" "..."
                     (replace-regexp-in-string ".*1G.*3G" ">" output))))

You can then run a Javascript REPL with M-x run-js and also send portions of files by selecting them and then running M-x send-region. Neat.

By way of conclusion

There are a few other tweaks that make my Javascripting just that little bit nicer, but they’re more personal Emacs setup than anything specific to Javascript. So, there you have it, the perfect Javascript editing environment.

Love regards etc

Tags: , , , , , , , ,

81 Responses to “Setting up Emacs as a Javascript editing environment for Fun or Profit”

  1. Thanks for this. That setup for js-comint is going to be particularly handy.

  2. Tom Davey says:

    Wow, awesome. What a great tutorial. You are a graceful and lucid writer.

    Curious: why not use Yegge’s js2-mode or the older Javascript major modes?

    Thanks again for this,
    Tom Davey

    • david miller says:

      @Tom js2 has some great features, but I tend to use Emacs 23’s built in js-mode (The natural successor to the old espresso-mode)…
      js2 never really got indentation right. only thing that’s even usable is the bouncing indentation setup, which overrides TAB & means that I can’t then use default Yasnippet keys for expansion…
      It’s also really, really big for an editing mode – not sure I really want a recursive-descent parser running every 3 seconds when I’m editing a js file on a remote server over ssh :)
      I keep meaning to pull a bunch of the better smallish features out of it and bind them with hooks but haven’t gotten around to it

      • Jeanne says:

        I love how they turned out, and what a fun memory of the rainy day! It will always make it stand out and that much more special. Yea for you (and them) being fliebxle!

  3. bob says:

    Pleased with myself – finally set up most everything :)
    Thanks for the guide.

    One thing though…

    If I’m wrapping a script in jquery’s “$(document).ready()” then lintnode, understandably, flags the error:
    “$.” is not defined.
    Fair enough… $ really hasn’t been defined yet.

    Is there a way that we can lintnode or flymake to not flag the error?

    • david miller says:

      Yeah, that can come up a lot – if you’re using this version of lintnode then you can pass the –exclude option to turn off specific JSLint warnings [1] – so you’d want –exclude undef.

      You can set these from within Emacs – I use this in my ~/.emacs

      (setq lintnode-jslint-excludes (list ‘nomen ‘undef ‘plusplus ‘onevar ‘white))


    • Jesse Proulx says:

      At the top of your JS files you can add a comment that JSLint will read for option switches and variables declared outside of your script, like so:

      /*jslint browser: true */
      /*global $,console */

      • david miller says:


        I didn’t know about the /*global */ directive – thanks!

        Edited the post to suggest this :)

        • Uri says:

          Both jslint and jshint support rc files you can keep in your projects, and thus avoid adding these indicators in source files. e.g. .jslintrc or .jshintrc

  4. thorarinn says:

    Pardon my ignorance, but I can’t seem to get the syntax-checking part to work properly: I’ve set up node as well as your fork of Lintnode, using the same settings in my .emacs, but when I run flymake-start-syntax-check on my js files, it’s all red. I’m using jQuery, but shouldn’t that be ok if I exclude undef in the .emacs setup like you did?

    This seems like such a cool addition to my js dev setup that I really want to make it click :)

  5. thorarinn says:

    … and thanks a lot for the guide!

  6. tortuga says:

    Great blog!
    Really thanks for sharing this post! : )
    You make me set up a great emacs js env. in few minutes!

    a small note: You didn’t yank your latest “))”
    to close your (setq inferior-js-mode-hook
    and > has replaced the >

    Bye and still thanks,

  7. Jesse Proulx says:

    An alternative to lintnode is to run a standalone version of V8, like so:

    This removes the overhead of running a node server application just for syntax checking, but still has the speed of the node.js internal engine.

  8. Murph says:

    Are you not bothered by the way js-mode indents inlined var declarations? eg

    var foo = {},
    bar = ”,

    Kinda sucks… and not only that, but even if you manually space the variables, the syntax highlighting doesn’t recognize them.

    I found a bug report on the emacs list for this issue from April, but nothing else. I’m new to emacs and have no idea how to fix it, other than to switch to the modified js2-mode, which I don’t want to do.

    Great guide, though. I tried getting js-comint working with Node yesterday and failed. It was invoking the REPL but not sending the region. Going to follow the guide step by step and see if I can fix it. Thanks

    • Murph says:

      So following up myself, when I set up the Node REPL, I get some functionality but it continues to be buggy. If I write a function and highlight it and run M-x js-send-region, I get ‘…’ printed from Node. Likewise if I place the pointer after that function and do M-x js-send-last-sexp. Does anyone else have these problems?

      • Murph says:

        Testing it some more, it seems like js-send-region only works for me if the region is one line. Otherwise it seems the region does not get read into the Node REPL and the REPL prints out ‘…’ . Would love a fix; being able to use inferior shells is one of the major reasons I’m trying to switch to Emacs.

        • GraemeA says:

          I’ve been looking at this – my impression is that some multiline functions work Ok with js-send-region, but it seems that blank lines confuse it.

          Also, embedded tab character in the region causes problems.

          I’m working on overriding comint-input-sender to strip out the problematic characters (this seems to be the approved way of altering input to comint) – no success yet.

        • Jaxon says:

          I love the conitmaibon of colors! I have never been able to make the splatter manicure work for me… The polish doesn't seem to cover the end of the straw correctly even when I dip it in the bottle :( x

      • Kenisha says:

        How could any of this be better stated? It conl’udt.

    • david miller says:

      >> other than to switch to the modified js2-mode, which I don’t want to do.
      Quite :)

      Was planning on looking into modifying indent behaviour to fix a bug in another project of mine, once I’ve figured out how that works, I may see if I can pull some of those indentation/highlighting bits out as a mode-hook.

      • Letitia says:

        (5.) Értsd = lehet,hogy a helyi posta "települt" kis (anno) és árusított ezt- azt. (stb.) Volt egy homályos fotóm – (függöny mögött volt a tábla – ?) – valamilyen pályázati pénzt is "kaptak"- (leányvásárra) 507 038 Ft-ot (1812 €-t ) – **o**********************************H*gy "dolgozzunk is" : ma (kedd) 15.50. órakor (?) a Pécs Tv bemutatja Kismányoky K. filmjét a Bauhausról – (pécsi épületekrÅ‘l)Pontosítandó! Most meg megnézem az idÅ‘járást ! (majd szétesik a ház…) (széltérkép)

    • Amelia says:

      Ah, i see. Well tha’ts not too tricky at all!”

  9. Luca Lenardi says:

    Hi! And first of all thanks a lot for this wonderful (and useful) post.

    Just an open question: did you came up with something for in-emacs documentation? It could be something like pylookup for the emacs python environment. Probably the point is getting the documentation in the correct format. Any idea?

  10. Jan Gloser says:

    Thanks a lot, man.

  11. basementdad says:

    Hi, in your $.get and $.post snippets are errors. They contain a “}” too much before the semicolon. Except that, thanks for the snippets. Awesome stuff.

    • david miller says:

      Thanks for the heads-up – in practice I tend not to use $.get & $.post very often – updated the tarball to fix that though

  12. Srinivas Y says:

    how did you resolve the tab conflict in both autocomplete and yasnippet.

    autocomplete works fine but snippet doesn’t work. am i missing something here. When i type fun and hit tab it auto-completes to function rather than expanding the snippet.

    btw thanks for the superb article…helped me setting up my emacs.

  13. wvxvw says:

    Something quick. This might be new feature, but you would want to update it, probably. I was following your explanation and found that I also must provide some values to lintnode-jslint-set otherwise node server will not launch from flymake-jslint.

    • janders says:

      I had the exact same issue — lintnode-jslint-set must be a string, not nil. Once I set it to “”, node started. However, I now have the following error that I’m trying to track down:

      Flymake: Configuration error has occured while running (curl –form source=<test_flymake.js –form filename=test_flymake.js –proxy Flymake will be switched OFF

      I thought maybe the less than symbol in "source=< …" was the issue, but removing it in the code didn't help.

      I also noted that if I open my browser and go to the server responds with: Cannot GET /jslint

      – JA

  14. […] Setting up Emacs as a Javascript editing environment for Fun or Profit « Deadpan Sincerity […]

  15. Marius says:

    Thanks for a great article!

    I wondered about one thing: Have you managed to combine comint and js-mode, to get auto-completion (and syntax highlighting) in the interpreter?

    • Jeana says:

      Sì, vabbé… ma esiste anche la resbnosapilità. Se un personaggio come un ministro della pubblica istruzione come la Moratti o un direttore di giornale come Ferrara fanno certe porcherie, riportarlo è dovere di informazione, o forse per apparire apolitici si dovrebbero censurare queste cose?

  16. Fantastic web page. Many helpful tips here. I am submitting the idea to a few pals ans as well revealing around delicious. And definitely, thank you on your hard work!

  17. […] todo esto tendremos Emacs listo para programar JavaScript. Por cierto, en esta web encontré gran parte de la información necesaria para escribir este […]

  18. ari says:

    Thanks for the fantastic article. I’ve been able to get some of it working but have run into some trouble getting flymake up.

    After following your directions, I try to visit a .js file and get the following:

    File mode specification error: (file-error “Searching for program” “no such file or directory” “node”)

    If I add the .nvm directory where node lives to my load-path I then get the following error:

    Flymake: Configuration error has occurred while running (curl –form source=<pendingAccounts.test_flymake.js –form filename=pendingAccounts.test_flymake.js –proxy Flymake will be switched OFF.

    (where pendingAccounts.test.js is the name of the file I'm trying to visit).

    For what it's worth, for the next moth or so we'll still be on node 0.6.21

    I've started tracking this down (in pauses at work – it'll take a bit) but I wanted to post where I'm at in case it helps someone or if the solution is known.

    And thanks again! Viva emacs!

  19. ari says:

    Oh snap. I think it has to do with the ancient version of node we’re using here at the ol’ office: 0.6.21

    I’ma give up for a while and let the browser tell me when I typo.. We’re supposed to upgrade soon.

  20. kuchnia says:

    magnificent put up, very informative. I wonder why the other specialists of
    this sector don’t realize this. You must continue your writing.
    I’m confident, you have a great readers’ base already!

  21. Article Source: Daniels is a master trout angler and author, living and trout fishing in the
    Mountain West – the heart of trophy trout country.

    To keep your campsite free from them, here are good tips to follow:.

    Scenes like this early morning scape may be welcoming to several individuals who seek the relaxation of one of the world’s oldest sports: fishing.

  22. endado says:

    You understand therefore significantly in the case of this topic, produced me in my view consider it from a lot of numerous angles. Its like women and men don’t seem to be involved unless it is something to do with Girl gaga! Your own stuffs outstanding. All the time care for it up!

  23. Tɦe brand is high bbay led light… Donald high bay led lights.

  24. This dust can enter the house with the air and cause illness and aggravate any dust related allergies.
    Household products such as vegetable oil and castile soap can be combined
    with vinegar to clean wood decks naturally as
    well. your family, especially children, your friends, your pets and yourself.

    Feel free to surf to my webpage – certified Long Island Stair installer []

  25. Kiyoko says:

    I see a lot of interesting posts on your page.
    You have to spend a lot of time writing, i know how to save
    you a lot of work, there is a tool that creates unique, google
    friendly posts in couple of minutes, just search in google – laranita’s free
    content source

  26. I loved as much as you’ll receive carried out right here.
    The sketch is tasteful, your authored material stylish. nonetheless, you command get got an nervousness over that you wish
    be delivering the following. unwell unquestionably come more
    formerly again since exactly the same nearly a lot often inside case you shield this hike.

    Check out my homepage … oklejanie samochodów

  27. endado says:

    Hello there, You have performed an excellent job. I will definitely digg it and in my opinion suggest to my friends. I’m confident they will be benefited from this web site.

  28. I have been exploring for a little for any high quality articles or
    weblog posts in this kind of area . Exploring in Yahoo I eventually stumbled upon this website.
    Reading this info So i’m glad to exhibit that I’ve an incredibly just right uncanny feeling I found out just what I needed.

    I such a lot definitely will make certain to do not omit this site
    and provides it a look regularly.

  29. Led high bay warehouse lighting

    Setting up Emacs as a Javascript editing environment for Fun or Profit « Deadpan Sincerity

  30. Johnk684 says:

    Very informative blog post.Really thank you! Keep writing. agegefdebcee

  31. Simply want to say your article is as astonishing.
    The clearness on your put up is simply great and i can assume
    you are knowledgeable on this subject. Fine together with your permission allow me to seize your RSS feed
    to stay updated with impending post. Thank you a
    million and please carry on the enjoyable work.

  32. Uggs On Sale says:

    On Sale Ugg Boots lakers season will begin in September and last to October.

  33. I am regular reader, how are you everybody? This piece of writing posted
    at this web page is actually fastidious.

    Look at my page: foggy window repair arlington

  34. This design is spectacular! You definitely know how to keep a readerr entertained.
    Between your wit and your videos, I was almkst
    moved to start my own blog (well, almost…HaHa!) Fantastic job.
    I really loced what you had to say, and more than that, hhow you presented it.
    Too cool!

  35. My experience advertising aguanga is the same level
    of relevancy to the difficulty many corporations and PR sites.
    Find a company with an intent to improve Google’s assessed value of that question is,
    and budget. And this is search engine optimisation initiative.
    Writer’s stats vary based on a specific keyword term for this keyword or long tail

  36. list proxy says:

    This paragraph will assist the internet people for setting
    up new blog or even a weblog from start to end.

  37. Frank says:

    Do you need unlimited content for your blog ? I’m
    sure you spend a lot of time writing content, but you can save it
    for other tasks, just search in google: kelombur’s favorite tool

  38. Hello fantastic blog! Does running a blog such as this require a large amount of work?

    I have very little understanding of programming however I had been hoping to start my
    own blog in the near future. Anyway, if you have any suggestions or tips
    for new blog owners please share. I know this is off subject but I simply needed to ask.

    My homepage spiderman unlimited hack

  39. Kayleigh says:

    Hi admin do you need unlimited articles for your page ?
    What if you could copy article from other sites, make it pass copyscape test and publish
    on your blog – i know the right tool for you, just search in google:
    Ziakdra’s article tool

  40. Very good info. Lucky me I found your website by accident (stumbleupon).

    I’ve book marked it for later!

  41. Tremendous things here. I’m very glad to look your article.
    Thank you so much and I’m looking forward to contact you.

    Will you kindly drop me a e-mail?

  42. This post offers clear idea for the new users of blogging, that in fact how to do blogging.

    • Mina says:

      I was a former commissioner in Delta state. Mr Nwaomuis very correct. All well known cosnismiomers patronize that Giddy place. Even the governors aides are regular visitors to the place. Are they armed robbers?. Actually the man is a corporate liar. Period.

  43. Fine way of telling, and nice article to get information on the
    topic of my presentation focus, which i am going to convey in college.

  44. Buenas, gracias por la informacion , me ha sido de gran utilidad, la compartire !!!Besos!!!!.

    Hola, buenísimo el artículo, muy util, lo compartire.
    Abrazos a todos

    Buenas, gracias por la informacion , me ha sido de gran utilidad, la compartire !!!Abrazos!!!!.

    Muchas gracias por entregar a todos una maravillosa posibilidad como para leer los
    comentarios críticos de este blog.

    Siempre es muy fantástico y asimismo rellena con un montón de diversión para mí
    y mis compañeros de oficina los trabajadores a visitar el weblog
    más de 3 veces a la r
    semana para leer a través de los nuevos consejos que
    has logrado. Y, en verdad, estoy tan de forma frecuente satisfechas con sus ideas creativas atractivas que sirve.

    Ciertas áreas dos de este artículo son indudablemente el más eficiente todo lo que hemos tenido.

    Super-Duper weblog Soy cariñoso él!! Volveremos más tarde a leer
    un tanto más. Hago uso de los feeds También

    Yo sencillamente no podía salir de su lugar ya antes
    de sugerir que me gustó mucho la información frecuente una persona dé para sus visitantes?

    Hmm es cualquier otra persona teniendo inconvenientes con las imágenes en este weblog carga?
    Estoy tratando de averiguar si es un problema en mi final o si es el blog.

    Cualquier respuesta sería valoradísima.

    Como novato, estoy navegando de forma permanente on-line para los artículos que me puede ayudar.


    Temas maravillosos en total, que termina de ganar un nuevo lector.
    ¿Qué podría sugerir sobre su publican que termina
    de crear un puñado de días dentro del pasado?

  45. buenas noches he visto tu post y esta muy bien tus ideas es claramente profesional

  46. Übersetzungsbüro Slowenisch

  47. Vergiss alle kostenpflichtige Vermittlungsagenturen, vergiss auch alle Speed Dating treffen und vor allem hör auf dich vor den Frauen für dumm zu verkaufen.

  48. Imposible encontrar un PC en esta tienda online me he podido hacer
    una pequeñisima idea

  49. For your “Javascript Console” part, You are MISSING one closing parentheses in your lisp code!
    More specifisic, you missed one closing parentheses in the following code snippet:
    (replace-regexp-in-string “.*1G\.\.\..*5G” “…”

Leave a Reply