Hermes Parser
Hermes Parser is a robust JavaScript parser built directly from the Hermes engine's parser, compiled to WebAssembly. This allows for high-performance parsing of JavaScript code in various environments, including Node.js and browsers. As of version 0.35.0, it supports parsing ES6+ syntax, Flow, and JSX. A key differentiator is its ability to output Abstract Syntax Trees (ASTs) in either the standard ESTree format or a Babel-compatible format, offering flexibility for integration into different tooling ecosystems. It also provides fine-grained control over Flow parsing, allowing users to explicitly enable Flow syntax detection or parse all ambiguous syntax as Flow. The project is actively maintained by Facebook, ensuring ongoing development and compatibility with modern JavaScript features.
Common errors
-
SyntaxError: Unexpected token
cause The parser encountered syntax it does not understand, often due to missing configuration for Flow or JSX, or attempting to parse future JavaScript syntax not yet supported.fixCheck `sourceType` (module/script/unambiguous), `flow` (detect/all), and ensure `babel: true` is set if parsing complex JSX or Flow constructions that might require Babel's specific interpretation. -
TypeError: hermes_parser__WEBPACK_IMPORTED_MODULE_0__.parse is not a function
cause This error typically occurs in environments (like Webpack bundles) where CommonJS `require` is used or incorrectly transpiled for an ESM-only package, or when attempting to import a non-existent symbol.fixEnsure you are using `import { parse } from 'hermes-parser';` for ESM environments. Verify that bundler configurations correctly handle ESM modules. If using TypeScript, check for correct `esModuleInterop` settings. -
HermesParserError: A 'return' statement can only be used within a function body
cause You have `return` statements outside of a function, which is typically a syntax error in JavaScript.fixIf this is intentional (e.g., for very specific module formats or transpilation targets), you can suppress this error by passing `{ allowReturnOutsideFunction: true }` in the `parse` options. Otherwise, refactor your code to place `return` statements within functions.
Warnings
- gotcha The `babel` option defaults to `false`, meaning the parser outputs ASTs conforming to the ESTree specification. If you are integrating with tools that expect Babel's specific AST format (e.g., Babel plugins, some linters), you must explicitly set `babel: true` in the parse options.
- gotcha The `flow` option defaults to `"detect"`, which only parses ambiguous syntax as Flow when an `@flow` pragma is present. If you have Flow syntax without a pragma and want it parsed as Flow (e.g., `foo<T>(x)` as a call with type argument), you must set `flow: "all"` in the parse options.
- breaking As a 0.x release package, `hermes-parser` may introduce breaking changes between minor versions (e.g., 0.30.0 to 0.31.0) without adhering strictly to semver for major bumps. Always review release notes when upgrading.
- gotcha The `transformOptions.TransformEnumSyntax` feature, if enabled, defaults to requiring `flow-enums-runtime`. If this transform is used in an environment where `flow-enums-runtime` is not available or you need a different runtime reference, you must provide a custom `getRuntime` function.
Install
-
npm install hermes-parser -
yarn add hermes-parser -
pnpm add hermes-parser
Imports
- parse
const parse = require('hermes-parser');import { parse } from 'hermes-parser'; - ParseOptions
import type { ParseOptions } from 'hermes-parser'; - Node
import type { Node } from 'hermes-parser';
Quickstart
import { parse } from 'hermes-parser';
const codeWithFlowAndJSX = `
// @flow
type User = {
id: string,
name: string,
isAdmin?: boolean,
};
const user: User = { id: '1', name: 'Alice' };
function greet(person: User): React.Element {
return <div>Hello, {person.name}!</div>;
}
const element = greet(user);
`;
// Parse with ESTree format (default) and detect Flow via pragma
const estreeAst = parse(codeWithFlowAndJSX, {
sourceType: 'module',
flow: 'detect',
sourceFilename: 'flow-jsx-example.js',
});
console.log('--- ESTree AST (excerpt) ---');
console.log(JSON.stringify(estreeAst.body[0], null, 2));
// Parse with Babel format and force all Flow parsing
const babelAst = parse(codeWithFlowAndJSX, {
babel: true,
sourceType: 'module',
flow: 'all',
sourceFilename: 'flow-jsx-example.js',
});
console.log('\n--- Babel AST (excerpt) ---');
console.log(JSON.stringify(babelAst.body[0], null, 2));
const simpleCode = `const x = 10;`;
const simpleAstTokens = parse(simpleCode, { tokens: true });
console.log('\n--- Tokens for simple code ---');
console.log(simpleAstTokens.tokens?.map(t => t.value));