Skip to content
Vibe Coders

Deploying Claude Code Output: From Artifact to Vercel in 20 Minutes

Start to finish: prompt, generate, local-run, commit, Vercel connect, env vars, DNS, live. The shortest path we know. For solo founders who want a URL by end of day.

By WitsCode10 min read

Most tutorials about deploying an AI-generated web app stop at the interesting part. They show you how to prompt the model, how the code appears, maybe a screenshot of the running localhost, and then they wave at a vague cloud icon labelled "ship it." The real work starts where those tutorials end, and it is the reason so many Claude Code artifacts never make it past the author's laptop. There is a gap between a working dev server and a public URL with SSL, a real domain, environment variables set correctly, and a CI pipeline that redeploys on every push. That gap is usually estimated at a weekend. It does not have to be. On a clean repo with a simple stack, the distance from first prompt to live production URL is twenty minutes, and most of the twenty is waiting. This article is the linear narrative of that twenty minutes, stage by stage, with the three or four traps that swallow people who have not done it before.

Minute zero to two, the prompt that sets everything up

The single decision that shortens every later stage is what you write in the first prompt. A vague brief like "build me a landing page" produces code Claude Code thinks is reasonable but which may not match what Vercel expects. The output might be a static HTML file, a Vite plus React SPA, a Next.js pages-router app, or a Next.js App Router app, and those four targets deploy differently. You want to specify the stack on the first line and let Claude Code scaffold into the shape Vercel auto-detects without any manual preset override later.

A prompt that works reliably names the framework, the language, the styling system, the package manager, and the Node version. Something like "build a Next.js 15 App Router app in TypeScript with Tailwind and shadcn/ui, using pnpm, pinned to Node 20." That sentence saves ten minutes of framework debugging at the Vercel import step, because the moment you mention pnpm and Node 20 Claude Code tends to write the engines field into package.json, which prevents a silent Node version roll-forward six weeks from now. If your app needs a database, name the database and the ORM in the same breath. Supabase with Drizzle, Postgres with Prisma, whatever. Specifying the data layer up front means the generated code includes the environment variables you will need to paste into Vercel later, and you will not discover half of them missing at build time.

The prompt is also where you tell Claude Code to initialise git and write a sensible gitignore. It is a one-line addition and it means when you reach the commit stage you do not have to pause and configure anything.

Minute two to seven, the generation

The middle of the generation is the part you cannot speed up. Claude Code reads your brief, plans, creates the directory structure, writes package.json, tsconfig, tailwind.config, the next.config, the app directory with layout and page, any components you asked for, and closes with a CLAUDE.md if you ran init earlier. On a small project this is three to five minutes. On a project with a database schema and a few routes it is closer to seven. Use the time to open a browser tab at github.com/new and at vercel.com/new, because you will need them ready in a minute.

The most useful thing to verify before generation finishes is that Claude Code writes a lockfile-compatible package.json. Ask it to include the engines field with Node 20.x pinned. Ask it to set the packageManager field with your pnpm version. These two fields are the difference between a deterministic build on Vercel and a build that succeeds on your laptop and fails in the cloud because a transitive dependency resolved to a different major version. They are cheap to add at prompt time and expensive to debug later.

Minute seven to eleven, install and run locally

Run pnpm install in the generated directory. This creates pnpm-lock.yaml, which is the file Vercel will use to install dependencies deterministically. Committing the lockfile is not optional. Without it Vercel will either fall back to npm or install latest-matching versions of every dependency, and either case produces a build that works today and breaks in a month when a minor release ships a regression. The lockfile is the single most important artifact in the whole deploy, and most Claude Code tutorials forget to mention it because the local dev server works fine without one.

While install runs, glance at the dependency tree for anything surprising. If Claude Code added a database client you did not ask for, this is the moment to uninstall it. If it pulled in a heavier UI library than you wanted, swap it now. The longer a bad dependency stays, the more of the generated code leans on it, and the harder the swap gets.

Start pnpm dev and open localhost:3000. The goal here is not to love the design, it is to confirm the app boots, the home route renders, and the TypeScript compiler is happy. If the terminal is quiet and the browser shows content, move on. If there are errors, fix them now. Every TypeScript error that survives to the Vercel build will stop the deploy, and fixing it in a Vercel build log means a three-minute round trip per attempt. Fixing it in the local terminal is a ten-second feedback loop.

This is also the stage where you discover that Claude Code generated references to environment variables that do not yet exist. A SUPABASE_URL import, a STRIPE_SECRET_KEY, a RESEND_API_KEY. Create a .env.local at the project root with plausible values so the dev server boots. Do not commit it, the gitignore Claude wrote should already exclude it, but do keep it open in your editor because you will need to transcribe every line into Vercel in a few minutes.

Minute eleven to fifteen, commit, push, and import to Vercel

Initialise a GitHub repo if you do not already have one. The fastest path is gh repo create with the GitHub CLI, which creates the remote and sets it as origin in one command. If you are in the browser, github.com/new plus a manual git remote add origin is the same thing in two more clicks. Stage everything Claude Code produced, write a one-line commit message, and push.

Check one thing before you push, which is that .env.local is not in the staged files. Ninety-nine percent of the time the gitignore handles this. One percent of the time Claude Code writes a gitignore that misses it, and you push secrets to a public repo. A thirty-second git status before pushing is cheap insurance. If you have already pushed secrets, rotate the keys first and rewrite history second, in that order.

Go to vercel.com/new and select Import Git Repository. If this is your first Vercel project you will also install the Vercel GitHub App, grant it access to the repo you just created, and return to the import screen. Pick the repo, and Vercel auto-detects the framework. If you prompted Claude Code correctly this should read Next.js, with the build command pnpm build, the output directory .next, and the install command pnpm install. Accept the defaults and click Deploy.

