Skip to main content

wmill.yaml reference

wmill.yaml is the configuration file for the Windmill CLI. It lives at the root of a project, binds workspaces to Windmill instances, and controls what wmill sync pull and wmill sync push do by default. This page disects every option the CLI reads from it.

Auto-generated files

wmill init writes a fully commented starter file with every option documented inline. wmill config prints a table of every option with its type, default, and description (wmill config --json for a machine-readable version). A JSON Schema for editor autocompletion is committed at cli/wmill.schema.json.

File discovery

When the CLI needs the config it walks up from the current directory looking for wmill.yaml, stopping at the git repository root (if any) or the filesystem root. If it finds the file in a parent directory, it logs a warning and changes the working directory there — so commands always run from the project root regardless of where they were invoked.

If no file is found, most commands print No wmill.yaml found. Use 'wmill init' to bootstrap it. and fall back to the built-in defaults listed below.

Schema header

Add this header to get editor autocompletion and validation in most editors (VS Code, Zed, JetBrains) via the YAML Language Server:

# yaml-language-server: $schema=wmill.schema.json

Starter example

A typical wmill.yaml for a single-workspace project:

# yaml-language-server: $schema=wmill.schema.json
defaultTs: bun
includes:
- "f/**"
excludes: []
skipSecrets: true
nonDottedPaths: true
syncBehavior: v1

workspaces:
main:
baseUrl: https://app.windmill.dev
# workspaceId defaults to "main"
# gitBranch defaults to "main"

Options at a glance

OptionTypeDefaultPurpose
defaultTs"bun" | "deno"bunTypeScript runtime for .ts scripts
includesstring[]["f/**"]Glob patterns to include in sync
extraIncludesstring[][]Extra include patterns merged on top
excludesstring[][]Glob patterns to exclude from sync
skipVariablesbooleanfalseSkip syncing variables
skipResourcesbooleanfalseSkip syncing resources
skipResourceTypesbooleanfalseSkip syncing resource types
skipSecretsbooleantrueSkip syncing secret variables
skipScriptsbooleanfalseSkip syncing scripts
skipFlowsbooleanfalseSkip syncing flows
skipAppsbooleanfalseSkip syncing apps
skipFoldersbooleanfalseSkip syncing folders
skipWorkspaceDependenciesbooleanfalseSkip workspace dependencies
includeSchedulesbooleanfalseInclude schedules
includeTriggersbooleanfalseInclude triggers (HTTP, WebSocket, Kafka, …)
includeUsersbooleanfalseInclude workspace users
includeGroupsbooleanfalseInclude workspace groups
includeSettingsbooleanfalseInclude workspace settings
includeKeybooleanfalseInclude the workspace encryption key
parallelintegerunset (1)Parallel operations during push
locksRequiredbooleanfalseFail push if any script lacks a lock
lintbooleanfalseRun lint before push
plainSecretsbooleanfalseStore secrets in plain text
messagestringunsetDefault commit message for push
promotionstringunsetBranch whose promotionOverrides to apply
skipBranchValidationbooleanfalseSkip git-branch ↔ workspace matching
nonDottedPathsbooleanfalse (true via wmill init)Use __flow/__app/__raw_app suffixes
syncBehaviorstring (v1)v1Ownership-handling behavior version
codebasesobject[][]Bundled codebases shared across scripts
workspacesobject{}Workspace bindings and per-workspace overrides
gitBranchesobjectDeprecated — use workspaces
environmentsobjectDeprecated — use workspaces
git_branchesobjectDeprecated — use workspaces
overridesobjectRemoved — errors on read

Core options

defaultTs

  • Type: "bun" | "deno"
  • Default: bun

Runtime used when a .ts file's language cannot be inferred from its filename (*.bun.ts and *.deno.ts override this). Also used by wmill script bootstrap and by lock/metadata generation to pick the right dependency resolver.

defaultTs: bun   # or: deno

includes

  • Type: string[]
  • Default: ["f/**"]

