Yes. v0 deploys a static React + Tailwind site. The build output is HTML, CSS, and JavaScript; there is no server runtime, no database, no API. The “Deploy” button publishes a static site to Vercel with a *.vercel.app URL. That is the literal answer. The interesting question is what the static deploy cannot do, what the developer has to add before calling it “production,” and when the right move is to a real framework like Next.js.
The reason “does v0 deploy just a static html” is a top search is that the answer is technically yes, and that “yes” hides the part of the question that actually matters. The static deploy is fine for a landing page, a portfolio piece, or a marketing site. The static deploy is not enough for an app that needs a backend, an auth flow, or real data.
This post is the v0 deploy story, the parts that work, the parts that do not, and the migration path for when the static deploy stops being enough.
Table of contents
- The direct answer: yes, with a clear asterisk
- What v0 generates, in build-output terms
- What works on the static deploy
- What does not work without a backend
- The deploy pipeline v0 actually uses
- When to move from v0 to a real framework
- The migration path that does not start over
- FAQ
The direct answer: yes, with a clear asterisk
v0 takes a prompt, generates a React + Tailwind project, builds it, and deploys the static output to Vercel. The URL is a *.vercel.app subdomain. The build is a real static site: HTML, CSS, JavaScript, images, and the React hydration script. There is no server.
The asterisk: a “static site” in the v0 sense means the HTML is pre-rendered at build time. The JavaScript is a React app that hydrates the page in the browser. The data is what was in the source at build time; there is no runtime database, no runtime API, no runtime anything except the JavaScript that runs in the browser.
For a marketing site, a portfolio, a landing page, or a static product page, that is enough. For an app that needs a backend, an auth flow, a database, or any kind of stateful interaction, the static deploy is the wrong shape.
What v0 generates, in build-output terms
The output of a v0 build, in the same shape any Next.js or Vite + React build produces:
dist/ (or build/, depending on the bundler)
├── index.html
├── assets/
│ ├── index-[hash].js
│ ├── index-[hash].css
│ └── ...
├── images/
└── favicon.ico
The index.html is a static HTML file with the React app’s root markup and a <script> tag pointing at the bundled JavaScript. The JavaScript hydrates the page in the browser and renders the React components. The CSS is the compiled Tailwind output. The images are whatever the v0 prompt asked for.
The output is a real static site. It can be served from any static host: Vercel, Netlify, Cloudflare Pages, Render, an S3 bucket behind CloudFront, a self-hosted Nginx. The choice of host is independent of the choice of v0 as the generator. The deploy button in v0 happens to use Vercel; the output is portable.
What works on the static deploy
The static deploy handles a real class of use cases well:
- Landing pages with hero, features, pricing, footer. The React components render the content from the build-time source.
- Marketing sites with multiple pages, navigation, and CTAs. Each page is a separate route in the React app; the static build emits one HTML file per route.
- Portfolio pieces with image galleries, case studies, and contact forms. The contact form is the only dynamic piece; the form-submit handler calls a third-party service (Formspree, Netlify Forms, a serverless function).
- Documentation sites with the content in the source. The static build emits a search-indexed HTML site that is faster than the same content in a CMS.
- Event pages, product launches, single-purpose sites. The site exists for a purpose, the purpose ends, the site stays up as a record.
For all of these, the static deploy is the right shape. The build is fast, the deploy is free on Vercel’s hobby tier, the URL is shareable, and the maintenance cost is zero.
What does not work without a backend
The static deploy breaks down at the first piece of stateful logic. The things that do not work:
- User accounts. The static site has no database, no session, no way to remember a user between visits. The right answer is an auth provider (Auth0, Clerk, Supabase Auth) and a backend service.
- Form submissions that need to be stored. A form that posts to a third-party form-handling service works (Netlify Forms, Formspree). A form that posts to your own backend does not, because there is no backend.
- Dynamic data. A blog that fetches posts from an API at runtime is not a static site; the build has to bake the data in, or the page has to fetch it from a public API at runtime. The first approach is a static site; the second is an SPA with a static shell.
- Personalization. Showing different content to different users requires either a build-time branch (impractical at scale) or a runtime layer (which is a backend, by definition).
- Server-side rendering with auth or cookies. A static site cannot read a cookie or check a session at request time. The auth check has to happen in the browser, after the page has loaded, which means the protected content is in the JavaScript bundle, which means anyone can read it.
- WebSockets, long-polling, server-sent events. None of these work in a static site. A real-time feature has to be a third-party service (Pusher, Ably) or a serverless function with WebSocket support.
The v0 deploy handles none of these out of the box. The “Deploy” button in v0 publishes a static site. The auth, the database, the form-submit handler, the real-time layer — all of that is the developer’s job to add.
The deploy pipeline v0 actually uses
The v0 “Deploy” button calls the Vercel deploy API with the build output. The pipeline:
- v0 builds the project (a
next buildor equivalent, depending on the v0 version). - v0 uploads the build output to Vercel’s edge network.
- Vercel assigns a URL (
*.vercel.appon the free tier, a custom domain on a paid plan). - Vercel serves the static output from its CDN.
The pipeline is the same shape as a Vercel deploy from a Git repo. The difference is the source: v0 owns the source, and the developer does not have a local copy of the code unless they download it from the v0 UI.
The right mental model: v0 is the editor and the deploy is the publish. The developer can take the generated code, put it in a Git repo, and deploy it from there. The v0 deploy is the fast path; the Git deploy is the right path for anything that is going to live longer than a week.
When to move from v0 to a real framework
The static deploy is the right answer for the first day. It is the wrong answer for the second month. The signals that it is time to move:
- You need a backend. The first time you need to store a form submission in your own database, the static deploy stops being enough. The right move is to add a backend (a Next.js API route, a serverless function, a separate API service).
- You need auth. The first time you need to know who the user is, the static deploy stops being enough. The right move is to add an auth provider and a backend that can read the session.
- You need to ship changes without a v0 round-trip. The first time you need to change a button color without re-prompting v0, the static deploy is friction. The right move is to download the code, put it in a Git repo, and deploy from the repo.
- You need to test changes in PRs. The first time you need preview deploys for every PR, the v0 model does not fit. The right move is a Git-based deploy (Vercel from Git, Netlify from Git, Render from Git) that gives preview deploys for free.
- The site becomes a real product. The first time the site is the product, not a marketing surface, the static deploy is the wrong shape. The right move is a real framework (Next.js, Remix, SvelteKit, Astro) with a real backend.
The migration is not a re-write. The output of v0 is React + Tailwind; the output of Next.js is React + Tailwind. The code moves from the v0 source to a Git repo, the build pipeline becomes next build (or equivalent), and the deploy pipeline becomes the same Vercel deploy from Git. The work is the backend, the auth, the database — the things v0 did not generate.
The migration path that does not start over
The migration is three steps, in order:
- Download the v0 code to a local directory. v0 has an “Export to Code” or equivalent that gives you the source. The source is a Vite or Next.js project.
- Put it in a Git repo. Push to GitHub or GitLab. The repo is now the source of truth; the v0 version is a snapshot.
- Connect the repo to Vercel (or another host). The deploy is now Git-based. Every push to
mainis a production deploy; every PR gets a preview URL. The v0 deploy button is no longer the path.
The migration does not touch the React code, the Tailwind config, the components, or the routing. The v0 output is portable. The migration is the deploy pipeline, the Git history, and the things v0 did not generate (the backend, the auth, the database).
For a team that has outgrown the v0 deploy, the RunxBuild deploy path is one option. The same pattern as Vercel from Git: a Git repo, a Dockerfile or build config, and a managed deploy. The static site stays static; the backend and the database come from the platform. For a team that wants to keep the v0 deploy as the fast path and add a real backend alongside, the answer is a v0 static site + a serverless function API + a managed database, all on the same platform. The static site is the front door; the backend is the back office.
How this fits the rest of the stack
The v0 deploy is a great starting point, but the team’s first backend addition is where the platform choice starts to matter. The first database, the first backend API, the first worker, and the first storage bucket each add a line item to the bill, and the team should know the total before the architecture grows. The RunxBuild hosting calculator is the right place to model that — pick the static site bandwidth, the backend runtime, the database tier, the worker count, and the storage, and the calculator shows what the v0-plus-backend stack actually costs.
Useful related references:
FAQ
Does v0 deploy a static HTML file?
Yes. The “Deploy” button in v0 publishes a static React + Tailwind site to Vercel. The build output is HTML, CSS, JavaScript, and images. There is no server runtime.
Can I deploy a v0 site to something other than Vercel?
Yes. Download the source from v0, put it in a Git repo, and deploy from the repo to any static host (Vercel, Netlify, Cloudflare Pages, Render, an S3 bucket). The output is portable.
Can v0 generate a full-stack app?
v0 generates the frontend. The backend (database, auth, API) is the developer’s job to add. The v0 “Deploy” button does not include a backend.
Can I add a backend to a v0 site?
Yes. The pattern is a v0 static site + a serverless function API + a managed database, all on the same platform. The static site is the front door; the serverless function is the API; the database is the storage. The migration is the deploy pipeline, not the React code.
How do I move from v0 to a real framework like Next.js?
Download the v0 code, put it in a Git repo, and deploy from the repo. The migration does not change the React code; the work is the backend, the auth, and the database — the things v0 did not generate.
Is v0 the same as Next.js?
No. v0 is an AI generator that produces a Next.js (or Vite) project as output. The output is a regular Next.js project that you can deploy, modify, and own. v0 is the editor; Next.js is the framework; Vercel is one of many deploy targets.