mrkeyoor.com_
Sat 08 Aug 22:51 UTC
npmCLI & Toolingupdated 08 Aug 2026

babylon

babylon is the JavaScript parser Babel 6 used. You give it source text and it returns a Babel-flavoured ESTree AST: a File node wrapping a Program, plus comments and tokens arrays. It handles JSX and Flow through plugins and was, in 2017, the parser with the best coverage of in-flight TC39 proposals. It is also finished. The project moved into the Babel monorepo as @babel/parser in 2018, the repository was archived, and the npm dist-tag still points at 6.18.0 from August 2017. Anything you install today parses the language as it stood at ES2017.

Verdict

babylon is a well-built parser that stopped in August 2017 and became @babel/parser. Keep it only to service Babel 6 code you have not migrated yet; for anything you will still be running next year, install @babel/parser instead.

API stability5/5parse, parseExpression, the options object and the emitted AST have not changed since 6.18.0 shipped in August 2017 and will not change, since the repository is archived. Anything written against it keeps working forever on that syntax subset. The caveat is that the README's own semver note warns spec-compliance fixes could ship in patch releases, which mattered while the project was alive; now there are no releases at all, so the surface is frozen in the strongest sense.
Docs3/5The 6.x README is compact and accurate: both entry points, every option, the plugin list, and an explicit table of how Babel's AST deviates from ESTree with links to the node specs. Two options are documented only as TODO, allowSuperOutsideMethod and strictMode, and there is no guidance on error handling, performance or migration. The AST spec it links to lives in the archived repository, so the practical path today is to read @babel/parser's docs and mentally subtract the newer syntax.
Maintenance1/5The GitHub repository has been archived since May 2018 with a README that says only that the project moved into babel/babel as @babel/parser. The last stable npm publish was 6.18.0 on 2017-08-15, and the newest thing on npm is 7.0.0-beta.47 from May 2018 that never reached stable. Two issues remain open on a read-only repo. Nothing will be fixed here; the same maintainers are active, just under a different package name.
Ecosystem3/5Roughly 5 million weekly downloads, almost all of it Babel 6 era tooling that was never migrated, so this is installed breadth rather than active adoption. The AST format itself is broadly supported: babel-traverse, babel-types and babel-generator from the same generation consume it directly, and the estree plugin bridges to ESTree consumers. What is missing is anything current, since new plugins, editors and codemod tools all target @babel/parser and its newer node types.

Use it if

  • You maintain a Babel 6 toolchain that already depends on babylon and you need to understand or patch what it parses before migrating
  • You are reading or writing a codebase that is frozen at ES2017 syntax and you want a parser whose behaviour will never shift under you
  • You need Babel's AST shape specifically, with StringLiteral and NumericLiteral instead of ESTree's Literal, and ClassMethod instead of MethodDefinition, for tooling written against Babel 6
  • You are tracing why an old build step fails on modern syntax and want to confirm the parser, not the transform, is the thing rejecting the code
Skip it if

Setup reality

