sveltejs/svelte · error · Error

'svelte/compiler' no longer exports a `walk` utility — pleas

Error message

'svelte/compiler' no longer exports a `walk` utility — please import it directly from 'estree-walker' instead

What it means

Svelte 5 removed the `walk` AST traversal utility that was previously exported from `svelte/compiler`. The export is kept only as a stub that throws unconditionally on call, so legacy imports fail loudly instead of silently breaking. The replacement is the identical API from the `estree-walker` package, which Svelte itself uses internally.

Source

Thrown at packages/svelte/src/compiler/index.js:196

}

/**
 * Remove the byte order mark from a string if it's present since it would mess with our template generation logic
 * @param {string} source
 */
function remove_bom(source) {
	if (source.charCodeAt(0) === 0xfeff) {
		return source.slice(1);
	}
	return source;
}

/**
 * @deprecated Replace this with `import { walk } from 'estree-walker'`
 * @returns {never}
 */
export function walk() {
	throw new Error(
		`'svelte/compiler' no longer exports a \`walk\` utility — please import it directly from 'estree-walker' instead`
	);
}

export { VERSION } from '../version.js';
export { migrate } from './migrate/index.js';

View on GitHub (pinned to 20b341f100)

Solutions

  1. Change the import to `import { walk } from 'estree-walker'` — the signature and behavior are compatible.
  2. Add `estree-walker` to your project's dependencies if it is not already present (it is a transitive dep, so pin it explicitly for stability).
  3. Run a repo-wide search for `from 'svelte/compiler'` usages of `walk` and update each call site.
  4. If you depend on Svelte-flavored walking (e.g. the `node`/`context` visitor shape from zimmerframe), use `import { walk } from 'zimmerframe'` instead, which is what Svelte's own migrate step uses.

Example fix

// before
import { walk } from 'svelte/compiler';
walk(ast, { enter(node) {} });

// after (plain estree traversal)
import { walk } from 'estree-walker';
walk(ast, { enter(node) {} });

// or, for Svelte-style visitors
import { walk } from 'zimmerframe';
walk(ast, state, { Identifier(node, { state }) {} });
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on the import, check whether the export is the deprecated stub.
import * as compiler from 'svelte/compiler';
if (typeof compiler.walk === 'function' && compiler.walk.toString().includes("'estree-walker'")) {
  // walk is the throwing stub — do not call it
  throw new Error('svelte/compiler walk is removed; import from estree-walker instead');
}

Type guard

// Narrow an imported symbol to a usable walker before calling.
import * as compiler from 'svelte/compiler';

/** @returns {compiler.walk is (ast: unknown, visitor: object) => void} */
function isUsableWalk(fn) {
  return typeof fn === 'function' && !fn.toString().includes("'estree-walker'");
}

if (isUsableWalk(compiler.walk)) {
  compiler.walk(ast, visitor);
} else {
  throw new Error('Use estree-walker directly');
}

Prevention

When it happens

Trigger: Calling `import { walk } from 'svelte/compiler'` and then invoking it. The throw happens the moment the function body executes — there is no DEV guard or condition. Code that imports the symbol but never calls it will not throw.

Common situations: Upgrading a project from Svelte 4 (or earlier) to Svelte 5 where tooling, plugins, ESLint rules, or custom preprocessors import `walk` from `svelte/compiler`. Codemods and AST analyzers written against the old export are the most common source.

Related errors


AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12). Data as JSON: /api/errors/eb9ae8b9f9ef72e3. Report an issue: GitHub.