Open-source project
airbnb/javascript avatar
airbnb/javascript

airbnb javascript style guide: the rules live on master, the lint lives in packages/

GitHub describes it as JavaScript Style Guide. The repository metadata lists JavaScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

148,287 stars26,561 forksJavaScriptMIT

At a glance

What is it?
airbnb/javascript is a prose style guide that ships two ESLint configs as npm packages, and the two halves have drifted apart in an interesting way: the rules are a moving document with no releases, while the build system lints its own markdown and installs the config packages from a nested preinstall step. It is most useful read next to the ESLint rule name attached to each rule.
Who is it for?
Use this guide when you want Airbnb conventions with the ESLint rule name attached to each one, and you are already on Babel with polyfills. Do not treat the document as a versioned standard, because the repository has no releases and the last push was on 2026-04-16, so a rule you quote in review can change under you.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 166 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The opening note assumes Babel, a preset and polyfills

The first thing the document says is a set of preconditions. It assumes you are using Babel, requires that you use babel-preset-airbnb or the equivalent, and assumes you are installing shims and polyfills in your app with airbnb-browser-shims or the equivalent. Everything that follows, from the arrow function sections to destructuring, is written inside that assumption.

There is no branch for a project without that toolchain. If you are on TypeScript with a different transpiler, or on a build that does not ship polyfills, the guide gives you no reduced version, and you are left deciding rule by rule which ones survive translation. Consequence: adopting the guide wholesale is only coherent if you adopt the toolchain it names, and a team that only wants the conventions has to do that filtering itself.

Symbols and bigint are the two types it tells you not to polyfill

The Types section splits values into primitives and complex types, and every rule in the document follows from which one you are holding. Primitives are string, number, boolean, null, undefined, symbol and bigint; object, array and function are complex, meaning you hold a reference rather than a value.

Buried under the primitive list is the exception that matters most in practice: symbols and BigInts cannot be faithfully polyfilled, so they should not be used when targeting browsers or environments that do not support them natively. That sits awkwardly next to the opening note about installing polyfills, because the shims package covers everything else the guide assumes and cannot cover these two. Consequence: your browser support list, not the style guide, decides whether those two types are available, and the guide hands you that decision without telling you how to make it.

const everywhere, let only on reassignment, and the scope difference

The References section is the part of the guide most often quoted, and it is three rules. Use const for all references and avoid var, enforced by the ESLint rules prefer-const and no-const-assign. If you must reassign a reference, use let instead of var, enforced by no-var. And note that both let and const are block-scoped, whereas var is function-scoped.

That last point is the one with a runtime consequence, and the guide shows it rather than asserting it:

javascript
{
  let a = 1;
  const b = 1;
  var c = 1;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError
console.log(c); // Prints 1

Consequence: converting a legacy function-scoped var to a block-scoped let changes which code can see the binding, so a mechanical var to let pass is a behaviour change and not only a style change. The ESLint rule name is what makes that pass reviewable.

npm test lints the README before it touches a config

The build system for this repository is documented in its own package.json, and the order of operations is unusual. A pretest hook runs the lint script, and that script is markdownlint pointed at prose:

json
  "scripts": {
    "preinstall": "npm run install:config && npm run install:config:base",
    "pretest": "npm run --silent lint",
    "lint": "markdownlint --config linters/.markdownlint.json README.md */README.md",
    "test:config": "cd packages/eslint-config-airbnb; npm test"
  },

So the first gate a contributor hits is a markdown rule, not a JavaScript rule, and it covers README.md plus the README of each subdirectory. The test step itself then changes directory into packages/eslint-config-airbnb and into the base package to run their tests. Consequence: the rules in react/ and css-in-javascript/ are prose checked by markdownlint, not configs covered by that test, so a React style change passes CI without a config test behind it.

preinstall reaches into packages/ and runs a nested npm install

The same file starts its lifecycle with a preinstall that runs two install steps, and each one changes directory into a subpackage and runs npm prune followed by npm install inside it. A postinstall then removes a nested markdownlint copy from node_modules with rimraf, which is a workaround rather than a version constraint.

This is a repository from an era when npm workspaces were not the default, and the shape shows: the root is a driver, the real artifacts are the two directories under packages/. Consequence: any package manager that hoists or isolates dependencies will disagree with this arrangement, and a contributor who installs with a different tool gets a tree that does not match what the scripts assume. Treat the root install as part of the repository, not as a convenience wrapper.

No releases, no changelog, and a document that is still being amended

The repository has no GitHub releases, and package.json carries version 2.0.0 for a package named airbnb-style whose description is A mostly reasonable approach to JavaScript. That version is the repository's own, not a version of the rules. The last push to the master branch was on 2026-04-16.

The document handles change the only way it can, through a table of contents entry called Amendments, and through the fact that every rule sits under a numbered anchor such as 1.1, 2.3 or 3.4. Consequence: there is no release to pin and no changelog to diff, so a rule number quoted in a code review or a wiki elsewhere can quietly mean something different a few months later. If you cite a rule, cite the ESLint rule name beside it, since prefer-const, no-var and no-new-object are versioned with the linter rather than with the prose.

Two documents answer to the name Airbnb style guide

The guide points at its siblings in one short list. ES5 is marked Deprecated and lives on its own branch at the es5-deprecated path, while React and CSS-in-JavaScript sit in directories of the same repository, and CSS & Sass and Ruby are separate repositories. The current document is the one carrying the ES 2015+ section.

That arrangement is convenient for the authors and awkward for a reader who arrives with a search result and no context. Consequence: a snippet attributed to the Airbnb style guide can come from the deprecated ES5 branch, from the React guide, or from the current document, and those three do not always agree on, for instance, how a function is declared. Check which document and which branch a rule comes from before you make your team follow it, and prefer the ESLint config package, which is installed and pinned, over a copied snippet.

Editorial conclusion

Use this guide when you want Airbnb conventions with the ESLint rule name attached to each one, and you are already on Babel with polyfills. Do not treat the document as a versioned standard, because the repository has no releases and the last push was on 2026-04-16, so a rule you quote in review can change under you. Verify three things first: which npm package you need, eslint-config-airbnb or eslint-config-airbnb-base, whether your target browsers support symbols and bigint, and which document you are citing, since the ES5 guide is marked deprecated on its own branch.

Frequently asked questions

How do I install the Airbnb JavaScript style guide as a linter?

The project publishes two npm packages, eslint-config-airbnb and eslint-config-airbnb-base, and both have their own directory under packages/ in the repository. Installing the repository root triggers a preinstall that runs npm prune and npm install inside each of those two packages.

Does the Airbnb JavaScript style guide require Babel?

The note at the top of the document says it assumes you are using Babel, requires babel-preset-airbnb or the equivalent, and assumes you install shims and polyfills with airbnb-browser-shims or the equivalent. No reduced version of the rules is offered for projects without that setup.

Which Airbnb style guide should I read, the ES5 one or the current one?

ES5 is marked Deprecated and lives on its own branch, while the current document is the one with the ECMAScript 6+ section, alongside separate React and CSS-in-JavaScript guides in the same repository. React and CSS & Sass also have their own guides, the latter in a different repository.

What does npm test check in the Airbnb style guide repository?

A pretest hook runs the lint script first, and that script is markdownlint configured by linters/.markdownlint.json, pointed at README.md and the README in each subdirectory. The test step then runs the tests of packages/eslint-config-airbnb and packages/eslint-config-airbnb-base in turn.

Official sources

  1. Official README
  2. Project repository