Fixing Module Not Found Errors in Vite + React Apps
Next.js gets most of the attention in the vibe coding world, but Vite + React is actually the most common AI-generated SPA stack. Cursor, Lovable, and Bolt.new all default to Vite when you ask for a React app without SSR, because Vite is faster, simpler, and produces cleaner output. But Vite apps suffer from the same missing-dependency problem as Next.js apps: the AI assistant imports packages without adding them to package.json, and the build fails with Module not found: Error: Can't resolve 'clsx'. The error message is slightly different from Next.js, but the root cause is identical. Here is why Vite + React apps fail, how the error differs from Next.js, and how Deployxa's AutoRepairService handles both.
The direct answer is that Vite uses a different build system (esbuild and Rollup) than Next.js (Webpack or Turbopack), but the missing-dependency problem is the same. The LLM writes import clsx from 'clsx' without adding clsx to package.json, and the build fails. The error message is Module not found: Error: Can't resolve 'clsx' in '/app/src/components', which is similar to Next.js's Cannot find module 'clsx' but uses Vite's specific error format. Deployxa's AutoRepairService handles both formats, because the classifier (powered by Gemini 2.5 Flash with a regex fallback) recognizes the common patterns across build systems.
Why Vite + React Is the Default for AI-Generated SPAs
Three reasons explain why AI assistants default to Vite for SPA generation. First, Vite is faster than Create React App (which is deprecated) and Webpack-based setups, which means the LLM's generated dev server starts in under a second, providing a better interactive experience. Second, Vite's configuration is simpler (a single vite.config.ts file with minimal boilerplate), which means the LLM produces cleaner output with fewer configuration errors. Third, Vite's output is a standard static SPA (HTML, CSS, JS in a dist directory), which is easy to deploy to any static hosting provider or container. For vibe coders who want a React app without SSR complexity, Vite is the natural choice.
The trade-off is that Vite apps do not have server-side rendering, which means they are not ideal for SEO-critical content (blogs, marketing pages). For apps where SEO matters, Next.js with SSR is the better choice. For apps where SEO does not matter (dashboards, admin panels, internal tools, SaaS apps behind authentication), Vite is simpler and faster. Deployxa's intelligence service detects whether your app is a static SPA or an SSR app and sizes the container appropriately, which means Vite apps get a smaller, cheaper container by default.
The Module Not Found Error in Vite
The error message in Vite is slightly different from Next.js, but the root cause is the same. Here is what a typical Vite build failure looks like:
vite v5.4.0 building for production...
transforming...
✓ 34 modules transformed.
dist/index.html 0.46 KB │ gzip: 0.30 KB
dist/assets/index-abc123.css 1.23 KB │ gzip: 0.45 KB
dist/assets/index-def456.js 142.67 KB │ gzip: 45.89 KB
Module not found: Error: Can't resolve 'clsx' in '/app/src/components'
at /app/node_modules/vite/dist/node/chunks/dep-abc.js:12345
at /app/src/components/Button.tsx:2The key part is Can't resolve 'clsx', which tells you that the clsx package is not installed. The fix is npm install clsx, but a vibe coder who has never seen this error might not know that. Deployxa's AutoRepairService handles this automatically: it traps the build failure, feeds the stderr to Gemini 2.5 Flash, which identifies clsx as the missing package, injects it into package.json, cleans the lockfile, and retries the build. The second build typically succeeds, and the app is live within 60 to 90 seconds of the first failure.
How the AutoRepairService Handles Vite-Specific Errors
The AutoRepairService's classifier is trained on error patterns from multiple build systems, including Vite, Next.js, Webpack, Rollup, and esbuild. For Vite, the classifier recognizes the following patterns:
- Module not found: Error: Can't resolve '([^']+)' -> missing package
- Failed to resolve import "([^"]+)" -> missing package (Vite's alternative error format)
- [plugin:vite:import-analysis] Module not found -> missing package (Vite plugin error)
For each pattern, the classifier extracts the package name and passes it to the patcher, which adds it to package.json and retries the build. The classifier also handles the case where multiple packages are missing, by extracting all package names from the stderr and adding them in a single patch. This is more efficient than adding one package at a time and retrying, because it reduces the number of build cycles.
Step-by-Step: Deploying a Vite + React App Without Manual Fixes
Here is the exact workflow for a typical Cursor-generated Vite + React app.
Step 1: Create your Vite app
If you do not have one yet, create a new Vite + React app:
npm create vite@latest my-app -- --template react-ts
cd my-app
npm installOr, if you are using Cursor, just describe what you want: "Create a React app with Vite that has a landing page, a pricing section, and a contact form." Cursor will generate the app for you.
Step 2: Push to GitHub
git init
git add .
git commit -m "vite + react app"
git remote add origin https://github.com/yourname/my-app.git
git push -u origin mainStep 3: Connect to Deployxa
In the Deployxa dashboard, connect your repository. Deployxa auto-detects Vite from your package.json and vite.config.ts:
[ingest] Detected Node.js project
[ingest] Framework: vite
[ingest] Runtime: node 20.x
[ingest] Build command: npm run build
[ingest] Output directory: dist
[ingest] Start command: npm run preview (or static file server)Step 4: Deploy and watch the auto-repair loop
Click Deploy. The first build runs. If your AI assistant forgot to add clsx, lucide-react, or any other package to package.json, the build fails, the AutoRepairService kicks in, patches the manifest, and retries. You watch this happen in real time in the build log panel. The second build typically succeeds, and the app is live within 60 to 90 seconds of the first failure.
Step 5: Verify with deployxa doctor
Once the app is live, run deployxa doctor to get a full health check. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.
Step 6: Add a custom domain
Add a custom domain in the Deployxa dashboard. SSL is provisioned automatically via Let's Encrypt.
Common Pitfalls and Troubleshooting
The first pitfall is Vite's base configuration. If your app is served from a subdirectory (e.g., yourapp.com/app/), you need to set base: '/app/' in vite.config.ts. The AutoRepairService does not handle this, because it is a configuration issue, not a missing-dependency issue. The second pitfall is environment variables. Vite uses import.meta.env.VITE_* for client-side environment variables, which are inlined at build time. If you set an environment variable in the Deployxa dashboard after the build, it will not be picked up until the next build. The fix is to trigger a rebuild after setting environment variables. The third pitfall is static asset paths. Vite generates absolute paths for static assets (e.g., /assets/index-abc123.js), which work when the app is served from the root but fail when served from a subdirectory. The fix is to set the base configuration as mentioned above. The fourth pitfall is SPA routing. Vite SPAs use client-side routing (e.g., React Router), which means all routes must fall back to index.html. Deployxa's static file server handles this automatically, but if you are using a custom server, you need to configure the fallback manually. The fifth pitfall is large bundle sizes. Vite does not code-split by default, which means a large app can produce a single large JS file. The fix is to use React.lazy and Suspense for route-level code splitting.
When to Choose Vite vs Next.js
The choice between Vite and Next.js depends on your app's requirements. Choose Vite if your app is a dashboard, admin panel, internal tool, or SaaS app behind authentication, where SEO does not matter and SSR is not needed. Vite is simpler, faster, and produces cleaner output. Choose Next.js if your app is a marketing site, blog, documentation portal, or any app where SEO matters, where you need server-side rendering, or where you want to use React Server Components. Deployxa supports both equally, with the AutoRepairService and the zero-config engine handling both frameworks automatically. For a deeper comparison of deployment patterns, see our article on SPA vs SSR hardware sizing. For the specific case of Next.js build failures, see our article on AI-generated Next.js build failures. And for the broader pattern of missing dependencies, see our article on the five common AI coding mistakes.
Advanced Vite Configuration for Production
Beyond the basics, Vite apps benefit from several production optimizations. The first is code splitting. By default, Vite produces a single JS bundle, which can be large for apps with many routes. You can use React.lazy and Suspense to split the bundle by route, which reduces the initial load time. The second is tree shaking. Vite uses Rollup for production builds, which automatically removes unused code (tree shaking). However, some libraries are not tree-shakeable (e.g., lodash, which imports everything by default). The fix is to use tree-shakeable alternatives (e.g., lodash-es) or to import specific functions (e.g., import debounce from 'lodash/debounce'). The third is asset optimization. Vite inlines small assets (under 4KB) as base64 data URLs, which reduces the number of HTTP requests. You can control this threshold via build.assetsInlineLimit in vite.config.ts. The fourth is environment-specific configuration. Vite supports multiple environment files (.env, .env.production, .env.staging), which are loaded based on the NODE_ENV environment variable. This lets you configure different API URLs for each environment. The fifth is source map generation. By default, Vite generates source maps in production, which helps with debugging but increases the bundle size. You can disable source maps via build.sourcemap: false for smaller production bundles. Each of these optimizations is optional, but they can significantly improve your app's performance and load time. For more on Vite configuration, see the Vite documentation, and for more on deployment, see our article on the auto-detection engine.
Conclusion: Vite Apps Deserve Auto-Repair Too
Vite + React is the most common AI-generated SPA stack, and it suffers from the same missing-dependency problem as Next.js. Deployxa's AutoRepairService handles both, because the classifier is trained on error patterns from multiple build systems. Stop debugging module not found errors and start shipping.
Ready to deploy your Vite app? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on AI coding patterns, see our articles on the CORS trap and the environment variable guide. Explore our free developer tools to speed up your workflow.