Ploy
Ploy

Vite

How the Ploy Vite integration works and how to configure it for Vite apps.

Vite

Ploy runs Vite apps — React SPAs that ship a worker, TanStack Start apps, and other worker + assets projects — directly from your ploy.yaml. You keep a single source of truth for bindings, assets, and compatibility settings, and Ploy handles the dev and build toolchain for you.

Ploy ships the @meetploy/vite package. Add its ploy() plugin to your vite.config.ts and it wires bindings, assets, and compatibility settings from ploy.yaml into the Vite toolchain for both dev and build.

How it works

When you run ploy dev or ploy vite, Ploy:

  1. Detects a Ploy Vite project — the project has a vite.config.* file and @meetploy/vite in its dependencies (or an ancestor's package.json, so monorepos work).
  2. Reads and validates ploy.yaml and resolves any Agent SDK bindings.
  3. Builds the runtime configuration from ploy.yaml — bindings, assets, and compatibility date/flags.
  4. Isolates the Miniflare registry under a fresh temp directory per project, so multiple projects don't collide locally.
  5. Spawns Vite (your local node_modules/.bin/vite, falling back to npx vite) with the generated config and Ploy environment variables wired in.

For ploy dev, a local Ploy dashboard / mock server is also started on port + 1000 and its URL is exposed to the worker via PLOY_DASHBOARD_URL and PLOY_MOCK_SERVER_URL.

Keep your bindings and compatibility settings in ploy.yaml — it's the single source of truth for your project's configuration.

Project setup

A Ploy Vite project needs three pieces: a package.json that calls Ploy, a vite.config.ts using the ploy() plugin from @meetploy/vite, and a ploy.yaml.

Install the plugin as a dev dependency:

pnpm add -D @meetploy/vite
package.json
{
	"scripts": {
		"dev": "ploy vite dev",
		"build": "tsc --noEmit && ploy vite build",
		"types": "ploy types -o env.d.ts"
	}
}
vite.config.ts
import { ploy } from "@meetploy/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [react(), ...ploy()],
});

ploy() returns an array of plugins, so spread it into the plugins list.

ploy.yaml
kind: dynamic
build: pnpm build
out: dist
compatibility_date: "2026-03-23"
assets:
  binding: ASSETS
  not_found_handling: single-page-application
  run_worker_first:
    - /api/*
    - "!/api/docs/*"
db:
  DB: default

For non-TanStack projects, Ploy looks for a worker entry at worker/index.ts (or the .js / .mjs variants).

Configuration

Everything the Vite toolchain needs is configured through ploy.yaml.

Project kind

Use kind: dynamic for Vite apps that ship a worker alongside static assets.

ploy.yaml
kind: dynamic
build: pnpm build
out: dist
FieldDescription
kinddynamic for Vite worker + assets apps
buildBuild command Ploy runs to produce out
outOutput directory the Vite build writes to

Compatibility

Set the Workers runtime compatibility date and flags here in ploy.yaml.

ploy.yaml
compatibility_date: "2026-03-23"
compatibility_flags:
  - nodejs_compat

Assets

The top-level assets key controls static asset behavior for dynamic Vite deployments.

ploy.yaml
assets:
  binding: ASSETS
  not_found_handling: single-page-application
  run_worker_first:
    - /api/*
    - "!/api/docs/*"
  • binding exposes the asset fetcher to your worker as env.ASSETS
  • not_found_handling: single-page-application enables SPA fallback so client routes resolve to index.html
  • run_worker_first lets API routes (or other patterns) bypass the asset layer and hit your worker first; prefix a pattern with ! to exclude it

Bindings

Add Ploy resources — databases, queues, auth, and more — with the same binding maps used by workers. They're available on env in your worker.

ploy.yaml
db:
  DB: default
queue:
  TASKS: tasks

After changing bindings, regenerate types so env.d.ts stays current:

ploy types -o env.d.ts

Dev server port and host

You can pin the local dev port and host per project. CLI flags (-p / --port, -h / --host) take precedence.

ploy.yaml
dev:
  port: 3000
  host: localhost

Running it

There are two ways to drive the Vite integration:

  • ploy dev — auto-detects the project type and, for Ploy Vite projects, starts the Vite dev server plus the local Ploy dashboard. This is the usual command during development. See ploy dev.
  • ploy vite <build|dev> — runs the underlying Vite command directly with the ploy.yaml-managed config. Use this in package.json scripts and CI. See ploy vite.
# Auto-detected dev server + dashboard
ploy dev

# Explicit Vite dev / build with ploy.yaml config
ploy vite dev
ploy vite build

Any extra arguments after ploy vite <mode> are forwarded to Vite. To pass Vite's own --config, forward it explicitly:

ploy vite build -- --config vite.config.custom.ts

TanStack Start

TanStack Start apps work the same way — spread ploy() alongside the TanStack Start plugin. See the dedicated TanStack Start guide for routing, server routes, and prerendering.

Notes

  • Use the ploy() plugin from @meetploy/vite and let Ploy manage your configuration from ploy.yaml.
  • Keep compatibility settings and bindings in ploy.yaml.
  • For plain workers use ploy dev / ploy build; for Next.js use ploy dev with @meetploy/nextjs.

How is this guide?

Last updated on