Configuration

Flue configuration is the small contract between a project author and the CLI. A flue.config.* file tells Flue which runtime target to build for, where the project root is, and where generated build output should be written. That matters because Flue applications are discovered from source modules, then built into either a Node.js server or a Cloudflare Workers-compatible application. The configuration reference is intentionally narrow: the authored config accepts only the options documented here, while lower-level discovery, validation, and source-root resolution are handled by the CLI implementation.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts

Purpose and Scope

Use this page when you need to author or review flue.config.ts, decide whether a project should target Node or Cloudflare, move Flue source modules into a custom root, or understand why the CLI selected a particular config file. In Flue terminology, the authored configuration is UserFlueConfig: the file-level object a developer writes. The resolved configuration is FlueConfig: the absolute, validated shape consumed by the rest of the CLI after defaults and path resolution have been applied. This separation lets project files stay concise while build and development commands receive normalized paths and a concrete target.

Configuration is not a general plugin system. The source and docs both present it as a small, strict interface for build selection and project layout. UserFlueConfig exposes target, root, and output, and the validation schema is a strict object with exactly those optional fields. That design prevents configuration files from silently accumulating unsupported options and keeps the public @flue/cli/config subpath focused on what authors need: defineConfig, UserFlueConfig, and FlueConfig. If you need to configure application behavior, agent definitions, routes, tools, skills, database adapters, or channels, do that in source modules rather than by extending the Flue config object.

Sources: packages/cli/src/lib/config.ts, packages/cli/src/config.ts

Relevant Source Files

  • apps/docs/src/content/docs/reference/configuration.md - Reader-facing reference for accepted config filenames, target, root, output, Vite configuration, and defineConfig().
  • packages/cli/src/lib/config.ts - Core implementation for authored and resolved config types, defineConfig(), validation, config-path discovery, and path-resolution behavior visible in the supplied source.
  • packages/cli/src/config.ts - Public @flue/cli/config subpath that re-exports only the authoring API and related types for project config files.
  • packages/cli/src/lib/config-paths.ts - Central list of supported config basenames and helper logic for candidate config paths.

Authoring a Config File

The recommended config file is flue.config.ts. Import defineConfig() from @flue/cli/config to get type checking and editor completion while returning the object unchanged. This helper does not transform the config; it exists so TypeScript-aware editors can guide authors toward the accepted shape. The public subpath deliberately re-exports only the authoring surface, so project files do not need to depend on internal CLI discovery functions. TypeScript configuration files are loaded directly by Node and therefore must use erasable TypeScript syntax rather than build-time-only language features that Node cannot execute directly.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts, packages/cli/src/config.ts

import { defineConfig } from '@flue/cli/config';
 
export default defineConfig({
  target: 'node',
});

Flue searches for configuration files using a fixed priority order. The supported basenames are flue.config.ts, flue.config.mts, flue.config.mjs, flue.config.js, flue.config.cjs, and flue.config.cts. TypeScript comes first because Flue projects are TypeScript-oriented, and the remaining extensions mirror Vite-style JavaScript and module formats. When an explicit config file is provided, candidate resolution returns only that resolved path. When no explicit file is provided, candidates are formed by joining the selected search directory with each supported basename in priority order.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config-paths.ts

Configuration Options Reference

OptionAuthored typeDefaultMeaning
target`'node''cloudflare'`none
rootstringDirectory containing the selected flue.config.*, or the selected search directory when no config file is loadedProject root used to locate Flue source modules. Must not be empty.
outputstring<root>/distBuild output directory. Must not be empty.

target chooses the runtime family. node builds a Node.js server, while cloudflare builds a Workers-compatible application. The implementation models this as a picklist of exactly those two strings. There is no documented default target, because choosing a runtime changes the generated application and development server behavior. If the file omits target, the CLI can still be driven by a command-line target override; otherwise, resolved CLI configuration needs a concrete value before build or development work can continue.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts

root controls where the project is considered to begin. When written in a config file, a relative root resolves from the directory containing that config file. The implementation comments also distinguish relative inline values, which resolve from the caller's working directory. After the root is known, Flue chooses the source-module location by looking for the first matching directory in this order: <root>/.flue, then <root>/src, then <root>. This convention lets projects keep Flue modules in a hidden framework directory, a conventional source directory, or the project root without requiring an extra option.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts

