New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

ember-estree

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ember-estree

ESTree generator for gjs and gts file used by ember

npmnpm
Version
0.6.11
Version published
Weekly downloads
77K
-24.67%
Maintainers
1
Weekly downloads
 
Created
Source

ember-estree

ESTree-compatible AST parser for Ember's .gjs and .gts files.

Parses <template> tags into Glimmer AST nodes that are embedded directly in the ESTree, so tools like linters and codemods can work with both the JavaScript/TypeScript and template portions of a single file.

Install

pnpm add ember-estree

Usage

Parsing

toTree returns a File node whose .program is a standard ESTree Program, with any <template> regions represented as Glimmer* AST nodes.

import { toTree } from "ember-estree";

let ast = toTree(`
  import Component from "@glimmer/component";

  export default class Demo extends Component {
    <template>Hello, {{this.name}}!</template>
  }
`);

console.log(ast.type); // "File"
console.log(ast.program.body.length); // 2 — ImportDeclaration + ClassDeclaration

parse is a lower-level alternative that returns the Program node directly.

import { parse } from "ember-estree";

let program = parse(`const x = <template>hi</template>;`);
console.log(program.type); // "Program"

Printing

print converts an AST node (ESTree or Glimmer) back to source code.

import { print } from "ember-estree";

print({ type: "Identifier", name: "foo" });
// => "foo"

print({
  type: "GlimmerTemplate",
  body: [{ type: "GlimmerTextNode", chars: "Hello" }],
});
// => "<template>Hello</template>"

print also accepts the File node returned by toTree, printing the whole program with file.comments woven back into the output (each comment is emitted before the nearest node that follows it in the original source). Placement is approximate — a trailing same-line comment becomes a leading comment of the next node — so pair the output with a formatter (e.g. prettier) when exact layout matters.

import { toTree, print } from "ember-estree";

let tree = toTree(`// greet the user\nlet greeting = "hello";`);

print(tree);
// => '// greet the user\nlet greeting = "hello";'

Options

Both toTree and parse accept an options object as their second argument.

All options are optional.

OptionTypeDescription
filePathstringUsed for language detection.
tokensbooleanGenerate a flat ast.tokens array. Required by ESLint; skipped by default so codemods and type-checkers pay nothing.
templateOnlybooleanParse the source as a raw Glimmer template. Use for .hbs files.
parser(placeholderJS: string) => { ast, ... }Use a custom JS/TS parser instead of the default oxc-parser. See Custom parser.
visitorsVisitorMap
or (outerAst) => VisitorMap
Callbacks fired on every node during traversal — JS/TS and Glimmer — in a single pass. See Visitors.

Handler signature is (node, path) => void, where path = { node, parent, parentPath } — a linked list that walks all the way back through the JS/TS root, so visitors can locate the enclosing scope or class from within a Glimmer subtree.

Token stream

Pass tokens: true to populate ast.tokens with a flat, position-sorted array of lexemes spanning the full file — including Glimmer tokens spliced in place of each <template> region. This is what ESLint's SourceCode needs; omit it for codemods or type-checkers that don't use the token stream.

import { toTree } from "ember-estree";

const result = toTree(source, {
  tokens: true,
  parser: myTsParser,
});
// result.ast.program.tokens now contains JS + Glimmer tokens in source order

For .hbs files via templateOnly, pass both flags:

toTree(hbsSource, { templateOnly: true, tokens: true });

Custom parser

Pass any JS/TS parser that returns an ESTree-compatible AST. ember-estree handles template splicing and Glimmer traversal on top of it.

import { parseSync } from "oxc-parser";
import { toTree } from "ember-estree";

const result = toTree(source, {
  parser: (js) => ({
    ast: parseSync("input.ts", js).program,
    visitorKeys: {
      /* ...parser's visitor keys... */
    },
  }),
});

The parser receives a placeholder-JS string (templates replaced with backtick expressions of equal length) and must return at least { ast }. Additional fields like scopeManager, visitorKeys, or services are preserved on the returned result.

Visitors

Pass visitors to observe or rewrite the tree in a single traversal. Handlers fire on both outer JS/TS nodes and spliced Glimmer subtrees, and a single node is never dispatched twice — safe to relocate nodes mid-walk.

The pseudo-type GlimmerBlockParams fires on any node that carries a blockParams array.

Plain-object form — use when you only need the type → handler map:

import { toTree } from "ember-estree";

const identifiers = [];
toTree(source, {
  visitors: {
    Identifier: (node) => identifiers.push(node.name),
    GlimmerPathExpression: (node) => identifiers.push(node.original),
  },
});

Factory form — use when you need the outer JS/TS AST up front (for example, to attach state to it before the walk):

import { toTree, print } from "ember-estree";