Glob patterns limiting which local files participate in sync. Matches both pulled and pushed items. Standard glob syntax applies: * matches within a path segment, ** matches across segments.

Overridden entirely when the -i, --includes CLI flag is passed.

includes:
- "f/**" # everything under the f/ root
- "u/alex/**" # one user's personal namespace

extraIncludes

  • Type: string[]
  • Default: []

Additional patterns merged with includes (both must match for a file to be considered). Useful inside a workspace overrides: block to tighten the scope for one workspace without rewriting the base includes list. Mirrors the --extra-includes CLI flag.

excludes

  • Type: string[]
  • Default: []

Glob patterns of files to exclude from sync, applied after includes. Overridden entirely by the -e, --excludes CLI flag.

What to sync

The CLI syncs a core set of items by default (scripts, flows, apps, resources, resource types, variables, folders) and opts out of the rest (secrets, schedules, triggers, users, groups, settings, encryption key). The skip* flags remove items from the default set; the include* flags opt additional categories in.

skipVariables

  • Type: boolean
  • Default: false

Skips all variables (including any secret variables) on both pull and push. Equivalent CLI flag: --skip-variables.

skipResources

  • Type: boolean
  • Default: false

Skips resources. Equivalent CLI flag: --skip-resources.

skipResourceTypes

  • Type: boolean
  • Default: false

Skips resource type definitions. Equivalent CLI flag: --skip-resource-types.

skipSecrets

  • Type: boolean
  • Default: true

Skips only secret variables (non-secret variables still sync unless skipVariables is also set). Defaults to true so secret values never leave the Windmill workspace unintentionally. Set to false only when you have understood the security implications. Equivalent CLI flag: --skip-secrets; --include-secrets overrides this setting from the CLI.

skipScripts

  • Type: boolean
  • Default: false

Skips scripts. Equivalent CLI flag: --skip-scripts.

skipFlows

  • Type: boolean
  • Default: false

Skips flows. Equivalent CLI flag: --skip-flows.

skipApps

  • Type: boolean
  • Default: false

Skips apps. Equivalent CLI flag: --skip-apps.

skipFolders

  • Type: boolean
  • Default: false

Skips folders (their metadata and ACLs). Equivalent CLI flag: --skip-folders.

skipWorkspaceDependencies

  • Type: boolean
  • Default: false

Skips the workspace-level shared dependency manifests (package.json, requirements.txt, …) used by TypeScript/Python scripts. Equivalent CLI flag: --skip-workspace-dependencies.

includeSchedules

  • Type: boolean
  • Default: false

Includes schedules in the sync scope. Equivalent CLI flag: --include-schedules.

includeTriggers

  • Type: boolean
  • Default: false

Includes all triggers (HTTP routes, WebSocket, Postgres, Kafka, NATS, SQS, GCP Pub/Sub, MQTT). Equivalent CLI flag: --include-triggers.

includeUsers

  • Type: boolean
  • Default: false

Includes workspace user memberships. Equivalent CLI flag: --include-users.

includeGroups

  • Type: boolean
  • Default: false

Includes groups and their memberships. Equivalent CLI flag: --include-groups.

includeSettings

  • Type: boolean
  • Default: false

Includes workspace-level settings (default timezone, auto-invite, error handler, …). Equivalent CLI flag: --include-settings.

includeKey

  • Type: boolean
  • Default: false

Includes the workspace encryption key. Only relevant when cloning a workspace to a new instance and you want secrets to decrypt without re-encryption. Equivalent CLI flag: --include-key.

Sync behavior

parallel

  • Type: integer
  • Default: unset (runs sequentially with concurrency 1)

Number of changes applied in parallel during push. Values <= 0 are clamped to 1. Folder-metadata changes are always applied sequentially first (so ACLs are in place before items reference them), then the rest of the changes run through the parallel pool. Equivalent CLI flag: --parallel <n>.

locksRequired

  • Type: boolean
  • Default: false

When true, wmill sync push fails upfront if any script (or flow inline script) that should have a lockfile is missing one. Prevents accidentally pushing non-reproducible scripts. Equivalent CLI flag: --locks-required.