This is the stage where two traps bite people who have not deployed to Vercel before. The first is wrong framework detection in monorepos. If your repo has a root package.json and the Next app lives in apps/web, Vercel detects the root and tries to build from there, which fails. The fix is under Settings, General, Root Directory, and you set it to apps/web or wherever the next.config sits. The second trap is when Claude Code generates a Vite plus React scaffold rather than Next.js, usually because the first prompt said "web app" and the model guessed Vite. Vercel will detect Vite correctly, build the static output, and deploy it, but if you wanted Next.js features like server components or server actions you will not have them. If that is a problem, either regenerate with a more specific prompt or switch the framework preset manually under Build and Development Settings. The switch by itself will not make the code Next.js, but it will stop Vercel trying to do the wrong thing with a Next config that does not exist.

Minute fifteen to eighteen, the environment variable migration

The first deploy will usually succeed at the install step and fail at the build or runtime step, because none of your environment variables are set. This is not a flaw in the process, it is the part of the process that every newcomer underestimates. Open the local .env.local in one window and Project Settings, Environment Variables in another. Vercel has a bulk paste UI where you can drop the whole .env file and it splits the lines into key-value pairs. Use it, do not type each one by hand.

Three things trip people up here. The first is that .env.local is git-ignored, so it never reached Vercel through the repo. Vercel reads environment variables only from Project Settings, and pasting them in is a manual step you cannot skip. The second is the scope selector. Each variable has three checkboxes, Production, Preview, and Development, and newcomers often set only Production. Preview deploys then crash because they have no DATABASE_URL, and you end up with a production URL that works and a PR preview URL that does not, which is exactly the opposite of what preview environments are for. Tick all three unless you have a specific reason to separate them. The third is the NEXT_PUBLIC prefix. Any variable prefixed NEXT_PUBLIC is inlined into the client bundle at build time, not read at runtime, so changing it requires a redeploy. If a public variable seems to be ignored after you update it, trigger a redeploy from the Deployments tab and it will pick up the new value.

Once the variables are in, hit Redeploy on the latest deployment. Two minutes later the build should go green and the app should respond at the generated vercel.app URL.

Minute eighteen to twenty, the domain

The vercel.app URL works, but it is not the URL you want your customers to share. Go to Settings, Domains, and add the domain you own. Vercel will show you either an A record or a CNAME, depending on whether the domain is an apex like example.com or a subdomain like app.example.com. The apex takes an A record pointing to 76.76.21.21. The subdomain takes a CNAME pointing to cname.vercel-dns.com. Open your registrar's DNS panel in another tab, add the record, and save.

DNS propagation is usually under a minute for a fresh record and up to an hour if you are updating an existing one. Vercel issues a Let's Encrypt certificate automatically once it can resolve the record, typically within sixty seconds of propagation completing. If the SSL provisioning hangs, the culprit is almost always a CAA record at the registrar restricting certificate authorities. Either add letsencrypt.org to the CAA record or remove the CAA record entirely, and the certificate will issue on the next attempt. At this point you refresh your browser at the custom domain and the app is live.

The three traps that turn twenty minutes into a weekend

The first is the environment variable migration. If you remember only one thing from this article, remember that Vercel cannot read your .env.local and that you must paste every variable into Project Settings manually, across all three environments. This single miss accounts for more first-deploy failures than any other cause.

The second is Node version drift. Vercel's default Node version moves forward over time, and a project built on Node 20 can silently be rebuilt on Node 22 a few months later, which occasionally breaks native dependencies or changes how a library behaves. Pin the version in two places if you want belt-and-braces, first with an engines field in package.json reading "node": "20.x", and second under Project Settings, General, Node.js Version. The two agree by default but the explicit settings survive framework preset changes.

The third is framework misdetection, which bites in monorepos and in cases where Claude Code guesses the wrong stack. The answer is not to fight Vercel but to make the repo shape match what Vercel expects, either by moving the Next app to the root, or by setting the Root Directory to the subfolder, or by regenerating with a more specific prompt. If you catch this in the import step you lose thirty seconds. If you discover it after a dozen failed deploys you lose an afternoon.

Why this sequence matters

There is nothing magical about twenty minutes. The number is a consequence of doing each stage in the order that minimises rework. Prompting with the stack named prevents framework fights later. Running locally before pushing catches TypeScript errors cheaply. Committing the lockfile prevents cloud non-determinism. Setting env vars across all three environments prevents preview URLs from being second-class. Pinning Node prevents future silent breakage. Each stage protects the ones downstream of it, and skipping one does not save time, it moves the cost to a harder-to-debug stage.

The broader point is that "deploying an AI-generated app" is not one task, it is eight small tasks that have to be done in a particular order with particular inputs. Claude Code can scaffold the code, Vercel can host the result, and the twenty minutes between them is mostly the careful handoff. Once you have done it twice, it stops feeling like a hurdle and starts feeling like pressing go. The first time is the one this article is for.

If you want the twenty minutes to happen without you doing it, WitsCode runs a deployment sprint service where we take a Claude Code artifact you generated, walk it through the exact sequence above, and hand back a live URL with custom domain, environment variables, preview deployments on every PR, and a short README that documents every var and every DNS record. → WitsCode deployment sprint

Get weekly field notes.

Practical writing on shipping products, straight to your inbox. No spam.

Need help with this?

MVP Development

We design and build web apps, MVPs, and SaaS products. Talk to us about what you are working on.

Talk to us

Want to discuss vibe coders for your business?

Start a project and we'll talk through where you are, what's working, and the highest-leverage moves for the next 90 days.