Deploy
Flue was designed to work with Vite. vite dev serves the application during development, vite build produces the deployable artifact, and shipping that artifact works like shipping any other Vite application to your hosting platform of choice.
This guide covers the build and the deploy path for each target. For each target’s runtime behavior in depth, see the Node.js and Cloudflare guides.
Build with Vite
Adding flue() from @flue/vite to vite.config.ts makes a Vite project a Flue application:
import { flue } from '@flue/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [flue()],
});
import { cloudflare } from '@cloudflare/vite-plugin';
import { flue } from '@flue/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [flue(), cloudflare()],
});
The plugin does three jobs on both targets:
- Resolves the project. It discovers
flue.config.tsand locates your entry modules (app.tsrequired;db.tsandcloudflare.tsoptional). - Scans for agents. The
'use agent'scan over your source root defines the application’s agent set, and the generated server bootstrap registers every scanned agent. - Transforms agent modules. The build stamps each agent’s identity (the function name, or its
agentNamestatic override) as a string literal bound to the function, so a minified production bundle cannot corrupt the durable identity.
flue() also accepts inline configuration merged over flue.config.ts — see Configuration.
Choose a target
Flue builds for two targets:
- Node.js produces a self-starting server you can run anywhere Node runs: a VM, a container, or a managed host.
- Cloudflare produces a Worker where each agent runs inside its own Durable Object, with durable state and global addressability out of the box.
When target is unset, flue() auto-detects it from the Vite plugin array: with @cloudflare/vite-plugin present the target is 'cloudflare', otherwise 'node'. An explicit target overrides detection.
Deploy on Node.js
vite build bundles the application into two Node entries: the self-starting dist/server.mjs, and the non-listening dist/app.mjs chunk it imports:
vite build
node dist/server.mjs
Three things to know before shipping the artifact:
- Environment: the built server does not load
.env— supply provider keys and other configuration when you start it. It listens on port3000by default; setPORTto change it. - Dependencies: application dependencies are externalized, not bundled. Deploy the artifact alongside its
node_modules, or in a container that installs them. - State: without a
db.tsadapter, conversations live in process-local memory and a restart loses them. Configure a durable adapter before deploying anything you care about.
vite preview serves the built artifact locally with production behavior — a faithful pre-deploy check.
For runtime details — state and durability, process ownership, multi-replica rules, environment and secrets — see the Node.js target guide. For step-by-step hosting walkthroughs, see Deploy Agents on Node.js, Docker, and the other platform guides in the ecosystem section.
Deploy on Cloudflare
On Cloudflare, flue() cooperates with the official @cloudflare/vite-plugin, which owns workerd dev, build output, preview, and deploy. flue() must come before cloudflare() in the plugins array; the wrong order is diagnosed with an error. Flue’s job is generating the Worker inputs the Cloudflare plugin consumes: a Worker entry that registers your scanned agents and exports one Durable Object class per agent, plus your authored wrangler.jsonc merged with the generated bindings. Add both generated paths to .gitignore:
.flue-vite/
.flue-vite.wrangler.jsonc
Two things stay yours to author in wrangler.jsonc: the nodejs_compat compatibility flag, and the Durable Object migrations — an append-only record of your deployments that Flue never writes. Every deployed agent needs a migration entry for its generated class, so adding an agent is always a triple: the agent, its mount in app.ts (skip for dispatch-only agents), and a new migration tag:
{
"name": "my-flue-worker",
"compatibility_date": "2026-06-01",
"compatibility_flags": ["nodejs_compat"],
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["FlueTriageAgent"] }],
}
Renaming or removing a deployed agent is a storage migration too (renamed_classes / deleted_classes) — read Managing migrations before changing anything already deployed.
Build and deploy through the Cloudflare plugin: vite build, then deploy against the config it emits into dist/. For the full walkthrough, see Deploy Agents on Cloudflare; for runtime behavior — generated classes and bindings, durable execution, service bindings — see the Cloudflare target guide.
Next steps
- Node.js and Cloudflare — each target’s runtime behavior in depth.
- Deploy Agents on Node.js and Deploy Agents on Cloudflare — step-by-step walkthroughs, plus Docker and other platforms.
- Database — durable conversation storage for the Node target.
- Configuration — every
flue.config.tsfield and the Vite plugin’s options.