npm install babylon gives you a 33 KB gzipped CommonJS module with zero runtime dependencies and a babylon CLI binary. Nothing to configure, no native build. The friction is entirely about what it will and will not accept. Two API entry points exist: parse(code, options) for a whole program and parseExpression(code, options) for a single expression. Options that matter are sourceType ('script' or 'module'), plugins (an array of strings), allowImportExportEverywhere, allowReturnOutsideFunction, sourceFilename and startLine. The default plugin set is empty, so JSX, Flow, class properties, object rest and spread, and dynamic import all fail until you name them. Running 6.18.0 against modern syntax gives a clear picture: async functions and the ** operator parse, but a?.b, a ?? b, 1n, 1_000, try {} catch {}, a ||= b, class A { #x }, import.meta and top-level await all throw SyntaxError. The output is a File node, not a Program node, so ast.program.body is where statements live; ast.comments and ast.tokens are populated by default, which surprises people used to acorn where tokens are opt-in. Error objects carry pos, loc.line and loc.column, so reporting failures is easy. There is one more trap in the version list: npm has 7.0.0-beta.47 published in May 2018, but the latest tag points at 6.18.0, so a range like ^6.18.0 is fine while a wildcard can quietly pick up an abandoned beta. If any of this is annoying, that is the signal to move: @babel/parser is a rename plus plugin-name updates for most callers.

Patterns

Parse ES module sourceparse-a-module

const babylon = require('babylon')

const ast = babylon.parse('import a from "a"; export default a', {
  sourceType: 'module',
})

console.log(ast.type)          // 'File'
console.log(ast.program.type)  // 'Program'
console.log(ast.program.body.length)

The root is a File node, not Program. Statements live at ast.program.body, which trips up code written for acorn.

Turn on JSX and Flow syntaxenable-jsx-and-flow

const babylon = require('babylon')

const ast = babylon.parse(source, {
  sourceType: 'module',
  plugins: ['jsx', 'flow'],
})

The default plugin list is empty, so <div/> and type aliases are syntax errors until you name the plugins. Both are verified working in 6.18.0.

Parse one expression instead of a programparse-single-expression

const babylon = require('babylon')

const node = babylon.parseExpression('a + b * c')
console.log(node.type) // 'BinaryExpression'

parseExpression skips program-level setup and returns the expression node directly. Use parse() whenever the input might be more than one expression.

Report a parse failure with positionhandle-syntax-errors

const babylon = require('babylon')

try {
  babylon.parse(source, { sourceType: 'module' })
} catch (err) {
  console.error(`${err.message} at ${err.loc.line}:${err.loc.column}`)
  console.error(`char offset ${err.pos}`)
}

Errors carry pos and loc. The message already includes a position suffix, so printing both duplicates it unless you strip the suffix first.

Confirm which modern syntax it rejectsdetect-unsupported-syntax

const babylon = require('babylon')

for (const src of ['a?.b', 'a ?? b', '1n', '1_000', 'try{}catch{}', 'a ||= b', 'class A{#x=1}', 'await x']) {
  try {
    babylon.parse(src, { sourceType: 'module' })
    console.log('OK  ', src)
  } catch (e) {
    console.log('FAIL', src, e.message)
  }
}

Every one of those fails on 6.18.0. If your source has any of it, no option or plugin helps; you need @babel/parser.

Enable the proposal plugins it does haveopt-into-proposals

const babylon = require('babylon')

const ast = babylon.parse(source, {
  sourceType: 'module',
  plugins: [
    'classProperties',
    'objectRestSpread',
    'dynamicImport',
    'asyncGenerators',
  ],
})

class A { x = 1 }, ({...a}) and import('x') all parse only with these on. The decorators plugin tracks an outdated proposal and produces nodes current tools will not recognise.

Use the comments and tokens it already collectedread-comments-and-tokens

const babylon = require('babylon')

const ast = babylon.parse('// note\nconst x = 1', { sourceType: 'module' })

console.log(ast.comments.map((c) => c.type)) // [ 'CommentLine' ]
console.log(ast.tokens.length)

Both arrays are populated by default with no option to request them, unlike acorn. That costs time and memory on large files you only wanted an AST for.

Get an ESTree-shaped AST for other toolsestree-compatible-output

const babylon = require('babylon')

const ast = babylon.parse(source, {
  sourceType: 'module',
  plugins: ['estree'],
})
// Literal instead of StringLiteral/NumericLiteral,
// Property instead of ObjectProperty/ObjectMethod

Add estree when feeding escodegen or eslint-style consumers. Babel's own babel-traverse and babel-types expect the deviations, so do not mix the two in one pipeline.

Parse code that breaks the usual rulesparse-script-fragments

const babylon = require('babylon')

const ast = babylon.parse(snippet, {
  allowReturnOutsideFunction: true,
  allowImportExportEverywhere: true,
  sourceFilename: 'inline.js',
  startLine: 42,
})

startLine and sourceFilename make error positions line up with the host file when you extract snippets out of templates or markdown.

Avoid the abandoned 7.0.0 betaspin-away-from-beta

// package.json
{
  "dependencies": {
    "babylon": "^6.18.0"
  }
}
// npm dist-tag latest is 6.18.0;
// 7.0.0-beta.47 (May 2018) exists but never shipped stable

A caret on 6.18.0 stays inside the 6.x line. A wildcard or a "next" tag can drag in a beta that was abandoned mid-migration.

Dump an AST from the shellcli-parse

npx babylon@6.18.0 --plugins jsx,flow src/component.js > ast.json

The package ships a babylon binary. It is useful for one-off inspection; it has no watch mode and no pretty-printing beyond raw JSON.

Move to the package this becamemigrate-to-babel-parser

// npm uninstall babylon && npm install @babel/parser

-const babylon = require('babylon')
-const ast = babylon.parse(code, { plugins: ['objectRestSpread'] })

+const parser = require('@babel/parser')
+const ast = parser.parse(code, { plugins: ['jsx'] })
// object rest/spread and dynamic import are now standard, no plugin needed

parse and parseExpression keep their signatures. The work is dropping plugin names that became standard syntax and renaming ones Babel 7 changed.

Alternatives

PackageRegistryPick it when
@babel/parsernpmYou want this exact parser and AST shape, still released, with current syntax support; this is where the project moved in 2018
acornnpmYou want a small, fast, plain ESTree parser and do not need Babel's node types or its proposal plugins
espreenpmYou are building on eslint's parser contract and want the AST that eslint rules already expect
meriyahnpmYou want an ESTree parser tuned for speed and are willing to trade a smaller ecosystem for it