lint

  • Type: boolean
  • Default: false

Runs wmill lint before push. If any errors are reported, the push aborts. Equivalent CLI flag: --lint. See Lint.

plainSecrets

  • Type: boolean
  • Default: false

When pulling, stores secret variable values in clear text in local YAML instead of the default encrypted form. When pushing, treats local secret values as already in clear text. Not recommended — use only in development or when secrets are already managed by an external secret store. Equivalent CLI flag: --plain-secrets.

message

  • Type: string
  • Default: unset

Default commit-like message attached to every script, flow, and app that sync push updates in this run. Overridden by --message <string>.

promotion

  • Type: string
  • Default: unset

Name of the source workspace whose promotionOverrides to apply on top of the current workspace during push. Typical use: deploying code tested on staging to prod. Mirrors the --promotion <name> CLI flag and is typically set per invocation rather than in the file.

skipBranchValidation

  • Type: boolean
  • Default: false

Disables the safety check that requires the current git branch to match an entry in workspaces:. Handy for throwaway feature branches. Equivalent CLI flag: --skip-branch-validation.

nonDottedPaths

  • Type: boolean
  • Default: false (set to true by wmill init for new projects)

Controls how flow/app/raw-app directories are named on disk.

  • truemy_flow__flow/, my_app__app/, my_raw_app__raw_app/
  • falsemy_flow.flow/, my_app.app/, my_raw_app.raw_app/

The non-dotted form avoids edge cases on Windows and with tooling that treats .flow as a file extension. Recommended for new projects.

syncBehavior

  • Type: string (format: vN)
  • Default: v1

Version knob for sync semantics. v1 enables:

  • Ownership preservation on push: updating an existing item keeps its permissioned_as owner instead of silently rewriting it to the caller.
  • on_behalf_of_email stripped on pull: the transient "acting user" field is never written to disk.

If not set, the CLI warns that ownership preservation is disabled. If set to a version newer than the CLI supports, the CLI errors and suggests wmill upgrade.

syncBehavior: v1

Codebase bundling

codebases

  • Type: object[]
  • Default: []

List of shared TypeScript/JavaScript projects bundled and uploaded alongside scripts so multiple scripts can import from a common library. Each entry runs through esbuild (or a custom bundler) during push. See Sharing common logic and Codebases and bundles for background.

FieldTypeDescription
relative_pathstring (required)Path to the codebase directory (relative to wmill.yaml)
includesstring[]Glob patterns of files to bundle
excludesstring[]Glob patterns of files to exclude
format"cjs" | "esm"Output module format
externalstring[]Packages left unbundled at runtime
assets{ from: string; to: string }[]Static files copied into the bundle
customBundlerstringPath to a custom bundler script (replaces esbuild)
injectstring[]Files injected into every entry point
defineRecord<string, string>Compile-time constants
bannerRecord<string, string>Text prepended to output files by type (js, css, …)
loaderRecord<string, string>esbuild loader overrides by file extension
codebases:
- relative_path: ./shared
includes: ["**/*.ts"]
excludes: ["**/*.test.ts", "node_modules/**"]
format: esm
external: ["pg", "axios"]
assets:
- from: ./static
to: ./dist
define:
API_URL: '"https://api.example.com"'
inject: ["./polyfills.ts"]
banner:
js: "/* bundled by windmill */"
loader:
".png": "dataurl"
# customBundler: ./build.ts

Workspaces

workspaces

  • Type: object
  • Default: {}

Map from a human-friendly workspace name to a Windmill instance and per-workspace sync configuration. The map key doubles as the default workspace id (workspaceId), the default git branch (gitBranch), and the filename suffix for workspace-specific items.

workspaces:
dev:
baseUrl: https://dev.windmill.dev
overrides:
skipSecrets: false