const ast = toTree(`const world = "🌍"; const X = <template>{{world}}</template>;`, {
  visitors: () => ({
    Identifier: (node) => (node.name = node.name.toUpperCase()),
    GlimmerPathExpression(node) {
      node.original = node.original.toUpperCase();
      if (node.head) node.head.name = node.original;
    },
  }),
});

print(ast.program);
// => 'const WORLD = "🌍";\nconst X = <template>{{WORLD}}</template>;'

Collecting Glimmer comments into program.comments — useful when adapting the AST for ESLint, which reads comments from the Program node:

const ast = toTree(source, {
  visitors: (outerAst) => {
    outerAst.program.comments = [...(outerAst.comments ?? [])];
    const push = (node) => outerAst.program.comments.push(node);
    return {
      GlimmerCommentStatement: push,
      GlimmerMustacheCommentStatement: push,
    };
  },
});

Removing nodes mid-traversal — siblings are splice-safe:

toTree(source, {
  visitors: () => ({
    GlimmerMustacheCommentStatement(node, path) {
      const siblings = path.parent?.body ?? path.parent?.children;
      const idx = siblings?.indexOf(node) ?? -1;
      if (idx >= 0) siblings.splice(idx, 1);
    },
  }),
});

Examples

The examples/ directory contains ready-to-run integrations:

ExampleDescription
eslint-parserCustom ESLint parser that understands <template>
zmodCodemod toolkit using zmod

AST node reference

Every AST node ember-estree may emit (171 total) — grouped by which files they appear in

Generated from oxc-parser's and @glimmer/syntax's visitor-key maps. Re-run node scripts/generate-ast-node-reference.mjs after bumping either dependency to keep this in sync.

Core ESTree — in .gjs and .gts (76 nodes)

Standard JavaScript node types. Present in both .gjs and .gts — TypeScript is a superset of JavaScript, so .gts files may contain all of these too.

NodeChild keys
AccessorPropertydecorators, key, typeAnnotation, value
ArrayExpressionelements
ArrayPatterndecorators, elements, typeAnnotation
ArrowFunctionExpressiontypeParameters, params, returnType, body
AssignmentExpressionleft, right
AssignmentPatterndecorators, left, right, typeAnnotation
AwaitExpressionargument
BinaryExpressionleft, right
BlockStatementbody
BreakStatementlabel
CallExpressioncallee, typeArguments, arguments
CatchClauseparam, body
ChainExpressionexpression
ClassBodybody
ClassDeclarationdecorators, id, typeParameters, superClass, superTypeArguments, implements, body
ClassExpressiondecorators, id, typeParameters, superClass, superTypeArguments, implements, body
ConditionalExpressiontest, consequent, alternate
ContinueStatementlabel
DebuggerStatement(leaf)
Decoratorexpression
DoWhileStatementbody, test
EmptyStatement(leaf)
ExportAllDeclarationexported, source, attributes
ExportDefaultDeclarationdeclaration
ExportNamedDeclarationdeclaration, specifiers, source, attributes
ExportSpecifierlocal, exported
ExpressionStatementexpression
ForInStatementleft, right, body
ForOfStatementleft, right, body
ForStatementinit, test, update, body
FunctionDeclarationid, typeParameters, params, returnType, body
FunctionExpressionid, typeParameters, params, returnType, body
Identifierdecorators, typeAnnotation
IfStatementtest, consequent, alternate
ImportAttributekey, value
ImportDeclarationspecifiers, source, attributes
ImportDefaultSpecifierlocal
ImportExpressionsource, options
ImportNamespaceSpecifierlocal
ImportSpecifierimported, local
LabeledStatementlabel, body
Literal(leaf)
LogicalExpressionleft, right
MemberExpressionobject, property
MetaPropertymeta, property
MethodDefinitiondecorators, key, value
NewExpressioncallee, typeArguments, arguments
ObjectExpressionproperties
ObjectPatterndecorators, properties, typeAnnotation
ParenthesizedExpressionexpression
PrivateIdentifier(leaf)
Programbody
Propertykey, value
PropertyDefinitiondecorators, key, typeAnnotation, value
RestElementdecorators, argument, typeAnnotation
ReturnStatementargument
SequenceExpressionexpressions
SpreadElementargument
StaticBlockbody
Super(leaf)
SwitchCasetest, consequent
SwitchStatementdiscriminant, cases
TaggedTemplateExpressiontag, typeArguments, quasi
TemplateElement(leaf)
TemplateLiteralquasis, expressions
ThisExpression(leaf)
ThrowStatementargument
TryStatementblock, handler, finalizer
UnaryExpressionargument
UpdateExpressionargument
V8IntrinsicExpressionname, arguments
VariableDeclarationdeclarations
VariableDeclaratorid, init
WhileStatementtest, body
WithStatementobject, body
YieldExpressionargument
TypeScript — .gts only (74 nodes)