output controls where build artifacts are written. Its default is <root>/dist, but relative values authored in a config file resolve from the config file's directory, not from root. That distinction is important in repositories where the config file and project root are not the same directory. Both root and output are validated as non-empty strings, so an empty path is treated as a configuration error rather than falling back to a default. The resolved FlueConfig stores root, sourceRoot, and output as absolute paths for downstream CLI code.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts

Discovery and Resolution Semantics

Config discovery starts from a normalized working directory. If a user passes an explicit configFile, the CLI resolves that path relative to the normalized cwd unless it is already absolute. The visible implementation treats a missing explicit config as an error, because an explicitly named file that does not exist is likely a typo rather than a valid no-config state. Without an explicit file, the CLI iterates through the supported basenames in priority order and checks for the first existing candidate. The helper in config-paths.ts provides the same candidate ordering for consumers that need the list of possible paths.

Sources: packages/cli/src/lib/config.ts, packages/cli/src/lib/config-paths.ts

The resolved configuration is richer than the authored object. UserFlueConfig is the optional authoring shape, but FlueConfig requires a target and absolute paths for root, sourceRoot, and output. sourceRoot is not authored directly; it is derived from root through source-root discovery. This is why the docs point readers to Project Layout for source-module placement rather than adding a separate configuration field. It also means build plugins, generated servers, and development runtime code can consume a stable resolved shape without reinterpreting project-layout conventions.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts

Vite Configuration

Flue configuration can also export a named vite value to pass native Vite configuration to development servers. The docs recommend using Vite's own defineConfig() helper for that named export while keeping the default export as Flue configuration. This keeps concerns separate: the default export answers Flue-specific questions such as target, root, and output, while the named Vite export customizes compatible Vite options. Flue still owns the Vite project root, server mode, host, port, and internal plugins, so application authors should not rely on Vite options that conflict with those framework-controlled settings.

Sources: apps/docs/src/content/docs/reference/configuration.md

import { defineConfig as defineViteConfig } from 'vite';
import { defineConfig } from '@flue/cli/config';
 
export default defineConfig({
  target: 'node',
});
 
export const vite = defineViteConfig({
  server: {
    watch: {
      ignored: ['**/evals/results/**'],
    },
  },
});

The practical rule is to use the Vite export for development-server details that Flue does not own. For example, the official reference shows ignoring evaluation result files from watch behavior. Those options are merged into both Node and Cloudflare development servers where applicable. By contrast, target selection and output placement belong in the Flue default export because they are consumed by the CLI before and during build orchestration.

Sources: apps/docs/src/content/docs/reference/configuration.md

System-to-Code Mapping

Reader concernPublic surface or implementationSource path
Type-safe project config authoringdefineConfig(config: UserFlueConfig): UserFlueConfigpackages/cli/src/lib/config.ts
Public import path@flue/cli/config re-exporting defineConfig, FlueConfig, and UserFlueConfigpackages/cli/src/config.ts
Accepted file namesCONFIG_BASENAMES in priority orderpackages/cli/src/lib/config-paths.ts
Accepted authored optionsStrict schema for target, root, and outputpackages/cli/src/lib/config.ts
Source module locationDerived sourceRoot from root using .flue, src, then root conventionspackages/cli/src/lib/config.ts

This mapping is useful when debugging a configuration issue. If TypeScript reports an unsupported option in flue.config.ts, start with the UserFlueConfig type and the strict schema. If the wrong file is being loaded, compare the file name against CONFIG_BASENAMES and remember that earlier names win. If generated output appears in an unexpected directory, check whether the output value is relative to the config directory rather than to root. If source modules are not discovered, confirm the physical directory order under root: .flue, then src, then the root itself.

Sources: packages/cli/src/lib/config.ts, packages/cli/src/config.ts, packages/cli/src/lib/config-paths.ts

Next Steps

For a new project, begin with the smallest valid config: set target to node or cloudflare, leave root and output at their defaults, and place authored modules under .flue or src according to the project-layout conventions. Add root only when the config file lives outside the intended project boundary. Add output only when build artifacts need to be separated from the default dist directory. If local development needs watch exclusions or related Vite behavior, export a named vite config and avoid overriding Flue-owned server settings.

Sources: apps/docs/src/content/docs/reference/configuration.md, packages/cli/src/lib/config.ts