oxc-project/oxc-walker oxc-walker
Version: 0.7.0 (Jan 2026)
Deps: magic-regexp@^0.10.0
Tags: latest: 0.7.0 (Jan 2026)
References: package.json — exports, entry points • README — setup, basic usage • GitHub Issues — bugs, workarounds, edge cases • Releases — changelog, breaking changes, new APIs
Search
Use skilld search instead of grepping .skilld/ directories — hybrid semantic + keyword search across all indexed docs, issues, and releases. If skilld is unavailable, use npx -y skilld search.
skilld search "query" -p oxc-walker
skilld search "issues:error handling" -p oxc-walker
skilld search "releases:deprecated" -p oxc-walker
Filters: docs:, issues:, releases: prefix narrows by source type.
API Changes
This section documents version-specific API changes -- prioritize recent major/minor releases.
NEW: ScopeTrackerVariable -- exported class in v0.7.0, enables instanceof checks on results from scopeTracker.getDeclaration(). Previously internal-only; LLMs will not know these classes are importable source
NEW: ScopeTrackerFunction -- exported class in v0.7.0, represents function declarations tracked by ScopeTracker. Import directly from oxc-walker for type narrowing source
NEW: ScopeTrackerImport -- exported class in v0.7.0, represents import declarations tracked by ScopeTracker. Has .importNode property for accessing the full ImportDeclaration source
NEW: ScopeTrackerFunctionParam -- exported class in v0.7.0, represents function parameters tracked by ScopeTracker. Has .fnNode for accessing the parent function node source
NEW: ScopeTrackerIdentifier -- exported class in v0.7.0, represents plain identifiers (e.g. class/enum names) tracked by ScopeTracker source
NEW: ScopeTrackerCatchParam -- exported class in v0.7.0, represents catch clause parameters tracked by ScopeTracker. Has .catchNode for the parent CatchClause source
NEW: getUndeclaredIdentifiersInFunction(node) -- exported in v0.7.0, returns string[] of identifier names referenced but not declared within a Function or ArrowFunctionExpression node source
NEW: isBindingIdentifier(node, parent) -- exported in v0.7.0, returns boolean indicating whether a node is a binding identifier given its parent context source
DEPRECATED: ScopeTrackerFunctionParam.start -- use .fnNode.start instead. The representation of this position may change in future versions source
DEPRECATED: ScopeTrackerFunctionParam.end -- use .fnNode.end instead. The representation of this position may change in future versions source
NEW: ScopeTrackerNode type -- union type exported in v0.7.0: ScopeTrackerFunctionParam | ScopeTrackerFunction | ScopeTrackerVariable | ScopeTrackerIdentifier | ScopeTrackerImport | ScopeTrackerCatchParam. Use for typing getDeclaration() results source
BREAKING: oxc-parser peer dependency -- v0.6.0 requires oxc-parser v0.98.0+. Older oxc-parser versions are no longer compatible source
Also changed: WalkOptions type exported v0.7.0 · WalkerEnter type exported v0.7.0 · WalkerLeave type exported v0.7.0 · WalkerCallbackContext type exported v0.7.0 · WalkerThisContextEnter type exported v0.7.0 · WalkerThisContextLeave type exported v0.7.0 · Identifier type exported v0.7.0 · ScopeTrackerOptions type exported v0.7.0
Best Practices
- Use regular function expressions (not arrow functions) for
enter/leave callbacks -- this.skip(), this.replace(), and this.remove() are bound via this context and won't work with arrow functions source
// correct
walk(ast, { enter(node) { this.skip() } })
// broken -- this.skip is undefined
walk(ast, { enter: (node) => { this.skip() } })
Use parseAndWalk over separate parseSync + walk when you only need a single pass -- it returns ParseResult (including program) so you can still re-walk the AST if needed later source
For hoisted declaration resolution, use the two-pass pattern: create ScopeTracker({ preserveExitedScopes: true }), run parseAndWalk as a pre-pass to collect all declarations, call scopeTracker.freeze(), then walk(program, { scopeTracker }) for analysis -- without this, getDeclaration() returns null for identifiers declared after their usage in source order source
Do not use this.replace() or this.remove() when a ScopeTracker is attached -- the scope tracker will not update its internal declarations, leaving stale scope data source
this.remove() takes precedence over this.replace() -- if both are called in the same callback, the node is removed regardless of replacement source
this.skip() is only available in enter, not leave, and skipping a node also prevents its leave() callback from firing -- this means ScopeTracker state can become inconsistent if you skip nodes that create scopes source
Type-narrow ScopeTrackerNode using the .type discriminant or instanceof (v0.7.0+) to access parent declaration nodes -- ScopeTrackerVariable exposes .variableNode, ScopeTrackerImport exposes .importNode, ScopeTrackerCatchParam exposes .catchNode, ScopeTrackerFunctionParam exposes .fnNode source
isCurrentScopeUnder(scope) uses strict child checking -- it returns false when the current scope equals the given scope, only true for descendants source
Use getUndeclaredIdentifiersInFunction(node) to find free variables (closures) in a function or arrow function expression -- useful for tree-shaking analysis and determining if a function can be safely hoisted or moved source
ScopeTrackerFunctionParam.start and .end are deprecated -- access the function's position via .fnNode.start and .fnNode.end instead source
1---2name: oxc-walker-skilld3description: ALWAYS use when writing code importing "oxc-walker". Consult for debugging, best practices, or modifying oxc-walker, oxc walker.4---56# oxc-project/oxc-walker `oxc-walker`78**Version:** 0.7.0 (Jan 2026)9**Deps:** magic-regexp@^0.10.010**Tags:** latest: 0.7.0 (Jan 2026)1112**References:** [package.json](./.skilld/pkg/package.json) — exports, entry points • [README](./.skilld/pkg/README.md) — setup, basic usage • [GitHub Issues](./.skilld/issues/_INDEX.md) — bugs, workarounds, edge cases • [Releases](./.skilld/releases/_INDEX.md) — changelog, breaking changes, new APIs1314## Search1516Use `skilld search` instead of grepping `.skilld/` directories — hybrid semantic + keyword search across all indexed docs, issues, and releases. If `skilld` is unavailable, use `npx -y skilld search`.1718```bash19skilld search "query" -p oxc-walker20skilld search "issues:error handling" -p oxc-walker21skilld search "releases:deprecated" -p oxc-walker22```2324Filters: `docs:`, `issues:`, `releases:` prefix narrows by source type.2526## API Changes2728This section documents version-specific API changes -- prioritize recent major/minor releases.2930- NEW: `ScopeTrackerVariable` -- exported class in v0.7.0, enables `instanceof` checks on results from `scopeTracker.getDeclaration()`. Previously internal-only; LLMs will not know these classes are importable [source](./.skilld/releases/v0.7.0.md#features)3132- NEW: `ScopeTrackerFunction` -- exported class in v0.7.0, represents function declarations tracked by `ScopeTracker`. Import directly from `oxc-walker` for type narrowing [source](./.skilld/releases/v0.7.0.md#features)3334- NEW: `ScopeTrackerImport` -- exported class in v0.7.0, represents import declarations tracked by `ScopeTracker`. Has `.importNode` property for accessing the full `ImportDeclaration` [source](./.skilld/releases/v0.7.0.md#features)3536- NEW: `ScopeTrackerFunctionParam` -- exported class in v0.7.0, represents function parameters tracked by `ScopeTracker`. Has `.fnNode` for accessing the parent function node [source](./.skilld/releases/v0.7.0.md#features)3738- NEW: `ScopeTrackerIdentifier` -- exported class in v0.7.0, represents plain identifiers (e.g. class/enum names) tracked by `ScopeTracker` [source](./.skilld/releases/v0.7.0.md#features)3940- NEW: `ScopeTrackerCatchParam` -- exported class in v0.7.0, represents catch clause parameters tracked by `ScopeTracker`. Has `.catchNode` for the parent `CatchClause` [source](./.skilld/releases/v0.7.0.md#features)4142- NEW: `getUndeclaredIdentifiersInFunction(node)` -- exported in v0.7.0, returns `string[]` of identifier names referenced but not declared within a `Function` or `ArrowFunctionExpression` node [source](./.skilld/releases/v0.7.0.md#features)4344- NEW: `isBindingIdentifier(node, parent)` -- exported in v0.7.0, returns `boolean` indicating whether a node is a binding identifier given its parent context [source](./.skilld/releases/v0.7.0.md#features)4546- DEPRECATED: `ScopeTrackerFunctionParam.start` -- use `.fnNode.start` instead. The representation of this position may change in future versions [source](./.skilld/pkg/dist/index.d.ts:L279)4748- DEPRECATED: `ScopeTrackerFunctionParam.end` -- use `.fnNode.end` instead. The representation of this position may change in future versions [source](./.skilld/pkg/dist/index.d.ts:L283)4950- NEW: `ScopeTrackerNode` type -- union type exported in v0.7.0: `ScopeTrackerFunctionParam | ScopeTrackerFunction | ScopeTrackerVariable | ScopeTrackerIdentifier | ScopeTrackerImport | ScopeTrackerCatchParam`. Use for typing `getDeclaration()` results [source](./.skilld/releases/v0.7.0.md#features)5152- BREAKING: `oxc-parser` peer dependency -- v0.6.0 requires `oxc-parser` v0.98.0+. Older oxc-parser versions are no longer compatible [source](./.skilld/releases/v0.6.0.md#features)5354**Also changed:** `WalkOptions` type exported v0.7.0 · `WalkerEnter` type exported v0.7.0 · `WalkerLeave` type exported v0.7.0 · `WalkerCallbackContext` type exported v0.7.0 · `WalkerThisContextEnter` type exported v0.7.0 · `WalkerThisContextLeave` type exported v0.7.0 · `Identifier` type exported v0.7.0 · `ScopeTrackerOptions` type exported v0.7.05556## Best Practices5758- Use regular function expressions (not arrow functions) for `enter`/`leave` callbacks -- `this.skip()`, `this.replace()`, and `this.remove()` are bound via `this` context and won't work with arrow functions [source](./.skilld/pkg/dist/index.d.ts:L88:90)5960```ts61// correct62walk(ast, { enter(node) { this.skip() } })63// broken -- this.skip is undefined64walk(ast, { enter: (node) => { this.skip() } })65```6667- Use `parseAndWalk` over separate `parseSync` + `walk` when you only need a single pass -- it returns `ParseResult` (including `program`) so you can still re-walk the AST if needed later [source](./.skilld/pkg/README.md#parse-and-walk-directly)6869- For hoisted declaration resolution, use the two-pass pattern: create `ScopeTracker({ preserveExitedScopes: true })`, run `parseAndWalk` as a pre-pass to collect all declarations, call `scopeTracker.freeze()`, then `walk(program, { scopeTracker })` for analysis -- without this, `getDeclaration()` returns `null` for identifiers declared after their usage in source order [source](./.skilld/pkg/README.md:L170:203)7071- Do not use `this.replace()` or `this.remove()` when a `ScopeTracker` is attached -- the scope tracker will not update its internal declarations, leaving stale scope data [source](./.skilld/pkg/README.md#thisreplacenewnode)7273- `this.remove()` takes precedence over `this.replace()` -- if both are called in the same callback, the node is removed regardless of replacement [source](./.skilld/pkg/README.md#thisremove)7475- `this.skip()` is only available in `enter`, not `leave`, and skipping a node also prevents its `leave()` callback from firing -- this means ScopeTracker state can become inconsistent if you skip nodes that create scopes [source](./.skilld/issues/issue-106.md)7677- Type-narrow `ScopeTrackerNode` using the `.type` discriminant or `instanceof` (v0.7.0+) to access parent declaration nodes -- `ScopeTrackerVariable` exposes `.variableNode`, `ScopeTrackerImport` exposes `.importNode`, `ScopeTrackerCatchParam` exposes `.catchNode`, `ScopeTrackerFunctionParam` exposes `.fnNode` [source](./.skilld/pkg/dist/index.d.ts:L268:311)7879- `isCurrentScopeUnder(scope)` uses strict child checking -- it returns `false` when the current scope equals the given scope, only `true` for descendants [source](./.skilld/pkg/dist/index.d.ts:L226:236)8081- Use `getUndeclaredIdentifiersInFunction(node)` to find free variables (closures) in a function or arrow function expression -- useful for tree-shaking analysis and determining if a function can be safely hoisted or moved [source](./.skilld/pkg/dist/index.d.ts:L246)8283- `ScopeTrackerFunctionParam.start` and `.end` are deprecated -- access the function's position via `.fnNode.start` and `.fnNode.end` instead [source](./.skilld/pkg/dist/index.d.ts:L277:285)