You describe an app idea to an AI tool. An hour later you have a working project. Next.js, App Router, TypeScript, Tailwind. Everything compiles, everything looks good. Now you want to put it on your own server. And that is where the real project begins.
AI coding assistants choose Next.js because React dominates the training data. Next.js is the most widely used React meta-framework, so Claude, ChatGPT and Copilot deliver it by default. This is not a quality judgment. It is a statistical effect. And for a project you want to host on your own VPS, it is the harder choice.
This article explains why. And why Nuxt is the more honest alternative for AI-generated projects on your own server.
Two Routers in One Framework
Next.js has two fundamentally different routing systems: the Pages Router and the App Router. Both exist in parallel within the same project. The Pages Router uses getServerSideProps and getStaticProps for data. The App Router uses React Server Components, async components and an entirely different mental model.
The problem: both appear in massive volume in the training data. AI assistants mix them. You get getServerSideProps alongside App Router handlers in the same project, or "use client" in places where it has no effect. The code compiles. And fails at runtime with errors that are cryptic to anyone who did not write the code.
If you chose vibe coding to move fast, you do not want to debug two routing paradigms as your first task.
React Server Components: The Invisible Mental Model
The App Router builds on React Server Components (RSC). Every component is a Server Component by default unless you explicitly mark it with "use client". Sounds simple. In practice it has subtle consequences.
You cannot use hooks in Server Components. You cannot pass functions as props across the client-server boundary. Event handlers do not exist. When an AI-generated component uses useState in a Server Component, it compiles. It breaks at runtime. The error reads like a React internal problem, not like "you forgot to write use client".
AI models regularly get this wrong because the RSC boundary is invisible. There is no syntax highlight, no linting that tells you upfront: this component runs on the server, that one in the browser. You need to carry the model in your head. Or clean up the errors manually.
Six Rendering Modes, Mixable Per Page
Next.js offers SSR, SSG, ISR, Partial Prerendering (PPR), Edge Runtime and Streaming. All mixable per page. For experienced teams this is powerful. For AI-generated projects it is a minefield.
The AI model picks a strategy per page based on pattern matching in the training data. There is no guarantee the strategies fit together. You get static pages next to ISR pages next to edge pages, and you as the reviewer have to figure out which strategy was chosen and whether it works for your deployment setup.
On a VPS the reality looks like this:
| Mode | On VPS | Constraints |
|---|---|---|
| SSG (static export) | Works | Pure HTML files, no Node process needed |
| SSR | Works | Needs running Node server, CPU-bound per request |
| ISR | With caveats | Filesystem cache by default, breaks with multiple instances, needs CDN with SWR header support |
| PPR | Conditional | Stable from Next.js 15, requires HTTP streaming support in your serving stack |
| Edge Runtime | Does not apply | Assumes Vercel edge network |
Four Caching Layers, Shifting Defaults
Next.js stacks four cache layers: Request Memoization, Data Cache, Full Route Cache and Router Cache. Defaults shifted across versions 13, 14 and 15. When you generate code with an AI tool, you get code for the version that dominates the training data. Whether the caching assumptions match your installed version, you find out in production.
Self-hosted, the Full Route Cache and Data Cache live on the local filesystem by default. That works with a single instance. The moment you start a second instance (for redundancy or load balancing), each instance serves its own cache. Data diverges. Stale content appears. The fix is a custom cacheHandler in next.config.js backed by a shared store like Redis. This is not a bug. It is a feature that Vercel solves automatically and that you have to build yourself on your VPS.
The Vercel Assumption
Next.js was designed around Vercel. That is not a secret and not a criticism. It means certain features assume an infrastructure layer that you do not have on a single VPS.
next/image processes images on demand using the native sharp library. On your VPS, image optimization and request handling share the same CPU cores. On small instances you notice. In Docker builds (Alpine, ARM cross-compilation), sharp is frequently missing or hits an architecture mismatch. You either configure an external image loader or install sharp explicitly.
ISR stores its cache locally. That breaks with multiple instances (see above). Additionally, ISR's stale-while-revalidate behavior depends on a CDN that honors the stale-while-revalidate cache-control header. CloudFront and Fastly support it. Cloudflare does not. The typical "VPS behind Cloudflare" setup, common among self-hosters, does not get the intended ISR behavior.
Edge Middleware is built for Vercel's edge network. On a VPS it runs inside your single Node process in one location. The code works, but the latency model from the docs does not apply.
Why AI Projects Get Hit Hardest
The irony: you chose vibe coding to get a result fast. The AI generates a Next.js project. It compiles. You are excited. Then you want to deploy it and discover: Next.js on a VPS is a second project. You have to learn the deployment internals to fix what the AI got wrong.
The AI-generated errors are systematic:
next/imagetriggerssharpCPU load or a native module build failure in Docker- ISR and route caching serve stale data once a second instance runs
- Edge middleware assumptions produce a different latency and execution model than the code expects
- App Router and Pages Router are mixed, and the runtime errors give no hint about which system caused the failure
Nuxt: One Path Instead of Six
Nuxt is the Vue full-stack framework. Its server engine Nitro was built to deploy to any target without a preferred platform. nuxt build produces an .output folder with a self-contained server:
node .output/server/index.mjs
No platform assumptions. No edge network requirement. The server runs behind nginx like any Node app and reads configuration from environment variables.
One rendering switch instead of six modes. ssr: true (default) or ssr: false for a SPA. Set once per project. No App-vs-Pages-Router split. AI-generated code points in one direction.
Explicit caching in one place. The entire caching policy lives in routeRules in nuxt.config.ts. You read the whole policy in one block instead of reverse-engineering four hidden layers:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // build-time static
'/products/**': { swr: 600 }, // cached, revalidate after 10 min
'/admin/**': { ssr: false } // client-only SPA
}
})
Portable output. Nitro ships deployment presets including node-server, Docker and many providers. The same codebase targets a VPS without rewrites. The default for self-hosting is the node-server preset.
Comparison Table
| Aspect | Next.js | Nuxt |
|---|---|---|
| Build output | next start or standalone | .output, one portable Node server |
| Image optimization | sharp on your CPU or custom loader | Opt-in via modules |
| Caching | Four layers, defaults shift between versions | One routeRules block |
| Rendering modes | SSR, SSG, ISR, PPR, Edge, mixable per page | SSR or SPA, once per project |
| AI-generated code | Mixes App Router and Pages Router | One routing model |
| Runtime RAM (small SSR app, idle) | ~0.5-0.7 GB | ~0.3-0.5 GB |
| Practical RAM (small prod app) | 2-4 GB | 1-2 GB |
| Safe starting point | 4 GB VPS | 2 GB VPS |
RAM values are directional estimates from community reports and public discussions. Your actual numbers depend on app complexity, traffic and middleware. The pattern is consistent: a comparable small SSR app runs roughly one VPS tier below the equivalent Next.js setup with Nuxt.
When Next.js Is Still the Right Choice
This article is about a specific situation: an AI-generated project that you want to host on your own server.
If you deploy to Vercel and do not plan to leave, Next.js is excellent. Vercel solves the caching, ISR, edge and image problems automatically. The framework and the platform are one unit, and that unit works.
If your team knows Next.js and consciously makes the architecture decisions (App Router, which caching strategy, how ISR works without Vercel), that is an informed choice. This article is for people who did not make these decisions themselves because the AI made them.
Conclusion
For AI-generated projects on your own server, Nuxt keeps the AI on one path and makes the deployment story boring. One rendering model, one caching block, one portable output. The AI can get less wrong, and you spend less time debugging framework internals.
Next.js is the more powerful framework. But power you do not control is complexity. If you use vibe coding to get a result fast, you want the framework that can go wrong the least.
Which VPS you need depends on your framework and traffic. Our framework calculator sizes the requirements for your project, and the VPS comparison shows you the cheapest options.
How much server does your framework need?
Enter framework, traffic and database. The calculator sizes RAM, CPU and storage for your VPS.
Open Framework Calculator