TypeScript-specific nodes. Can only appear in .gts files.

NodeChild keys
TSAbstractAccessorPropertydecorators, key, typeAnnotation
TSAbstractMethodDefinitionkey, value
TSAbstractPropertyDefinitiondecorators, key, typeAnnotation
TSAnyKeyword(leaf)
TSArrayTypeelementType
TSAsExpressionexpression, typeAnnotation
TSBigIntKeyword(leaf)
TSBooleanKeyword(leaf)
TSCallSignatureDeclarationtypeParameters, params, returnType
TSClassImplementsexpression, typeArguments
TSConditionalTypecheckType, extendsType, trueType, falseType
TSConstructorTypetypeParameters, params, returnType
TSConstructSignatureDeclarationtypeParameters, params, returnType
TSDeclareFunctionid, typeParameters, params, returnType, body
TSEmptyBodyFunctionExpressionid, typeParameters, params, returnType
TSEnumBodymembers
TSEnumDeclarationid, body
TSEnumMemberid, initializer
TSExportAssignmentexpression
TSExternalModuleReferenceexpression
TSFunctionTypetypeParameters, params, returnType
TSImportEqualsDeclarationid, moduleReference
TSImportTypesource, options, qualifier, typeArguments
TSIndexedAccessTypeobjectType, indexType
TSIndexSignatureparameters, typeAnnotation
TSInferTypetypeParameter
TSInstantiationExpressionexpression, typeArguments
TSInterfaceBodybody
TSInterfaceDeclarationid, typeParameters, extends, body
TSInterfaceHeritageexpression, typeArguments
TSIntersectionTypetypes
TSIntrinsicKeyword(leaf)
TSJSDocNonNullableTypetypeAnnotation
TSJSDocNullableTypetypeAnnotation
TSJSDocUnknownType(leaf)
TSLiteralTypeliteral
TSMappedTypekey, constraint, nameType, typeAnnotation
TSMethodSignaturekey, typeParameters, params, returnType
TSModuleBlockbody
TSModuleDeclarationid, body
TSNamedTupleMemberlabel, elementType
TSNamespaceExportDeclarationid
TSNeverKeyword(leaf)
TSNonNullExpressionexpression
TSNullKeyword(leaf)
TSNumberKeyword(leaf)
TSObjectKeyword(leaf)
TSOptionalTypetypeAnnotation
TSParameterPropertydecorators, parameter
TSParenthesizedTypetypeAnnotation
TSPropertySignaturekey, typeAnnotation
TSQualifiedNameleft, right
TSRestTypetypeAnnotation
TSSatisfiesExpressionexpression, typeAnnotation
TSStringKeyword(leaf)
TSSymbolKeyword(leaf)
TSTemplateLiteralTypequasis, types
TSThisType(leaf)
TSTupleTypeelementTypes
TSTypeAliasDeclarationid, typeParameters, typeAnnotation
TSTypeAnnotationtypeAnnotation
TSTypeAssertiontypeAnnotation, expression
TSTypeLiteralmembers
TSTypeOperatortypeAnnotation
TSTypeParametername, constraint, default
TSTypeParameterDeclarationparams
TSTypeParameterInstantiationparams
TSTypePredicateparameterName, typeAnnotation
TSTypeQueryexprName, typeArguments
TSTypeReferencetypeName, typeArguments
TSUndefinedKeyword(leaf)
TSUnionTypetypes
TSUnknownKeyword(leaf)
TSVoidKeyword(leaf)
Glimmer template — in .gjs and .gts (21 nodes)

Nodes produced inside <template>...</template> regions by @glimmer/syntax, prefixed with Glimmer when spliced into the ESTree.

NodeChild keys
GlimmerAttrNodevalue
GlimmerBlockbody
GlimmerBlockStatementpath, params, hash, program, inverse
GlimmerBooleanLiteral(leaf)
GlimmerCommentStatement(leaf)
GlimmerConcatStatementparts
GlimmerElementModifierStatementpath, params, hash
GlimmerElementNodeattributes, modifiers, children, comments, blockParamNodes, parts
GlimmerHashpairs
GlimmerHashPairvalue
GlimmerMustacheCommentStatement(leaf)
GlimmerMustacheStatementpath, params, hash
GlimmerNullLiteral(leaf)
GlimmerNumberLiteral(leaf)
GlimmerPathExpression(leaf)
GlimmerProgrambody, blockParamNodes
GlimmerStringLiteral(leaf)
GlimmerSubExpressionpath, params, hash
GlimmerTemplatebody
GlimmerTextNode(leaf)
GlimmerUndefinedLiteral(leaf)

License

MIT

Keywords

AST

FAQs

Package last updated on 12 Jul 2026

Related posts