Try this tool today

Accelerate your vibe coding workflow with our partner link.

Get Started →

v0 by Vercel is a CLI tool for deploying static and serverless web applications to the Vercel platform. It is used when a developer needs to build, preview, and deploy a site with a single command, especially during local development, CI/CD workflows, or when automating releases. It matters most when a project requires fast iteration, zero-downtime deploys, and automatic previews for pull requests.

Deploying a Project

To deploy a project, run:

v0 deploy

This command reads the v0.json configuration file (if present) and performs the following steps:

  • Detects the framework (React, Next.js, Svelte, etc.) via package.json and src/ structure.
  • Builds the project using npm run build or yarn build.
  • Uploads the output directory (default: out/ or dist/) to Vercel’s edge network.
  • Creates a new deployment and returns a URL like https://my-site-abc123.vercel.app.

If no v0.json exists, it uses sensible defaults:

  • build.command = npm run build
  • build.outputDirectory = out/
  • build.environment = production

A minimal v0.json might look like:

{
  "name": "my-site",
  "build": {
    "command": "npm run build",
    "outputDirectory": "build"
  },
  "routes": [
    {
      "src": "/(.*)",
      "dest": "/index.html"
    }
  ]
}

The routes section defines rewrite rules for static sites. For example, this config ensures that all routes (like /about, /blog/first-post) are served by index.html using client-side routing.

Previewing Changes

When working on a feature branch, run:

v0 deploy --name feature/new-ui --team my-team

This creates a preview deployment at https://feature-new-ui-my-site.vercel.app with the feature/new-ui branch. The --name flag sets the deployment name and is used in the Vercel UI.

The tool automatically detects Git context:

  • If HEAD is on a branch, it creates a preview deployment for that branch.
  • If HEAD is on main, it creates a production deployment.
  • It annotates the deployment with the Git commit SHA and branch name.

Additional flags:

  • --no-commit — skips Git commit after deployment.
  • --no-merge — deploys without merging the current branch into main.
  • --tag — adds a Git tag to the deployment.

Customizing the Build Process

To override the default build command or environment variables, add to v0.json:

{
  "build": {
    "command": "npm run build -- --optimized",
    "outputDirectory": "dist",
    "environment": {
      "NODE_ENV": "production",
      "API_BASE_URL": "https://api.example.com"
    }
  }
}

The environment object sets environment variables available at runtime. The --optimized flag is passed to npm run build.

For projects with multiple build targets, use builds instead of build:

{
  "builds": [
    {
      "command": "npm run build:client",
      "outputDirectory": "public",
      "environment": {
        "NEXT_PUBLIC_ENV": "staging"
      }
    },
    {
      "command": "npm run build:server",
      "outputDirectory": "server",
      "environment": {
        "NODE_ENV": "production"
      }
    }
  ]
}

Each build is treated as a separate deployment artifact, and v0 uploads them all. It then generates a manifest.json that maps paths to assets.

Handling Serverless Functions

v0 automatically detects serverless functions in functions/ or src/functions/. For example:

src/
└── functions/
    ├── api/hello.js
    └── api/users.js

When deployed, the api/hello.js file becomes available at https://my-site.vercel.app/api/hello.

To customize function behavior, use functions in v0.json:

{
  "functions": {
    "api/*.js": {
      "runtime": "nodejs18.x",
      "memory": "2048MB",
      "timeout": 30,
      "environment": {
        "DATABASE_URL": "postgresql://..."
      }
    }
  }
}

The functions object maps glob patterns to configuration. The runtime field accepts standard AWS Lambda runtimes (e.g., nodejs18.x, python3.9).

Functions can be triggered by HTTP, event sources (e.g., cron, S3), or internal calls. The timeout value is in seconds and applies to each function instance.

Setting Up HTTP Routes

Define routing rules using routes in v0.json. Each route has src, dest, and optional headers, continue, and status.

Example:

{
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "/functions/api/$1.js",
      "status": 200
    },
    {
      "src": "/admin/(.*)",
      "dest": "/admin.html",
      "headers": {
        "Cache-Control": "public, max-age=3600"
      }
    },
    {
      "src": "/(.*)",
      "dest": "/index.html",
      "continue": true
    }
  ]
}

The continue flag enables fallback routing: if a route doesn’t match, it continues to the next. This allows clean client-side routing.

When a request arrives at /admin/settings, v0 matches the second route, serves admin.html, and applies the Cache-Control header.

Common Pitfalls

  • build.outputDirectory is not respected if build.command outputs to build/ but v0.json points to dist/ — the uploaded content is empty. The fix: ensure the build command writes to the correct directory.
  • Function handler files must be named index.js, handler.js, or function.js — if api/hello.js is used but the file exports module.exports.handler, it works. But if the export is export function hello, v0 fails silently: the function returns 404 with no logs.
  • v0 deploy assumes package.json is in the project root — if package.json is in apps/web/, the build command fails unless --root is set.
  • Environment variables defined in v0.json are not automatically available in functions — they must be explicitly included in functions/*.js or set via functions/*/environment.
  • routes are matched in order — a route with continue: true must be placed at the end of the list to act as a fallback. Placing it at the front can lead to unexpected behavior.

