Skip to content

How to Migrate Your Project to Vite+ from Webpack or Vite

The Problem

I stared at my package.json and counted seven different tools:

- nvm for Node.js version management
- npm for package management
- vite for dev server and build
- vitest for testing
- typescript for type checking
- eslint for linting
- prettier for formatting

Each had its own config file. Each had its own command. Each had its own way of breaking at the wrong time.

Then I saw Vite+ announcement. One tool to unify them all. But I hesitated:

“It’s too much.”

That was my first reaction on Reddit. Migration anxiety from years of broken builds and config nightmares. Would switching to Vite+ break my project? How long would it take?

It turned out, for my existing Vite project, the migration was one command. For Webpack projects, it takes a few more steps. Here’s what I learned.

What Vite+ Actually Does

Vite+ unifies the fragmented JavaScript toolchain:

Before Vite+: Fragmented Tools
┌─────────────────────────────────────────────────────┐
│ Your Project │
├─────────────────────────────────────────────────────┤
│ .nvmrc → Node version │
│ package.json → Scripts, dependencies │
│ vite.config.js → Dev server, build │
│ vitest.config.js → Tests │
│ tsconfig.json → Type checking │
│ .eslintrc.js → Linting │
│ .prettierrc → Formatting │
└─────────────────────────────────────────────────────┘
7 tools, 7 configs, 7 sources of problems
After Vite+: Unified Toolchain
┌─────────────────────────────────────────────────────┐
│ Your Project │
├─────────────────────────────────────────────────────┤
│ vite.config.js → All configuration │
│ │
│ vp env → Node version management │
│ vp dev → Development server │
│ vp test → Run tests │
│ vp check → Type checking │
│ vp build → Production build │
│ vp run → Script execution │
└─────────────────────────────────────────────────────┘
1 config, sensible defaults, less cognitive load

The key insight: Vite+ doesn’t replace Vite. It wraps Vite and adds unified tooling. If you already use Vite, you’re 90% there.

Migration Path 1: Existing Vite Projects

This was my situation. I already had a Vite project. The migration was embarrassingly simple:

migrate-vite.sh
# From your existing Vite project root
npx vp install

That’s it. Vite+ auto-detected my package manager (pnpm in my case) and integrated without disruption.

But I was skeptical. I wanted to see what actually changed:

check-changes.sh
git diff

The changes were minimal:

  • Added vite-plus to devDependencies
  • Added vp scripts to package.json
  • Created a backup of my original config

I tested everything still worked:

test-migration.sh
vp dev # Development server - worked
vp build # Production build - worked
vp test # Tests - worked
vp check # Type checking - worked

The whole migration took about 5 minutes, including my paranoid testing.

Migration Path 2: Webpack Projects

My colleague’s project was on Webpack. This required more work. Webpack and Vite have fundamental differences:

AspectWebpackVite
Module systemCommonJS + ESMESM only
Dev serverBundle-basedNative ESM
Config complexityHighLower
Build speedSlowerFaster

Step 1: Install Vite

install-vite.sh
npm install -D vite @vitejs/plugin-react

Replace @vitejs/plugin-react with the appropriate plugin for your framework:

  • Vue: @vitejs/plugin-vue
  • Svelte: @sveltejs/vite-plugin-svelte
  • Vanilla: No plugin needed

Step 2: Move index.html to Root

Webpack often keeps index.html in subdirectories. Vite expects it at the root:

move-html.sh
mv src/index.html ./

Step 3: Update Import Syntax

This was the most time-consuming part. Webpack supports both CommonJS and ESM. Vite requires ESM:

Before (Webpack with CommonJS):

src/utils.js (Webpack)
const lodash = require('lodash')
const config = require('./config')
module.exports = {
formatData: function(data) {
return lodash.map(data, item => item.value)
}
}

After (Vite with ESM):

src/utils.js (Vite)
import lodash from 'lodash'
import config from './config.js' // Note: .js extension required
export function formatData(data) {
return lodash.map(data, item => item.value)
}

Common issues I encountered:

  1. Missing file extensions: Vite requires .js or .ts extensions in imports
  2. require() calls: Must convert to import
  3. module.exports: Must convert to export
  4. Dynamic requires: Need to use import() instead

Step 4: Replace Config Files

Before (webpack.config.js):

webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
devServer: {
port: 3000,
hot: true
}
}

After (vite.config.js):

vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
port: 3000
}
})

The config is simpler because Vite handles most transformations automatically.

Step 5: Add Vite+

Once Vite is working, add Vite+:

add-viteplus.sh
npx vp install

What Changed in package.json