prod:
baseUrl: https://app.windmill.dev
workspaceId: prod-ws # set only if it differs from the key
gitBranch: main # set only if it differs from the key
overrides:
skipSecrets: false
includeSchedules: true
promotionOverrides:
skipApps: true
specificItems:
resources: ["u/alex/prod_*"]
variables: ["u/alex/env_*"]

commonSpecificItems:
resources: ["u/alex/config/**"]
folders: ["f/env_*"]
settings: true

The key commonSpecificItems is reserved — it is not a workspace, it declares items that should be stored per-workspace for every workspace.

Per-workspace fields

FieldTypeDescription
baseUrlstringWindmill instance URL (e.g. https://app.windmill.dev). The CLI matches this against local workspace profiles so the same file works on any machine logged into the instance.
workspaceIdstringWindmill workspace id. Defaults to the map key.
gitBranchstringGit branch name this workspace is auto-selected on. Defaults to the map key.
overridesPartial<SyncOptions>Any top-level sync option, overridden when this workspace is active.
promotionOverridesPartial<SyncOptions>Overrides applied when this workspace is the source of a --promotion push. Falls back to overrides if unset.
specificItemsobjectItems stored per-workspace on disk (see below).

specificItems and commonSpecificItems

Both share the same shape. Items whose path matches one of these patterns get the workspace name inserted into the local filename (database.resource.yamldatabase.prod.resource.yaml on disk). Full details in Workspace-specific items.

FieldTypeDescription
variablesstring[]Variable path patterns
resourcesstring[]Resource path patterns
triggersstring[]Trigger path patterns
foldersstring[]Folder path patterns
settingsbooleanTreat settings.yaml as per-workspace
schedules pattern list

The internal SpecificItemsConfig_Yaml type also accepts a schedules key, but it is currently not part of the JSON Schema and is reserved for future use. Prefer triggers for now.

Workspace resolution order

  1. --workspace <name> — explicit CLI override.
  2. Current git branch — the first entry whose effective gitBranch (the gitBranch field, or the map key if unset) matches git rev-parse --abbrev-ref HEAD.
  3. Local profile — the workspace selected via wmill workspace switch.

Settings resolution priority

When multiple layers define the same option, the highest-priority one wins:

  1. CLI flags (highest).
  2. promotionOverrides of the workspace pointed to by --promotion.
  3. overrides of the resolved workspace.
  4. Top-level options in wmill.yaml.
  5. Built-in defaults (lowest).

Deprecated and removed keys

The CLI reads the legacy keys below and normalizes them to workspaces in memory, emitting a one-time deprecation warning. Run wmill config migrate to rewrite the file in the new format — it preserves every field (baseUrl, workspaceId, overrides, promotionOverrides, specificItems, commonSpecificItems).

gitBranches (deprecated)

Legacy multi-branch map. Keys were git branch names (not freeform workspace names). Has the same per-entry shape as workspaces. Priority over environments and git_branches if multiple legacy keys are present.

environments (deprecated)

Legacy single-branch alias of gitBranches intended for promotion workflows on one branch. Same per-entry shape. Only read if workspaces and gitBranches are both absent.

git_branches (deprecated)

Snake-case variant of gitBranches, kept for historical configs. Lowest priority among the legacy keys.

overrides (removed)

Was previously a top-level key holding per-branch overrides. Reading a non-empty overrides now errors:

❌ The 'overrides' field is no longer supported.
The configuration system now uses workspace-based configuration.
Please delete your wmill.yaml and run 'wmill init' to recreate it with the new format.

Move the settings into the matching entry under workspaces: (overrides: lives inside a workspace entry, not at the top level).

Fields not meant for wmill.yaml

The internal SyncOptions type also contains fields backing one-off CLI flags (yes, dryRun, skipPull, failConflicts, json, jsonOutput, stateful, raw). Setting these in wmill.yaml is technically possible but discouraged — they describe one invocation, not a project's baseline. In particular:

  • raw is now the default on push. The CLI prints --raw is now the default, you can remove it as a flag if set.
  • stateful enables .wmill/ state tracking. The file-based alternative (sync from a clean checkout every time) is recommended instead.

See also