Move from Webpack to Vite without the manual config rewrite.
Paste a webpack.config.js and get back a Vite config skeleton, a tiered report (manual, verify, info), and a dependency checklist. It reads your config statically and never runs it, so the boring parts are mapped for you and anything risky is flagged for review. AST-based, not regex.
npm i -D @shiftkit/webpack-to-vite- Mapped: Config translated deterministically.
- Source: No detect-only source traps were surfaced for this config.
- Then: Still run vite build && vite preview once before merging.
Can’t map from config alone. You decide.
Mapped, but behavior may differ. Worth a look.
Bookkeeping. Vite handles it.
Migration checklist
Config translation is the start, not the finish. Work top-down, or skip the file-writing steps with the CLI’s --apply mode (below).
- Save the config. Drop the output above into
vite.config.tsat your project root. - Move to an HTML entry. Vite is HTML-first: create
index.htmlat the root with<script type="module" src="/src/index.tsx">instead of lettingHtmlWebpackPlugingenerate it. - Install dependencies.See the “Required dependencies” block above.
- Migrate env vars. Rename build-time vars to the
VITE_prefix and read them viaimport.meta.envin source (onlyVITE_vars reach the client). - Fix the source traps. Convert
require()/require.context/worker-loaderusages (see below). - Test the build, not just dev. Run
vite build && vite preview. Vite’s build pipeline can differ from the dev server. - Migrate Jest if present. Use the sister tool, Jest → Vitest.
Skip the file steps: --apply
Prefer the terminal? --apply writes the config and a JSON report to disk. It never deletes your webpack config and never mutates package.json:
npx @shiftkit/webpack-to-vite webpack.config.js --apply --out vite.config.tsAdd --strict in CI to fail the build when any manual-review item is emitted, --json for a machine-readable result, or --target-vite 7 for the rollupOptions fallback.
What gets mapped
The analyzer parses your config with Babel rather than regex, so it understands TypeScript, defineConfig() wrappers, identifier re-exports, webpack-merge, and function-form configs (read without executing). A partial mapping table follows. Anything that is not a clean mapping gets a tiered warning instead of a silent guess.
| Webpack | Maps to | Vite | Notes |
|---|---|---|---|
| resolve.alias | → | resolve.alias [{ find, replacement }] | name$ becomes an exact /^name$/ rule |
| babel/ts/css loaders | → | dropped (native) | Vite transpiles & handles CSS; no type-check |
| @svgr/webpack | → | vite-plugin-svgr | import via ./icon.svg?react |
| DefinePlugin | → | define | process.env.* → import.meta.env |
| HtmlWebpackPlugin | → | root index.html | verify: move template, add module script |
| devServer.proxy | → | server.proxy | pathRewrite → rewrite fn |
| output.path / publicPath | → | build.outDir / base | static values only |
| devtool | → | build.sourcemap | source-map / inline / hidden |
Detect-only traps (never auto-rewritten)
These live in your application source, not the config. The analyzer flags them so you migrate them deliberately. It will not rewrite source for you:
require()/module.exports- convert app source to ESM (import/export).require.context()and dynamicimport()with a variable - useimport.meta.glob()with a static glob.process.env.Xin source - migrate toimport.meta.env.VITE_X.worker-loader/new Worker(…)- use the?workerimport suffix ornew Worker(new URL(…), { type: ‘module’ }).module.hot- Vite usesimport.meta.hotwith a similar but distinct API.externalsandModuleFederationPlugin- reviewed by hand; external and federation semantics differ from webpack.
How accurate is the output?
Mappings are deterministic and covered by a fixture suite. The output is a skeletonwith a confidence band and tiered warnings. It never claims source or architecture migration is complete, which is why “Verify before merging” appears even when the config maps cleanly.
FAQ
Does ShiftKit run or upload my webpack config?
No. ShiftKit does not run your webpack config. It parses the config statically in a browser Web Worker (Babel AST, no eval, no new Function, no execution of your config). Your config is never uploaded.
Is this a one-click converter?
No. It is an analyzer. Config translation is only half of a webpack to Vite migration. The risky parts live in your app source (require, process.env, require.context, web workers, Module Federation). The tool emits a Vite 8-oriented vite.config.ts skeleton and a tiered report, and marks everything that needs manual work. It never claims source or architecture migration is done.
Why Vite 8 by default?
Vite 8 is current and ships Rolldown as the unified bundler. The output uses build.rolldownOptions and Vite 8’s built-in resolve.tsconfigPaths. Toggle to Vite 7 to get build.rollupOptions plus the vite-tsconfig-paths plugin instead.
What happens with a function-form config?
The analyzer reads the returned object statically without executing the function. If the config branches on env/argv, it surfaces a manual warning telling you to resolve the conditional config yourself. It never picks a branch for you.
Why a confidence band instead of a percentage?
A percentage would be misleading. Each field either maps cleanly, maps with a caveat, or cannot be mapped from config alone. The band (High confidence / Verify before merging / Manual review required) plus raw counts (e.g. 2 manual · 4 verify · 6 info) tells you exactly what to check before merging.
Can I run this in the terminal or in CI?
Yes. Run "npx @shiftkit/webpack-to-vite webpack.config.js", add --json for a machine-readable result, or --strict to exit non-zero when any manual-review item exists. --apply --out vite.config.ts writes the config plus a JSON report; it never deletes your webpack config and never mutates package.json. A GitHub Action mirrors the flags.
How is the package secured against supply-chain attacks?
Releases publish from GitHub Actions via npm Trusted Publishing (OIDC, no long-lived tokens) with a provenance attestation, so you can verify the tarball was built from the tagged commit. We also recommend "min-release-age=7" in your .npmrc, which blocks freshly-published (and not-yet-caught) malicious versions.
Changelog
Pulled from the package’s CHANGELOG.md at build time. The currently installed version is v0.1.0.
- v0.1.02026-05-31latest
- featVite 8-first Webpack → Vite migration analyzer with a parse → static-eval → intermediate-model → render pipeline. Static AST only, so your webpack config is never executed.
- feat18 fixtures (12 release-gate + module-federation/css-modules/alias-array-value/html-plugin + stretch) with exact tier/code snapshots, flag assertions, valid-TS output checks, a source-level no-eval/no-`new Function` gate, and CLI `--json`/`--strict` tests.