Utilities for traversing and transforming Oxc ESTree-compatible abstract syntax trees.
npm install @jsxtools/oxc-utilsThis package is ESM-only and supports Node.js 20.19 or newer.
Visitor walks an Oxc program depth-first. Add :exit to a node type to run a handler after its children.
import { Visitor } from "@jsxtools/oxc-utils";
const identifiers = [];
const visitor = new Visitor({
Identifier(node) {
identifiers.push(node.name);
},
});
visitor.visit(program);Compose independent rules to run them in one traversal. Handlers for the same phase run in argument order.
const visitor = Visitor.compose(importRule, templateRule, diagnosticsRule);
visitor.visit(program);For lower-level traversal, import walkNode, walkProgram, or a node-specific walker from @jsxtools/oxc-utils/walk.
The AST and visitor APIs are bidirectionally type-compatible with oxc-parser and @oxc-project/types 0.139.0. Traversal matches oxc-parser's JavaScript Visitor enter, child-key, array-element, and exit order for all 165 upstream node types.
This package additionally visits Oxc's Program.hashbang as a Hashbang node before the program body. The exported visitorKeys therefore has 166 node types, with Hashbang as the only addition and hashbang prepended to Program. The visitor-key object and every child-key array are frozen and readonly.
Both visitors benchmarked by this project perform traversal in JavaScript. Handler merging remains CSP-safe for six or more handlers: this package uses a loop rather than dynamically compiling a function.
Extract tagged templates from a program and compile their static parts with unique placeholders before passing them through a text transform.
import {
getCompiledTaggedTemplateLiterals,
hydrateCompiledTaggedTemplateLiterals,
} from "@jsxtools/oxc-utils";
const compiled = getCompiledTaggedTemplateLiterals(program, source, ({ templateIndex, boundaryIndex }) => {
const split = `__template_${templateIndex}_${boundaryIndex}__`;
return { merge: split, split };
});
const hydrated = hydrateCompiledTaggedTemplateLiterals(compiled, (text) => transform(text));Hydration is recoverable: when a transform removes, duplicates, or reorders placeholders, affected parts retain their original text and report a recovery reason.
@jsxtools/oxc-utils— complete public API@jsxtools/oxc-utils/ast— Oxc AST TypeScript definitions@jsxtools/oxc-utils/key— visitor keys by node type@jsxtools/oxc-utils/template-literal— template compilation and hydration@jsxtools/oxc-utils/template-literal-visitor— AST template extraction@jsxtools/oxc-utils/visitor— optimized visitor API@jsxtools/oxc-utils/walk— low-level typed walkers
npm run build— compile JavaScript and declarationsnpm run lint— check source, tests, and configuration with Biomenpm run lint:package— validate the published package with publintnpm run lint:workflow— validate GitHub Actions workflows with actionlintnpm run format:check— check documentation formatting with dprintnpm test— run runtime regression testsnpm run test:types— verify the public TypeScript APInpm run benchmark:visitor— compare local and upstream visitor construction and traversalnpm run check— clean-build and run all tests
The dependency-free benchmark parses one generated 5,000-declaration optional-call-heavy program, validates callback counts, warms each case, alternates local/upstream order, invokes exposed GC between samples, and reports 11-sample medians with median absolute deviation. It separately measures isolated cold import plus first construction, cached construction, empty and hot visitor workloads, and an eight-handler CSP-safe merge stress case. Use npm run benchmark:visitor -- --quick for a correctness-only smoke run; timing ratios never determine its exit status.