# What changed in es-module-lexer

> 51 changes in es-module-lexer 2 to 3 from its official release notes, upgrade guides and advisories: 11 breaking, 2 security, 8 new APIs and options. Each one cited. Sources checked 2026-10-20. HTML: https://unstale.sh/npm/es-module-lexer/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## es-module-lexer 3

### Breaking changes

- init is now a function, changing how developers use the API. (3.0.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.2)
- This entry point is the asm.js build; the unmaintained pure-JS port is removed. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- New entry point with the v2-shaped API: parse returns only imports and exports, at is dropped, and re-exported imported names are reported in ln/ls/le. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- export default interface Foo now reports Foo as its local name. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Reexports resolve to their originating import regardless of statement order; export * is represented as reexport-all and its import as reexport-star. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Full-build records now use tagged unions discriminated by type, with descriptive fields replacing the terse v2 names and numeric type tags. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- ImportType is now a type-only union of named numeric literal aliases; no runtime enum is exported. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- initSync is no longer exported; parse initializes on first use. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Node.js 18 or later is required. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Invalid escape sequences now throw a parse error instead of yielding undefined. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

### Security

- Module strings decode without eval, improving one-import parse speed and allowing Wasm builds under --disallow-code-generation-from-strings. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Nesting past 1024 brackets or 512 dynamic imports now produces a parse error instead of memory corruption. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

### New APIs and options

- A glob flag is added on dynamic imports. (3.0.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.1)
- A specifier is added on import.meta. (3.0.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.1)
- typeOnly is added on import.meta. (3.0.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.1)
- Dynamic import attributes are typed null; attributesStart locates the options argument. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Dynamic imports carry a best-effort probablyTypeOnly field in full builds. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Full builds lex TypeScript type-only imports, exports, aliases, interfaces, and ambient declarations; type-only edges carry typeOnly. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

### Performance

- Reduces TypeScript lookahead work, improving lexer performance. (3.0.4) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.4)
- Parser wrapper overhead was reduced. (3.0.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.2)
- The full Wasm build uses SIMD scanning for long line comments and templates; the minimal build stays Wasm MVP. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

### Behavior and default changes

- The minimal build enforces Wasm MVP and uses no post-MVP features. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- parse initializes Wasm synchronously on first call; await init is only required on browser main threads, and all four entry points share the parse/init API. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

### Fixes and other changes

- Preserves complete import attribute metadata in parser results. (3.0.4) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.4)
- Lexes `/` after a postfix non-null assertion as division. (3.0.4) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.4)
- Fixes handling of ASI and repeated non-null assertions in TypeScript export bindings. (3.0.3) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.3)
- Handles TypeScript generic commas in exported bindings. (3.0.3) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.3)
- Minimal build reexports report no local name. (3.0.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.1)
- Unannotated declare let/var no longer erases the following statement. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Shorthand declare module no longer erases the following statement. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- A dynamic import with a single template-literal argument reports a glob specifier with each interpolation collapsed to *. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- Typed export binding lists now collect every declarator. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- export { type as } and type as as now follow TypeScript's specifier table. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)
- U+00A0 is treated as whitespace around import/export names. (3.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/3.0.0)

## es-module-lexer 2

### Breaking changes

- Import assertions have been removed. (2.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.0.0)

### New APIs and options

- A minimal build variant is available for es-module-shims. (2.3.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.0)
- The export statement start position is exposed as ss. (2.2.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.2.0)

### Performance

- The lexer skips identifier and number runs, improving lexer performance. (2.3.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.2)
- The lexer gates keywordStart on the next byte for i/c tokens. (2.3.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.1)
- Node uses a fast native UTF-16 source copy into Wasm memory. (2.3.1) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.1)

### Behavior and default changes

- Parsing now supports import attribute items. (2.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.0.0)

### Tooling

- Adds side-effects metadata to package.json, which can inform bundler behavior. (2.3.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.2)

### Fixes and other changes

- The asm.js integer return type annotation is fixed. (2.3.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.2)
- The sourcename is now forwarded through the pre-init parse path. (2.3.2) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.2)
- WebAssembly memory can grow for sources over ~4MB, including in the minimal build. (2.3.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.3.0)
- A method named import with two or more arguments is no longer treated as a dynamic import. (2.2.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.2.0)
- Export var, let, and const declarations now detect every binding. (2.2.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.2.0)
- The n field is now reported for dynamic imports using no-substitution template literals. (2.2.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.2.0)
- Dynamic import attributes are always excluded from the specifier range. (2.1.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.1.0)
- Handles new `of` conflict cases. (2.1.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.1.0)
- A global reference issue has been fixed. (2.0.0) — [release notes](https://github.com/guybedford/es-module-lexer/releases/tag/2.0.0)
