Skip to content


Subversion checkout URL

You can clone with
Download ZIP
js2-mode with some improvements
Emacs Lisp
Branch: master
Pull request Compare This branch is 437 commits behind mooz:master.

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


An improved JavaScript mode for GNU Emacs. Forked from


$ git clone git://
$ cd js2-mode
$ emacs --batch --eval '(byte-compile-file "js2-mode.el")'

Then, place js2-mode.elc into your site-lisp directory.

In you emacs config:

(autoload 'js2-mode "js2-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))

See for details.

Differences between original js2-mode.el

Supported more popular indentation style

When js2-consistent-level-indent-inner-bracket-p is non-nil

[foo, bar, baz].forEach(function (v) {
    if (validate(v))

[a, b, c].some(function (v) {
    return validate(v);

When js2-consistent-level-indent-inner-bracket-p is nil (Same as original js2-mode's indentation)

[foo, bar, baz].forEach(function (v) {
                            if (validate(v))

[a, b, c].some(function (v) {
                   return validate(v);

Pretty multi-line variable declaration

In original js2-mode.el,

var foo = 10,
bar = 20,
baz = 30;

In this js2-mode.el, when the value js2-use-ast-for-indentation-p is non-nil (default nil),

var foo = 10,
    bar = 20,
    baz = 30;

Support for abbreviated destructuring assignments

let {a, b}       = {a: 10, b: 20}; // Abbreviated   (Not supported in original js2-mode.el)
let {a: a, b: b} = {a: 10, b: 20}; // Same as above (Supported in original js2-mode.el)

(function ({responseText}) { /* */ })(xhr); // As the argument of function

for (let [k, { name, age }] in Iterator(obj)) // nested
    print(k, name, age);

Support for expression closure in property value

let worker = {
    get age() 20,
    get sex() "male",
    fire: function () _fire()

Fixed odd indentation of "else if" with no braces

In original js2-mode.el,

if (foo)
    return foo;
else if (bar)
return bar;      // here

In this js2-mode.el,

if (foo)
    return foo;
else if (bar)
    return bar;  // fixed

Fixes in Imenu support

Supports element-get form:

foo["bar"] = function() {};
foo[647] = function() {};

Proper position for functions in nested object literals:

foo = {
    bar: function() {}, // ok in original
    baz: {
         boop: function() {} // fixed here

Imenu support for function nesting

Supports one level of nesting:

function foo() {
    function bar() { // shown as
        function baz() {} // hidden

Top-level function can be anonymous wrapper:

(function() {
    var foo = function() {}; // shown as foo

Examples of output:

No support for library-specific extension methods like _.extend.

Highlights undeclared/external variables

Original mode highlights them only on the left side of assignments:

var house;
hose = new House(); // highlights "hose"

Here they are highlighted in all expressions:

function feed(fishes, food) {
    for each (var fish in fshes) { // highlights "fshes"
        food.feed(fsh); // highlights "fsh"
    hood.discard(); // highlights "hood"

Destructuring assignments and array comprehensions (JS 1.7) are supported:

let three, [one, two] = [1, 2];
thee = one + two; // highlights "thee" 

function revenue(goods) {
    // highlights "coast"
    return [price - coast for each ({price, cost} in goods)].reduce(add);


If you find problems, please report them to

Something went wrong with that request. Please try again.