Using Multiple Configurations

To deploy different environments with different settings, use v0.json alongside environment-specific files:

v0.json
v0.production.json
v0.staging.json

Then run:

v0 deploy --config v0.staging.json

The tool merges configurations:

  • Top-level v0.json is base.
  • v0.staging.json overrides it.
  • The --config flag loads the specified file and applies it on top.

For example:

// v0.json
{
  "name": "my-app",
  "build": {
    "command": "npm run build",
    "outputDirectory": "build"
  }
}
// v0.staging.json
{
  "name": "staging-my-app",
  "build": {
    "environment": {
      "NODE_ENV": "staging",
      "LOG_LEVEL": "debug"
    }
  },
  "routes": [
    {
      "src": "/api/(.*)",
      "dest": "/functions/api/$1.js",
      "headers": {
        "X-Environment": "staging"
      }
    }
  ]
}

This results in a staging deployment with:

  • Name: staging-my-app
  • NODE_ENV=staging, LOG_LEVEL=debug
  • X-Environment: staging header on API routes.

CI/CD Integration

In a CI system like GitHub Actions, use:

- name: Deploy to Vercel
  run: |
    npm install -g v0
    v0 deploy --name ${{ github.ref_name }} --team my-team

The --name flag uses the current branch name (main, feature/new-ui) as the deployment name, which is useful for tracking.

For pull requests, run:

- name: Deploy Preview
  if: github.event_name == 'pull_request'
  run: |
    v0 deploy \
      --name "pr-${{ github.event.number }}" \
      --tag "pr-${{ github.event.number }}" \
      --team "my-team"

This creates a preview deployment for each PR and tags the deployment with the PR number.

Debugging Deployments

When a deployment fails, check the output log. A typical failure looks like:

v0 deploy --name feature/new-ui

✓ Detecting framework: Next.js
✓ Building with: npm run build
Error: Cannot find module 'next'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:561:25)
    at Module.require (internal/modules/cjs/loader.js:689:19)
    at require (internal/modules/cjs/helpers.js:15:18)
    at Object.<anonymous> (/home/runner/work/my-site/next.config.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at Function.Module._load (internal/modules/cjs/loader.js:561:25)
    at Module.require (internal/modules/cjs/loader.js:689:19)

This indicates a missing next package, likely because package.json is not in the root directory.

To debug, run:

v0 deploy --verbose --dry-run
  • --verbose prints each step: detecting framework, building, uploading, creating deployment.
  • --dry-run simulates the entire process without uploading or creating a deployment.

Use --dry-run to validate v0.json changes before pushing to main.

Handling Deployments in Production

After a deployment, check the deployment logs at https://vercel.com/my-team/my-site.

  • Logs show stdout, stderr, and build output.
  • Each function has its own log stream.
  • Deployment metadata includes:
  • Git commit SHA
  • Branch name
  • Deployment ID
  • Deployed at timestamp
  • Build command and output

A common silent failure is missing index.html in build/. The server returns 404 for all routes, even though the index.html exists. The fix: ensure the build command outputs build/index.html, not build/html/index.html.

Another silent issue: function handler files are not exported correctly. The handler.js file must export a handler function or a default export:

// Correct
export const handler = async (req, res) => {
  res.json({ message: "Hello" });
};

// Or
export default async function handler(req, res) {
  res.json({ message: "Hello" });
}

If the export is export function handler, the function is not found. The logs show:

Error: Function handler not found: handler
    at Function.fromEvent (/var/task/index.js:1:1234)

Summary of Key Commands

  • v0 deploy — deploys current branch to Vercel.
  • v0 deploy --name <name> — sets deployment name.
  • v0 deploy --config <file.json> — uses a custom config.
  • v0 deploy --verbose --dry-run — debugs deployment steps.
  • v0 deploy --no-commit — skips Git commit after deployment.

Configuration Keys

  • name — deployment name.
  • build.command — build command.
  • build.outputDirectory — output directory.
  • build.environment — environment variables.
  • functions.<glob> — per-function settings.
  • routes — HTTP route rules.

Failure Modes

  • Build fails silently: build.outputDirectory is missing or build.command doesn’t write to it.
  • Functions not found: handler function not exported correctly.
  • Routing mismatch: routes not in order, continue: true not set where needed.
  • Environment variables not applied: missing in functions/*/environment.
  • Missing v0.json: defaults applied, but unexpected behavior occurs.

v0 by Vercel is a fast, reliable, and composable deployment tool for modern web applications. It excels when used consistently across teams, CI systems, and staging environments. Its success hinges on correct v0.json structure, consistent build outputs, and understanding of routing and function exports.

This page was rewritten on 11 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.