flue dev
Purpose and Scope
The development command is the local feedback loop for a Flue application. It starts a server, watches the project, and reloads the running application when relevant files change. That matters because Flue projects are not only request handlers: they can expose agents, workflows, dispatch routes, and channel ingress surfaces that may keep streams open while work is happening. The command is therefore designed to be more than a simple static file watcher. It gives developers a stable local port, a repeatable configuration resolution path, and target-specific behavior for Node.js or Cloudflare development while preserving enough runtime discipline to avoid confusing reloads during accepted work.
Sources: apps/docs/src/content/docs/cli/dev.md
Use this page when you need a reference for command syntax, option defaults, reload behavior, and the differences between the Node.js and Cloudflare development targets. It is intentionally focused on local development, not production build output. The same options that name a target, root, configuration file, output directory, port, and environment file are useful during the edit-run-debug cycle, but their effects differ from deployment commands. In particular, the Node development path uses an in-memory Vite module runtime and does not write deployment artifacts to the configured output directory.
Relevant Source Files
- apps/docs/src/content/docs/cli/dev.md - The canonical documentation source for the command synopsis, option defaults, watch behavior, target-specific runtime behavior, examples, and the link back to the broader CLI overview.
Synopsis
flue dev [--target <node|cloudflare>] [--root <path>] [--output <path>] [--config <path>] [--port <number>] [--env <path>]The command can be run with no flags when the project has enough configuration for Flue to discover a target and local settings. When the target is ambiguous, choose one explicitly. The two supported target values are Node.js and Cloudflare. The port flag selects the local listener, while root and config influence where the project is resolved from and which configuration file is loaded. The environment flag is specifically for selecting an alternate dotenv-format file before configuration is evaluated; it is not a replacement for shell variables, because shell values take precedence over values loaded from that file.
Sources: apps/docs/src/content/docs/cli/dev.md
Options Reference
| Option | Default | Behavior |
|---|---|---|
| `--target <node | cloudflare>` | Configuration value |
--root <path> | Selected config-file directory, or config search directory | Selects the project root used for discovery and local resolution. |
--output <path> | <root>/dist | Configures deployment build output. Node development does not write runtime artifacts there. |
--config <path> | Auto-discovered flue.config.* | Selects a specific configuration file instead of relying on auto-discovery. |
--port <number> | 3583 | Selects the local server port. |
--env <path> | <config-base>/.env, when present | Loads one alternate dotenv-format file before configuration. Relative paths resolve from the config base, and shell values win. |
The important configuration distinction is between auto-discovered and explicit configuration files. Auto-discovered files named with the Flue configuration convention are watched as part of the project, so editing, creating, or deleting one restarts the local development session and resolves configuration again. An explicit configuration file selected with the config flag is also watched, even if it lives outside the project root. This supports advanced layouts where a shared or generated configuration file is kept elsewhere, while still preserving the same restart behavior developers expect from files inside the application.
The environment option participates before configuration is evaluated. That ordering is useful when configuration reads process environment variables to select adapters, credentials, targets, model settings, or channel secrets. Relative environment paths resolve from the configuration base, which keeps command invocations portable when run from different working directories. Shell variables win over loaded file values, so a terminal override remains authoritative. That precedence is important in local debugging because it allows a one-off shell export or process manager setting to override a checked-in or generated dotenv file without editing the project.
Sources: apps/docs/src/content/docs/cli/dev.md
Local Development Flow
A typical session begins by choosing the target and loading configuration, then starting a local server on the selected port. After startup, the command watches project files and reacts to relevant edits. The visible behavior is a live development server, but the underlying contract is configuration-aware and target-aware. When the configuration changes, the current local session is interrupted and a new session is started with freshly resolved settings. That means the active server can move from one configuration shape to another without requiring a manual stop and restart, as long as the edited configuration becomes valid again.
Configuration errors are handled as recoverable development states. If an edited configuration is invalid, the command waits for the next configuration change rather than continuing with a partially understood setup. This is a practical choice for agent and workflow applications, where an invalid model provider, route mount, database adapter, or channel setting could produce misleading behavior if the server attempted to run anyway. Once the developer fixes the configuration and saves another change, the command starts a new session. During a configuration restart, active local requests and streaming connections are interrupted, so clients should be prepared to reconnect during configuration-level edits.
This restart behavior is different from ordinary source reload behavior because configuration defines the shape of the development session itself. Changing application code may be handled inside a running listener, but changing the configuration can alter the target, root, loaded resources, environment choices, or other assumptions used to construct that listener. Treat configuration edits as local session boundaries. For routine agent handler, workflow, tool, or route changes, rely on the target-specific reload behavior described below; for configuration changes, expect a more disruptive restart that intentionally discards the old development session.
Node.js Target Behavior
For the Node.js target, the project runs through an in-memory Vite module runtime. The documentation explicitly calls out that Node development does not write runtime artifacts to the deployment output directory. This keeps the development loop fast and avoids confusing local hot reload with a production build. The same output option can still be present because it belongs to the broader configuration surface, but the Node development server is focused on loading and replacing the application in memory rather than producing deployable files as a side effect of every edit.
Sources: apps/docs/src/content/docs/cli/dev.md
The Node reload path includes a quiescence step for tracked Flue work. On a source change, Flue pauses new admissions for agents, workflows, dispatch, and channels, then lets already accepted work settle before replacing the loaded application on the same port. In this context, an admission is the point where the local server accepts new work into a tracked runtime operation. Pausing admissions prevents new long-running work from entering the old application instance while the replacement is being prepared. Observation-only requests and already accepted event streams do not block this drain, which keeps monitoring and streaming behavior from unnecessarily holding the reload hostage.
While the Node target is draining or loading, new admissions receive a structured 503 response. That status is not just a generic crash signal; it represents a temporary development reload state where the listener remains present but is not accepting new agent, workflow, dispatch, or channel work. If changed source fails to load, the listener remains available in a failed state and can recover after the next valid edit. This is useful during iterative development because syntax errors or module loading errors do not require restarting the command. The server can remain the stable endpoint while the developer fixes the problem.
There is one important boundary to understand: reload quiescence only tracks work that Flue knows about. Work started outside Flue’s tracked operations, including detached promises created by application handlers, is not part of the drain. Developers should avoid using detached background work as a substitute for agents, workflows, schedules, or durable actions when reload safety matters. If application code starts unmanaged asynchronous work, the development server cannot reliably wait for it before replacing the loaded application. This is especially relevant for webhook handlers, channel integrations, and custom route code that might be tempted to fire and forget side effects.
Cloudflare Target Behavior
For the Cloudflare target, the command starts Vite with the official Workers integration. The local development behavior follows Cloudflare runtime conventions for bindings and environment files rather than inventing a separate Flue-only mechanism. In particular, Cloudflare runtime bindings continue to use the official dev variables, dotenv, and environment selection conventions. This matters when a project depends on Worker-specific bindings, Cloudflare Workers AI, platform secrets, queues, storage, or other Cloudflare-local behavior that should resemble the deployed worker environment as closely as possible during development.
Sources: apps/docs/src/content/docs/cli/dev.md
Choose the Cloudflare target when the code you are testing depends on Worker APIs or Cloudflare binding behavior. Choose the Node.js target when you want the Node local runtime, Node-compatible adapters, or development behavior around the in-memory Vite module runtime. Some integrations are naturally target-specific. For example, sandbox adapters that depend on Node APIs and SSH libraries belong with the Node target, while Worker integrations need the Cloudflare runtime surface. The development command exposes the target flag so the same project can make that choice explicit when configuration does not already define it.
Examples
flue dev
flue dev --target node
flue dev --target cloudflare --port 8787
flue dev --env .env.stagingStart with the bare command when working inside a standard project that has a discoverable configuration file. Add the target flag when the configuration does not select a target or when you want to verify a specific runtime path. Use a custom port when another local server already owns the default port, or when matching a platform convention such as the common Cloudflare local port. Use the environment flag to test a staging-like set of variables without changing the default dotenv file. Remember that a relative environment file path is resolved from the configuration base, not necessarily from the shell’s current directory.
A practical debugging sequence is to run the command, open the local route or client that exercises an agent or workflow, edit a source file, and watch whether the request is admitted, drained, or temporarily rejected during reload. If a request receives a structured 503 during Node development, retry after the reload finishes. If the server enters a failed state after a bad source edit, fix the file and save again. If a configuration edit breaks startup, correct the configuration and let the watcher start a new session rather than assuming the old application is still valid.
Next Steps
Use this reference together with the broader CLI overview when planning the complete development workflow. After the local server behaves correctly, move to the build reference for target-specific deployment output. If your work involves agents, workflows, channels, or sandboxes, read the corresponding guide pages so the code you test under the development server follows Flue’s durable and target-aware runtime model. For Node development, pay close attention to which operations are tracked by Flue. For Cloudflare development, verify that bindings and environment conventions match the Worker setup you expect to deploy.