The most visible change is in package.json scripts:

Before (Webpack project):

package.json (Webpack)
{
"scripts": {
"dev": "webpack serve --mode development",
"build": "webpack --mode production",
"test": "jest",
"lint": "eslint src/",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"webpack": "^5.0.0",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.0.0",
"jest": "^29.0.0",
"eslint": "^8.0.0",
"typescript": "^5.0.0"
}
}

After (Vite+ project):

package.json (Vite+)
{
"scripts": {
"dev": "vp dev",
"build": "vp build",
"test": "vp test",
"check": "vp check"
},
"devDependencies": {
"vite-plus": "^1.0.0"
}
}

Four separate commands become one unified interface.

Common Mistakes I Made

Mistake 1: Trying to Migrate Everything at Once

I got ambitious and tried to migrate from Webpack to Vite+ in one shot. Bad idea.

Wrong:

wrong-approach.sh
npm uninstall webpack webpack-cli webpack-dev-server
npm install -D vite-plus
# Everything breaks at once

Right:

right-approach.sh
# Step 1: Webpack → Vite (keep project working)
npm install -D vite @vitejs/plugin-react
# Fix all ESM issues, test thoroughly
# Step 2: Vite → Vite+ (minimal change)
npx vp install
# Test again

Mistake 2: Not Updating Import Paths

Vite requires explicit file extensions for local imports:

Wrong:

src/App.jsx
import Header from './components/Header' // Works in Webpack

Right:

src/App.jsx
import Header from './components/Header.jsx' // Required in Vite

This caught me multiple times. I wrote a script to find and fix them:

fix-imports.sh
# Find imports without extensions
grep -rn "from '\\.\/" src/ | grep -v ".js'" | grep -v ".jsx'"

Mistake 3: Keeping Old Configs

I left webpack.config.js sitting in my project. Later, I couldn’t remember which config was active.

Wrong:

project/
├── webpack.config.js # Which one is active?
├── vite.config.js
└── ...

Right:

cleanup.sh
rm webpack.config.js
rm -rf webpack/ # If you had webpack-specific dirs

Mistake 4: Ignoring Node Version Requirements

Vite+ has specific Node version requirements. I tried running it on an old Node version:

Error: Vite+ requires Node.js 18.0.0 or higher

Instead of manually managing Node versions, I let Vite+ handle it:

node-version.sh
vp env
# Auto-detects and installs/uses correct Node version

Migration Timeline

Here’s how long each phase took me:

For a Vite project (simple migration):

Vite to Vite+ Timeline
Day 1 (30 minutes):
- Run `npx vp install`
- Test all scripts
- Verify build output
- Commit changes

For a Webpack project (full migration):

Webpack to Vite+ Timeline
Week 1: Webpack to Vite
- Day 1-2: Install Vite, create config
- Day 2-3: Convert CommonJS to ESM (most time-consuming)
- Day 3-4: Fix CSS handling differences
- Day 4-5: Test and fix edge cases
Week 2: Vite to Vite+
- Day 1: Run `npx vp install`
- Day 1-2: Test all functionality
- Day 2: Clean up old configs
- Day 3: Final verification

The CommonJS to ESM conversion was 60% of the effort. If your project already uses ESM, migration is much faster.

What About Vue, Svelte, etc.?

The Reddit discussion showed anticipation for Vue support:

“I’m waiting for their tools to properly support Vue”

I tested React and vanilla JS projects successfully. For Vue and Svelte, the Vite part works fine, but Vite+ specific features may have framework-specific quirks. Check the documentation for framework-specific plugins.

Is It Worth It?

After the migration, here’s what changed in my daily workflow:

Before:

Terminal window
nvm use # Switch Node version
npm run dev # Start dev server
npm run test # Run tests (in another terminal)
npm run lint # Check code style
npm run typecheck # Type checking
npm run build # Production build

After:

Terminal window
vp env # Node version handled
vp dev # Dev server
vp test # Tests
vp check # Type checking + linting combined
vp build # Production build

The unified interface reduces cognitive load. I no longer think about which tool does what. I just prefix everything with vp.

Summary

Migrating to Vite+ depends on your starting point:

For existing Vite projects: One command (npx vp install). Five minutes.

For Webpack projects: A two-step process:

  1. Migrate to Vite (ESM conversion, config changes)
  2. Add Vite+ (npx vp install)

The main effort is CommonJS to ESM conversion. Use the incremental approach: migrate to Vite first, verify everything works, then add Vite+.

The unified toolchain reduces the mental overhead of managing multiple build tools. One prefix (vp), one config file, fewer things to remember.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments