esbuild-plugin-react-virtualized
An esbuild plugin that patches a broken import in react-virtualized so bundlers don't choke on it.
Repository Health
Technical Analysis
esbuild-plugin-react-virtualized is a narrowly scoped esbuild plugin that fixes a long-standing bundling error in react-virtualized, where the compiled WindowScroller/utils/onScroll.js file imports a named export, bpfrpt_proptype_WindowScroller, that does not actually exist in the sibling module it’s imported from. Without a workaround, esbuild (and anything built on top of it, including Vite) fails the build with a “No matching export” error the moment react-virtualized is pulled into the dependency graph.
The plugin hooks into esbuild’s onLoad lifecycle, matches the one broken file by a path regex, reads its contents, and strips the offending import statement with a targeted string replacement before the file continues through the rest of the build pipeline. It ships as a single default export that drops straight into esbuild’s plugins array or into Vite’s optimizeDeps.esbuildOptions.plugins, with no configuration required.
What You Get
- A drop-in esbuild plugin — a single default export you add to esbuild’s plugins array
- Vite compatibility via optimizeDeps.esbuildOptions.plugins
- An automatic patch of react-virtualized’s onScroll.js file applied at build time, with no manual patch-package step to maintain
- Dual ESM/CJS build output (dist/index.mjs, dist/index.cjs) with matching TypeScript type declarations
Common Use Cases
- Fixing “No matching export” build errors when bundling a project that still depends on the unmaintained react-virtualized library with esbuild
- Unblocking Vite dev servers and production builds that pull in react-virtualized transitively through another UI library
- Replacing a manual patch-package or postinstall sed script previously used to work around the same react-virtualized bug
- Keeping a legacy codebase on react-virtualized building cleanly under a modern esbuild/Vite toolchain while a migration to react-window or another list-virtualization library is planned
Under The Hood
Architecture The entire plugin is a single file, src/index.ts, exporting one esbuild Plugin object with a single onLoad hook. There is no internal module structure, no shared state, and no configuration surface — the design is appropriately minimal for a single-purpose bundler patch: a filter regex narrows the hook to exactly one file (WindowScroller/utils/onScroll.js, matched with both forward- and back-slash path separators for Windows compatibility), the file is read from disk, a second regex strips the one broken import line, and the patched contents are handed back to esbuild. Nothing else in the build is touched, and there is no code path that could affect unrelated files.
Tech Stack Written in TypeScript against the esbuild Plugin type, declared as esbuild’s sole peer dependency. The project builds with tsdown into dual ESM (.mjs) and CommonJS (.cjs) bundles with matching .d.mts/.d.cts declarations, targeting ES2020 under strict TypeScript settings (strict: true, noUnusedLocals: true). Tooling is modern and lightweight: pnpm for package management, Biome for linting and formatting, Husky plus lint-staged for pre-commit checks, and release-please driving a GitHub Actions release/publish pipeline that publishes to npm with provenance.
Code Quality There are no test files anywhere in the repository, despite a GitHub Actions workflow literally named “Test” — that workflow only runs pnpm tsc (typecheck), pnpm lint (Biome), and pnpm build, with no unit or integration test step. Type safety comes from TypeScript’s strict mode rather than from any executed test suite. The single source file is short, clearly named, and easy to read in isolation, but the complete absence of automated tests means a regression in the regex or filter logic would only surface once a consumer’s build broke.
API Design The developer experience is deliberately frictionless: consumers import one default export and add it to esbuild’s or Vite’s plugins array with zero configuration options to learn. The README documents both the raw esbuild usage and the Vite optimizeDeps integration directly, so there is essentially no ramp-up beyond copying a two-line snippet. The tradeoff for that simplicity is that the plugin encodes one specific fix for one specific react-virtualized version quirk rather than exposing any generalized patching capability.