As of 31 March 2015 the JavaScript transpiler that used to be called 6to5 becomes Babel and, with the 5.0.0 release, opens a public plugin API: the transformation code, previously wired into the core, now extends from the outside. The official release post documents it. The shift is a clean one: from ES6โ†’ES5 converter to infrastructure for generic syntactic transforms.

Context

ECMAScript 2015 (ES6) is in its final steps: the sixth draft of ECMA-262 is at the candidate stage and the Ecma General Assembly will adopt it in June 2015. The syntactic additions are many โ€” let/const, arrow functions, classes, template literals, destructuring, modules โ€” but the production runtimes, current browsers and the widely deployed Node.js versions, speak ES5. To write ES6 today and run it everywhere, a source-to-source compilation step is needed.

6to5, started in September 2014 by Sebastian McKenzie, covers this case. The name, though, nails the project to a single version transition, and in February 2015 it changes to Babel. The not-born-to-die post (15 February 2015) explains it plainly: with ES6 renamed ECMAScript 2015 and a yearly standardisation cycle on the way, a tool called โ€œ6 to 5โ€ is born with its expiry date already attached. The new aim is to offer a parsing and transformation foundation that other tools can reuse โ€” minifiers, beautifiers, linters, code-coverage tools.

Architecture

Babel works in three stages. The source goes through a parser โ€” a fork of acorn extended to cover ES6+ syntax and JSX โ€” which produces an Abstract Syntax Tree (AST). The tree enters a transform phase, where a visitor walks the nodes and applies the rewrites. At the end a generator serialises the resulting AST into target JavaScript, with the option of pairing it with a source map that traces every position in the generated file back to the line and column of the original source.

The change in 5.0 lies in the middle phase, rewritten and made extensible. A plugin is a function that receives the Babel object and returns a visitor: a set of methods keyed by node type (ArrowFunctionExpression, ClassDeclaration, and so on) that the traversal calls one by one. Inside a visitor you inspect and modify the current node, replace subtrees, insert or remove declarations. The transforms that convert ES6 into ES5 run on the same mechanism opened to external authors; there is no privileged internal lane, separate from the public one.

Above these three stages sits .babelrc, a JSON configuration file that every integration in the project reads in the same way: the require hook babel/register, babel-node, the Webpack loader babel-loader, the Browserify transform babelify. Before 5.0 the configuration had to be repeated at each entry point; with the single file the options โ€” transform presets, active plugins, language stage โ€” sit in one place, at the project root.

Critical point

The releaseโ€™s most debatable design choice concerns experimental proposals. In the 6to5 versions, features not yet standard were enabled through a binary experimental option: all or nothing. 5.0 removes it and adopts the stages of the TC39 process, the five levels (from 0, strawman, to 4, finished) by which the committee classifies the maturity of each proposal.

The trouble is the default: in Babel 5.0 proposals at stage 2 or above are active without explicit configuration. Stage 2 means โ€œdraftโ€ โ€” a proposal with sketched-out semantics, not yet stable, open to breaking changes in later committee rounds. Syntax such as class properties (es7.classProperties), decorators (es7.decorators) and export extensions (es7.exportExtensions) thus ends up inside the default perimeter. Anyone adopting it writes code against a moving specification: a committee move on one of these stages can break the build, and future alignment with whatever syntax may eventually be standardised is not guaranteed. It is a choice that puts early access to features ahead of source stability, and in a production codebase it is one to make knowing what it entails.

Implications

Now that the visitor is exposed, the boundary of what you can do without forking the tool moves. An organisation that wants, say, to rewrite certain function calls automatically, inject instrumentation or forbid some syntactic constructs already at compile time, does so as a plugin loaded via .babelrc, no longer with a patch to the core. The same AST and the same traversal needed to down-level ES6 become available for arbitrary application-level transforms.

There is also a less obvious effect, tied to the change in import hoisting in 5.0: import statements are no longer compiled inline where they appear, but lifted to the top of the module, in line with ES6 module semantics. It is an adjustment to the specification, but it changes execution order relative to the written code: a side effect you expect downstream of an import may now fire before statements that, on the page, precede it. It is worth checking when you upgrade from an earlier 6to5.

Limits

Transpilation resolves syntax, not the runtime. Converting an ES6 class into an ES5 constructor function gives code that runs on an old engine, but methods such as Array.prototype.includes or objects such as Promise and Map belong to the standard library, not the grammar: they do not come out of transforming the AST, and must be supplied separately through a polyfill loaded at runtime. It is worth keeping the two apart โ€” what the transpiler rewrites and what the polyfill adds โ€” so as not to take for granted that transpiled code runs on a browser where, in fact, those library methods are missing.

The cost of the build step remains. Adopting Babel means the executed source is not the written one; source maps stitch debugging back together, but the pipeline has to be maintained, versioned and made reproducible. On projects that run only on already-updated runtimes the gain may not be worth the added complexity โ€” a case-by-case judgement, not a default.


https://babeljs.io/blog/2015/03/31/5.0.0 https://babeljs.io/blog/2015/02/15/not-born-to-die https://babeljs.io/blog/2015/01/12/6to5-esnext https://www.infoq.com/news/2015/02/babel-new-name-for-6to5/ https://262.ecma-international.org/6.0/

Cover image: Babel wordmark logo: the word โ€œbabelโ€ in golden yellow on a transparent background โ€” logo by Henry Zhu, CC BY-SA 4.0 โ€” https://commons.wikimedia.org/wiki/File:Babel_Logo.svg