diff --git a/.github/hooks/workmux-status/hooks.json b/.github/hooks/workmux-status/hooks.json new file mode 100644 index 000000000..3e69b55c9 --- /dev/null +++ b/.github/hooks/workmux-status/hooks.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "hooks": { + "userPromptSubmitted": [ + { + "type": "command", + "bash": "workmux set-window-status working" + } + ], + "postToolUse": [ + { + "type": "command", + "bash": "workmux set-window-status working" + } + ], + "agentStop": [ + { + "type": "command", + "bash": "workmux set-window-status done" + } + ] + } +} diff --git a/.webmux.yaml b/.webmux.yaml new file mode 100644 index 000000000..21dfa5dff --- /dev/null +++ b/.webmux.yaml @@ -0,0 +1,39 @@ +# Project display name in the dashboard +name: windmilldocs + +# Each service defines a port env var that webmux injects into .env.local +# when creating a worktree. Ports are auto-assigned: base + (slot × step). +# Use `source .env.local` in your .workmux.yaml pane commands to pick them up. +services: + - name: app + portEnv: PORT + portStart: 3000 # Port for the main branch (slot 0) + portStep: 10 # Increment per worktree (3010, 3020, ...) + +# Agent profiles determine how AI agents run in worktrees +profiles: + default: + name: default + + # --- Sandbox profile (uncomment to enable) --- + # Runs agents in Docker containers for full isolation. + # Requires: docker + a built image. + # sandbox: + # name: sandbox + # image: my-project-sandbox + # envPassthrough: # Env vars forwarded into the container + # - DATABASE_URL + # systemPrompt: > + # You are running inside a sandboxed container. + # Start the dev server with: npm run dev + +# --- Linked repos (uncomment to enable) --- +# Monitor PRs from related repos in the dashboard. +# linkedRepos: +# - repo: org/other-repo +# alias: other + +# --- Startup environment variables --- +# These will appear as configurable fields in the UI when creating a worktree. +# startupEnvs: +# NODE_ENV: development diff --git a/.workmux.yaml b/.workmux.yaml new file mode 100644 index 000000000..069ffcaa4 --- /dev/null +++ b/.workmux.yaml @@ -0,0 +1,21 @@ +main_branch: main + +panes: + # Agent pane — runs the AI coding assistant + - command: >- + claude --append-system-prompt + "You are running inside a git worktree managed by workmux.\n + Pane layout (current window):\n + - Pane 0: this pane (claude agent)\n + - Pane 1: dev server\n\n + To check dev server logs: tmux capture-pane -t .1 -p -S -50\n + To restart dev server: tmux send-keys -t .1 C-c 'source .env.local && PORT=\$PORT npm run start' Enter" + focus: true + + # Dev server — waits for .env.local (written by webmux) then starts + - command: >- + npm install && + until [ -f .env.local ]; do sleep 0.2; done; + source .env.local; + PORT=$PORT npm run start + split: horizontal diff --git a/docusaurus.config.js b/docusaurus.config.js index 0b6f91054..acf0c31cd 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -60,6 +60,54 @@ const config = { { to: '/terms/2025-12-01', from: '/terms' + }, + { + to: '/platform/script-editor', + from: '/product/script-editor' + }, + { + to: '/platform/flow-editor', + from: '/product/flow-editor' + }, + { + to: '/platform/app-builder', + from: '/product/app-builder' + }, + { + to: '/platform/triggers', + from: '/product/triggers' + }, + { + to: '/platform/datatables', + from: '/product/datatables' + }, + { + to: '/platform/deployment-versioning', + from: '/product/deployment-versioning' + }, + { + to: '/platform/local-dev', + from: '/product/local-dev' + }, + { + to: '/platform/workers', + from: '/product/workers' + }, + { + to: '/platform/sandboxes', + from: '/product/sandboxes' + }, + { + to: '/platform/observability', + from: '/product/observability' + }, + { + to: '/platform/rbac', + from: '/product/rbac' + }, + { + to: '/platform/self-host', + from: '/product/self-host' } ] } @@ -138,6 +186,25 @@ const config = { href: '/' }, items: [ + { + type: 'dropdown', + label: 'Platform', + position: 'left', + items: [ + { label: 'Script editor', href: '/platform/script-editor' }, + { label: 'Flow editor', href: '/platform/flow-editor' }, + { label: 'App builder', href: '/platform/app-builder' }, + { label: 'Triggers', href: '/platform/triggers' }, + { label: 'Data tables', href: '/platform/datatables' }, + { label: 'Deployment & versioning', href: '/platform/deployment-versioning' }, + { label: 'Local dev', href: '/platform/local-dev' }, + { label: 'Workers', href: '/platform/workers' }, + { label: 'AI sandboxes', href: '/platform/sandboxes' }, + { label: 'Observability', href: '/platform/observability' }, + { label: 'RBAC', href: '/platform/rbac' }, + { label: 'No-ops self-host', href: '/platform/self-host' }, + ] + }, { href: '/pricing', position: 'left', diff --git a/frontend-builder-full.png b/frontend-builder-full.png new file mode 100644 index 000000000..780ecf20f Binary files /dev/null and b/frontend-builder-full.png differ diff --git a/src/components/products/DatatablesHeroAnimation.jsx b/src/components/products/DatatablesHeroAnimation.jsx new file mode 100644 index 000000000..a987d227b --- /dev/null +++ b/src/components/products/DatatablesHeroAnimation.jsx @@ -0,0 +1,246 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { motion, useInView } from 'framer-motion'; +import { ArrowDown, Play, CheckCircle, Loader2, Database } from 'lucide-react'; + +const insertedRows = [ + { id: 1, customer: 'Alice Martin', amount: '$1,250.00', status: 'active' }, + { id: 2, customer: 'Bob Chen', amount: '$890.00', status: 'pending' }, + { id: 3, customer: 'Carol Smith', amount: '$2,100.00', status: 'active' }, + { id: 4, customer: 'Dan Wilson', amount: '$450.00', status: 'active' }, +]; + +const scriptLines = [ + { tokens: [{ text: 'import ', color: 'text-purple-400' }, { text: '* as wmill ', color: 'text-blue-300' }, { text: 'from ', color: 'text-purple-400' }, { text: "'windmill-client'", color: 'text-amber-300' }] }, + { tokens: [] }, + { tokens: [{ text: 'export async function ', color: 'text-purple-400' }, { text: 'main', color: 'text-blue-300' }, { text: '(', color: 'text-gray-400' }] }, + { tokens: [{ text: ' name', color: 'text-orange-300' }, { text: ': string, ', color: 'text-gray-400' }, { text: 'amount', color: 'text-orange-300' }, { text: ': number', color: 'text-gray-400' }] }, + { tokens: [{ text: ') {', color: 'text-gray-400' }] }, + { tokens: [{ text: ' const ', color: 'text-purple-400' }, { text: 'db ', color: 'text-blue-300' }, { text: '= ', color: 'text-gray-400' }, { text: 'wmill', color: 'text-blue-300' }, { text: '.getResource(', color: 'text-gray-400' }, { text: "'pg'", color: 'text-amber-300' }, { text: ')', color: 'text-gray-400' }] }, + { tokens: [{ text: ' await ', color: 'text-purple-400' }, { text: 'db', color: 'text-blue-300' }, { text: '.query(', color: 'text-gray-400' }] }, + { tokens: [{ text: " `INSERT INTO orders (name, amount)", color: 'text-amber-300' }] }, + { tokens: [{ text: " VALUES ($1, $2)`", color: 'text-amber-300' }, { text: ', [name, amount]', color: 'text-gray-400' }] }, + { tokens: [{ text: ' )', color: 'text-gray-400' }] }, + { tokens: [{ text: '}', color: 'text-gray-400' }] }, +]; + +export default function DatatablesHeroAnimation() { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, amount: 0.3 }); + const [phase, setPhase] = useState(0); + + // Phases: + // 1 - panels visible + code appears + run 1 starts immediately + // 2 - run 1: done → row 1 appears + // 3 - run 2: running + // 4 - run 2: done → row 2 appears + // 5 - run 3: running + // 6 - run 3: done → row 3 appears + // 7 - run 4: running + // 8 - run 4: done → row 4 appears + + useEffect(() => { + if (!isInView) return; + const timers = [ + setTimeout(() => setPhase(1), 200), + setTimeout(() => setPhase(2), 1000), + setTimeout(() => setPhase(3), 1700), + setTimeout(() => setPhase(4), 2500), + setTimeout(() => setPhase(5), 3200), + setTimeout(() => setPhase(6), 4000), + setTimeout(() => setPhase(7), 4700), + setTimeout(() => setPhase(8), 5500), + ]; + return () => timers.forEach(clearTimeout); + }, [isInView]); + + // Odd phases = running, even phases >= 2 = done + const isRunning = phase >= 1 && phase % 2 === 1; + const isDone = phase >= 2 && phase % 2 === 0; + const runState = isRunning ? 'running' : isDone ? 'done' : 'idle'; + + // Each even phase >= 2 adds a row + const visibleRowCount = phase < 2 ? 0 : Math.floor(phase / 2); + + const studioColumns = ['id', 'customer', 'amount', 'status']; + + return ( +
+ Scripts, flows, apps, and infrastructure in one place. +
+ +
+ Fix issues and open PR
+ {subtitle}
+ )} ++ Any script or workflow can be triggered by{' '} + schedules,{' '} + webhooks, + {' '}message queues, database changes, emails, and{' '} + more. +
+ +{subtitle}
diff --git a/src/data/products/app-builder.js b/src/data/products/app-builder.js new file mode 100644 index 000000000..3201e5bb4 --- /dev/null +++ b/src/data/products/app-builder.js @@ -0,0 +1,7 @@ +export const appBuilderProduct = { + slug: 'app-builder', + name: 'App builder', + headline: 'Full-code frontends connected to your backend', + description: 'Build custom UIs in React or Svelte with an auto-generated, type-safe API to backend runnables in 20+ languages.', + link: '/platform/app-builder', +}; diff --git a/src/data/products/datatables.js b/src/data/products/datatables.js new file mode 100644 index 000000000..62194b780 --- /dev/null +++ b/src/data/products/datatables.js @@ -0,0 +1,7 @@ +export const datatablesProduct = { + slug: 'datatables', + name: 'Data tables', + headline: 'SQL storage with near-zero setup', + description: 'Store and query relational data from scripts, flows, and apps. Windmill manages the database, credentials, and schema so you just write SQL.', + link: '/platform/datatables', +}; diff --git a/src/data/products/index.js b/src/data/products/index.js new file mode 100644 index 000000000..67554810a --- /dev/null +++ b/src/data/products/index.js @@ -0,0 +1,15 @@ +// Build +export { scriptEditorProduct } from './script-editor'; +export { workflowEditorProduct } from './flow-editor'; +export { appBuilderProduct } from './app-builder'; +export { datatablesProduct } from './datatables'; +export { triggersProduct } from './triggers'; +export { versioningProduct } from './versioning'; +export { localDevProduct } from './local-dev'; + +// Run +export { observabilityProduct } from './observability'; +export { rbacProduct } from './rbac'; +export { sandboxesProduct } from './sandboxes'; +export { workersProduct } from './workers'; +export { selfHostProduct } from './self-host'; diff --git a/src/data/products/local-dev.js b/src/data/products/local-dev.js new file mode 100644 index 000000000..8d49a4b5e --- /dev/null +++ b/src/data/products/local-dev.js @@ -0,0 +1,7 @@ +export const localDevProduct = { + slug: 'local-dev', + name: 'Local dev', + headline: 'Develop locally, deploy to Windmill', + description: 'Use the CLI, VS Code extension, and AI coding assistants to build scripts and flows from your own environment.', + link: '/platform/local-dev', +}; diff --git a/src/data/products/observability.js b/src/data/products/observability.js new file mode 100644 index 000000000..e525fbd97 --- /dev/null +++ b/src/data/products/observability.js @@ -0,0 +1,7 @@ +export const observabilityProduct = { + slug: 'observability', + name: 'Observability', + headline: 'Every run, logged and searchable', + description: 'Real-time logs, job metrics, run history, and alerting across all your scripts and flows.', + link: '/platform/observability', +}; diff --git a/src/data/products/rbac.js b/src/data/products/rbac.js new file mode 100644 index 000000000..97276333d --- /dev/null +++ b/src/data/products/rbac.js @@ -0,0 +1,7 @@ +export const rbacProduct = { + slug: 'rbac', + name: 'RBAC', + headline: 'Role-based access controls', + description: 'Enforce role-based access, audit logs, secret management and compliance controls.', + link: '/platform/rbac', +}; diff --git a/src/data/products/sandboxes.js b/src/data/products/sandboxes.js new file mode 100644 index 000000000..1d1ced22f --- /dev/null +++ b/src/data/products/sandboxes.js @@ -0,0 +1,7 @@ +export const sandboxesProduct = { + slug: 'sandboxes', + name: 'AI sandboxes', + headline: 'Isolated environments for AI agents', + description: 'How do I run AI agents safely in Windmill? Isolated sandboxes for Claude Code, Codex, or custom agents with persistent storage and pre-configured tools.', + link: '/platform/sandboxes', +}; diff --git a/src/data/products/script-editor.js b/src/data/products/script-editor.js new file mode 100644 index 000000000..92222965d --- /dev/null +++ b/src/data/products/script-editor.js @@ -0,0 +1,7 @@ +export const scriptEditorProduct = { + slug: 'script-editor', + name: 'Script editor', + headline: 'Code editor with built-in infrastructure', + description: 'Write a function in TypeScript, Python, Go, Bash, or SQL. Windmill gives you a UI, an API endpoint, triggers, and resource access automatically.', + link: '/platform/script-editor', +}; diff --git a/src/data/products/self-host.js b/src/data/products/self-host.js new file mode 100644 index 000000000..9bcabb37e --- /dev/null +++ b/src/data/products/self-host.js @@ -0,0 +1,7 @@ +export const selfHostProduct = { + slug: 'self-host', + name: 'No-ops self-host', + headline: 'Your infrastructure, zero maintenance', + description: 'Deploy Windmill on your own infrastructure with zero maintenance and no ops overhead.', + link: '/platform/self-host', +}; diff --git a/src/data/products/triggers.js b/src/data/products/triggers.js new file mode 100644 index 000000000..9c25dd517 --- /dev/null +++ b/src/data/products/triggers.js @@ -0,0 +1,7 @@ +export const triggersProduct = { + slug: 'triggers', + name: 'Triggers', + headline: 'Every way to start a script or flow', + description: 'How do I trigger scripts and flows in Windmill? Schedules, webhooks, Kafka, Postgres CDC, WebSockets, emails, and more.', + link: '/platform/triggers', +}; diff --git a/src/data/products/versioning.js b/src/data/products/versioning.js new file mode 100644 index 000000000..2485dddc9 --- /dev/null +++ b/src/data/products/versioning.js @@ -0,0 +1,7 @@ +export const versioningProduct = { + slug: 'deployment-versioning', + name: 'Deployment & versioning', + headline: 'Deploy in one click. Version with Git.', + description: 'Deploy in one click with built-in versioning, or connect Git for source control, local development, and CI/CD pipelines.', + link: '/platform/deployment-versioning', +}; diff --git a/src/data/products/workers.js b/src/data/products/workers.js new file mode 100644 index 000000000..956235430 --- /dev/null +++ b/src/data/products/workers.js @@ -0,0 +1,7 @@ +export const workersProduct = { + slug: 'workers', + name: 'Workers', + headline: 'Isolated workers that scale with your workload', + description: 'How do Windmill workers work? Route workloads by tag, scale horizontally, and deploy workers anywhere.', + link: '/platform/workers', +}; diff --git a/src/data/products/workflow-editor.js b/src/data/products/workflow-editor.js new file mode 100644 index 000000000..34a6ac451 --- /dev/null +++ b/src/data/products/workflow-editor.js @@ -0,0 +1,7 @@ +export const workflowEditorProduct = { + slug: 'flow-editor', + name: 'flow editor', + headline: 'Visual workflow engine with full code flexibility', + description: 'Orchestrate scripts into DAG-based flows with branching, loops, retries, approval steps, and full observability.', + link: '/platform/flow-editor', +}; diff --git a/src/landing/Hero.jsx b/src/landing/Hero.jsx index cedfe0673..596321e7f 100644 --- a/src/landing/Hero.jsx +++ b/src/landing/Hero.jsx @@ -4,6 +4,7 @@ import RadialBlur from './RadialBlur'; import HomescreenSvg from '../../static/homescreen.svg'; import Link from '@docusaurus/Link'; import { Copy, Check } from 'lucide-react'; +import HeroCTAButtons from '../components/products/HeroCTAButtons'; function CliSnippet() { const cmd = 'npm install -g windmill-cli'; @@ -73,24 +74,8 @@ export default function Hero() {+ {item.name} +
++ {item.description} +
+{desc}
+ {docLink && ( + +{subtitle}
+ )} ++ {feat.desc} +
+ {feat.content ? ( + feat.content + ) : feat.image ? ( +
+ {code}
+
+ );
+}
+
+{/* ── Local dev features data ── */}
+
+export const localDevFeatures = [
+ {
+ icon: Terminal,
+ label: 'wmill app new',
+ title: 'Scaffold a project',
+ desc: Run wmill app new to create a new full-code app. An interactive wizard prompts for the app path, framework (React 19/18 or Svelte 5), and optional data table configuration. The CLI generates the project structure, installs dependencies, and creates the raw_app.yaml config.,
+ docLink: '/docs/full_code_apps/cli_workflow',
+ },
+ {
+ icon: Play,
+ label: 'wmill app dev',
+ title: 'Local dev server',
+ desc: Run wmill app dev to start a local development server with hot module replacement. Frontend changes reload instantly. Backend runnables execute on Windmill workers with results streamed back via WebSocket. The wmill.d.ts type definitions regenerate automatically when runnables change.,
+ docLink: '/docs/full_code_apps/cli_workflow',
+ },
+ {
+ icon: Zap,
+ label: 'Type generation',
+ title: 'Auto-generated types',
+ desc: The dev server generates wmill.d.ts with typed signatures for every backend runnable. Parameter types and return types are inferred from your code. Your editor provides autocomplete and type checking when calling backend.my_runnable() without any manual configuration.,
+ docLink: '/docs/full_code_apps/frontend',
+ },
+ {
+ icon: Bot,
+ label: 'Claude Code & Codex',
+ title: 'Claude Code & Codex',
+ desc: Run wmill app generate-agents to create AGENTS.md and DATATABLES.md context files. Claude Code, Codex, and Cursor read these files to understand your project structure, available runnables, and data table schemas. Claude Code skills let AI write valid frontend and backend code for your app out of the box.,
+ docLink: '/docs/misc/guides/local_dev_with_ai',
+ },
+];
+
+{/* ── Dev mode switch section ── */}
+
+export function DevModeSection() {
+ const [mode, setMode] = useState('local');
+ return (
+ + Build full-code apps directly in the browser or use the CLI for a full local development workflow with your own editor and AI tools. +
++ Create and edit apps directly in the Windmill browser editor. File tree, code editor, runnables panel, data table config, and preview without deployment. +
+ {/* Placeholder: screenshot of the Windmill UI full-code app editor showing the file tree + on the left, code editor in the center, and runnables panel on the right. + Save as static/img/money-pages/full-code-ui-editor.webp */} +{feat.desc}
+ {feat.docLink && ( +App builder
++ Build custom UIs in React or Svelte on top of your backend scripts and flows through an auto-generated, type-safe API. +
++ The app builder lets you write a React or Svelte frontend that calls scripts and flows, also referenced as 'backend runnables'. Windmill handles execution, authentication, and hosting. You keep full control over the UI and can develop from the browser editor or locally from the CLI. +
++ Single functions in TypeScript, Python, Go, SQL, Bash, and 15+ other languages. Each script runs on an isolated worker. +
++ Multi-step workflows that chain scripts into DAGs with branching, loops, retries, and approval steps. +
+wmill.ts file that makes them callable from the frontend. Your editor gets full autocomplete and type checking out of the box. Runnables execute on workers and stream results back to the UI in real time.}
+ docLink="/docs/full_code_apps/frontend"
+ reverse
+ />
+
+ {/* ═══════════════ Datatables ═══════════════ */}
+ DATATABLES.md context file so AI assistants understand the data model when building your frontend.}
+ docLink="/docs/core_concepts/persistent_storage/within_windmill#datatables"
+ />
+ {/* TODO: screenshot of the datatables UI showing a table with columns, rows, and the schema editor. Save as static/img/money-pages/datatables.webp (approx 1200x800px) */}
+
+ {/* ═══════════════ Develop from UI or locally ═══════════════ */}
+ Deploy from the browser or CLI. Each deployment is versioned and can be synced to Git. Promote across staging and production workspaces.
+ + Check our versioning dedicated pageEvery backend runnable call is logged with its inputs, outputs, duration, and status. Run history is searchable, failed jobs show full error traces.
+ + Check our observability dedicated page{desc}
+ {docLink && ( + +Data tables
++ Store and query relational data from scripts, flows, and apps. Windmill manages the database, credentials, and schema so you just write SQL. +
++ Datatables are a workspace-scoped layer on top of your own PostgreSQL database, added as a resource. Configure it once, then any script, flow, or app can query it. Windmill manages credentials internally so they are never exposed to users. +
+schema.table syntax. Typically one or a few datatables per workspace, with schemas for logical separation.}
+ docLink="/docs/core_concepts/persistent_storage/data_tables"
+ reverse
+ />
+
+ {/* ═══════════════ Asset tracking and data lineage ═══════════════ */}
+ raw_app.yaml and query them from backend runnables with SQL. The CLI generates a DATATABLES.md context file so AI coding assistants understand the data model.}
+ docLink="/docs/full_code_apps/data_tables"
+ reverse
+ />
+
+ {/* ═══════════════ Database Studio ═══════════════ */}
+ + {flow.label} +
+{desc}
+ {docLink && ( + +Deployment & versioning
++ Every script, flow, and app is versioned on every deployment. Connect a Git repository for full source control and CI/CD. +
++ Windmill keeps an immutable history of every script, flow, and app deployment. Compare any two versions side by side, roll back in one click, or sync everything to Git. +
+{desc}
+ {docLink && ( + +Local development
++ The Windmill CLI syncs your workspace to a local folder. Edit scripts and flows in any editor, push changes back with one command. +
++ Write and test scripts in your own editor, IDE, or AI coding assistant. The Windmill CLI keeps your local files and remote workspace in sync. +
+wmill sync pull downloads your entire workspace as plain files: scripts, flows, apps, resources, triggers, and variables. Edit anything locally, then wmill sync push to deploy. Both commands support path filters to sync specific folders.}
+ docLink="/docs/advanced/cli/sync"
+ />
+
+ {/* ═══════════════ VS Code extension ═══════════════ */}
+ wmill init to generate context files and skill files for Claude Code, Cursor, and other AI tools. The generated AGENTS.md teaches assistants Windmill's file structure, script conventions, and deployment workflow. AI tools can also connect to a workspace through the MCP server to execute scripts, manage resources, and monitor jobs directly.}
+ docLink="/docs/misc/guides/local_dev_with_ai"
+ />
+
+ {/* ═══════════════ Create scripts, flows, and apps ═══════════════ */}
+ Scaffold new items locally with one command. The CLI generates the file structure Windmill needs for deployment.
+{item.desc}
+ +WM_TOKEN and BASE_INTERNAL_URL to connect to a running instance, or use mocked API files to work offline. Debug with VS Code breakpoints or JetBrains run configurations.}
+ docLink="/docs/advanced/local_development/run_locally"
+ reverse
+ />
+
+ {/* ═══════════════ Git integration ═══════════════ */}
+ wmill sync push deploys to your Windmill workspace and, when Git Sync is enabled, automatically commits the changes to your repository. Changes can also be pulled from Git via CI/CD pipelines, making Git the single source of truth. For staging and production workflows, see versioning and deployment.}
+ docLink="/docs/advanced/git_sync"
+ reverse
+ />
+
+ {/* ═══════════════ FAQ ═══════════════ */}
+ {desc}
+ {docLink && ( + +Observability
++ Real-time logs, run history, queue metrics, critical alerts, and OpenTelemetry. See everything that happens across your platform. +
++ Every script and flow execution is logged, searchable, and monitored. No external tooling or configuration required. +
+{desc}
+ {docLink && ( + +RBAC
++ Roles, folder-based ACLs, and encrypted secrets with OAuth, SAML, and SCIM. Every action is recorded in the audit log. +
++ Windmill combines role-based permissions, folder-level ACLs, and encrypted secrets to control who can see, edit, and run every resource in your workspace. +
++ Windmill provides five built-in roles that cover the full spectrum from platform administration to run-only access. No custom role configuration needed. +
+| Role | +Scope | +Description | +
|---|---|---|
| {role.name} | ++ + {role.scope} + + | +{role.desc} | +
u/alice/my_script) are private by default. Items in folders (f/team/my_script) inherit the folder's group permissions.}
+ docLink="/docs/core_concepts/roles_and_permissions#permissions-and-access-control"
+ reverse
+ />
+ {/* Placeholder image: screenshot of the share/permissions dialog on a script showing owner, group permissions (viewer/writer), and path, ~1200x800px, save as /static/img/money-pages/acl.webp */}
+
+ {/* ═══════════════ Encrypted secrets ═══════════════ */}
+ {desc}
+ {docLink && ( + +AI sandboxes
++ Run AI coding agents in sandboxes with persistent storage, pre-configured tools, and security boundaries. +
+
+ AI sandboxes combine two Windmill features to create secure, persistent environments for AI coding agents. Any script can become a sandbox with two annotations: // sandbox for process isolation via NSJAIL, and // volume: name path for persistent storage across runs. This pattern works for any agent that operates on a local filesystem: Claude Code, Codex, OpenCode, or custom agents.
+
@anthropic-ai/claude-agent-sdk. Select it from the script editor to get a pre-configured sandbox with session persistence: the session ID is stored in the volume so the agent resumes where it left off. Pass instructions and skill files as input parameters to give the agent project-specific context.}
+ docLink="/docs/core_concepts/ai_sandbox"
+ />
+
+ {/* Codex and custom agents */}
+ // sandbox for isolation, and // volume: name path for persistence.}
+ docLink="/docs/core_concepts/ai_sandbox"
+ reverse
+ />
+
+ {/* Persistent volumes */}
+ {'$workspace'} or {'$args[userId]'} to scope storage per user or workspace. Up to 10 volumes per script, with an LRU cache up to 10 GB per worker.}
+ docLink="/docs/core_concepts/volumes"
+ />
+
+ {/* Process isolation */}
+ // sandbox annotation enables it per script, or it can be forced instance-wide for all jobs. For lighter workloads, PID namespace isolation is available as a faster alternative with lower overhead.}
+ docLink="/docs/advanced/security_isolation"
+ reverse
+ />
+
+ {/* Resources and permissions */}
+ {desc}
+ {docLink && ( + +Workers
++ Route jobs by tag, scale horizontally, and deploy workers anywhere. Every job runs in its own isolated environment. +
++ When you run a script or a flow in Windmill, the code does not execute on the server. It is picked up by a worker, an isolated process that runs one job at a time. The server handles the API, UI, and scheduling. Workers handle execution. You can run one worker or hundreds, on the same machine or across continents. +
+$workspace or {'$args[argName]'} for flexible routing.}
+ docLink="/docs/core_concepts/worker_groups"
+ image={null}
+ reverse
+ />
+
+ {/* Dedicated workers */}
+ {lang.runtime}
+{lang.deps}
+{lang.lsp}
+{desc}
+ {docLink && ( + +Script editor
++ Every function you write gets a parameters UI, an API endpoint, triggers, one-click deployment, and monitoring out of the box. +
++ Windmill provides a full-featured code editor in the browser where you write scripts like in a classic IDE. Built on Monaco, it includes LSP autocompletion, linting, and formatting. +
++ From a single script, Windmill automatically generates the infrastructure to make it production-ready: +
+{item.label}
+@task and each one runs as a distinct job with its own logs and timeline. The result is the same as a visual flow, with full observability, but written entirely in the code editor.}
+ docLink="/docs/core_concepts/workflows_as_code"
+ reverse
+ /> */}
+
+ {/* ═══════════════ Built-in infrastructure ═══════════════ */}
+
+ Deploy and your script is immediately available. Each save creates a new immutable version with a unique hash.
+ + Check our versioning dedicated pageEach script runs on an isolated worker with the full CPU and memory available to it. Scale horizontally and eliminate cold starts.
+ + Check our workers dedicated page
+ Every execution is logged with its inputs, outputs, duration, and status. Run history is searchable and filterable.
+ + Check our observability dedicated page{desc}
+ {docLink && ( + +
+ {text}
+
+ Self-hosting
++ Deploy Windmill with Docker Compose or Kubernetes in minutes. Updates, scaling, and configuration are handled for you. +
++ Windmill is open source under the AGPLv3 license. We believe infrastructure software should be transparent: you should be able to read every line of code that runs your jobs, audit it, and fix it yourself if needed. Self-hosting is not a second-class option. There is no phone-home, no license server, no feature gating on the open-source edition. Your data stays on your machines, your secrets never leave your network. The Enterprise edition adds SAML/SCIM, audit logs, Git sync, and priority support on top of the same core engine. +
+docker compose up -d starts the full Windmill stack: server, workers, PostgreSQL, and LSP for language intelligence. Database migrations run automatically on startup. Caddy handles TLS termination out of the box.}
+ image={null}
+ >
+ To get started, make sure Docker is running and execute the following commands:
+Go to http://localhost and voila.
/api/health endpoint and built-in Prometheus metrics are available for monitoring.}
+ >
+ {/* Placeholder: terminal screenshot showing docker pull and restart with migration output, ~1200x800px, save as /static/img/money-pages/self-host-upgrades.webp */}
+ {desc}
+ {docLink && ( + +Triggers
++ Schedules, webhooks, Kafka, Postgres CDC, WebSockets, emails, and more. No extra configuration needed. +
++ Every trigger type works with both scripts and flows. Attach one or many triggers to any runnable. A single script can be scheduled on a cron, exposed via webhook, and listening on a Kafka topic at the same time. +
++ Single functions in TypeScript, Python, Go, SQL, Bash, and other languages. Attach any trigger to run them on events, schedules, or API calls. +
++ Multi-step workflows that chain scripts into DAGs with branching, loops, retries, and approval steps. Triggered the same way as scripts. +
++ Consume events from message brokers and streaming platforms. Each message triggers a script or flow execution with the message payload as input. +
++ Beyond the core trigger types, Windmill supports several additional ways to start executions. +
+{desc}
+ {docLink && ( + +{subtitle}
+ )} ++ {feat.desc} +
+ {feat.content ? ( + feat.content + ) : feat.image ? ( +Flow editor
++ Chain scripts into multi-step workflows with branching, loops, retries, approval gates, and full observability. +
+results.step_name or JavaScript expressions. The editor provides autocompletion for available variables and validates expressions before running.}
+ docLink="/docs/flows/editor_components"
+ reverse
+ visual={
+
+ }
+ />
+
+ {/* ═══════════════ Step types (grid) ═══════════════ */}
+ Beyond scripts, the flow editor provides built-in nodes for common control flow patterns.
+
+ Each deployment creates a new immutable version. View history, compare diffs, and promote flows from staging to production.
+ + Check our versioning dedicated pageEach flow step runs on an isolated worker with roughly 20ms of overhead between steps. Assign dedicated workers to eliminate cold starts.
+ + Check our workers dedicated page
+ Logs stream in real time. Inputs and outputs are inspectable at every step. Runs can be restarted from any step.
+ + Check our observability dedicated pageFor platform teams who deploy AI agents to production and need full control over permissions, monitoring and audit logs.
-- Get started for free on Windmill Cloud or self-host the open-source version. -
-For data teams who want reliable ETL with native DuckDB and Ducklake integrations. No Airflow or Spark clusters to manage.
-- Get started for free on Windmill Cloud or self-host the open-source version. -
-For platform teams who need to ship internal tools with production-grade observability, enterprise controls and zero infrastructure overhead.
-- Get started for free on Windmill Cloud or self-host the open-source version. -
-For ops and engineering teams who run critical jobs. Trigger any script or workflow from schedules, webhooks, Kafka, Postgres, websockets and more. With error handlers and recovery logic powered by Windmill's workflow engine.
-- Windmill supports 20+ trigger types out of the box. Run your code from any event source, no glue infrastructure required. -
-- Get started for free on Windmill Cloud or self-host the open-source version. -
-For engineering teams who need to build workflows with production-grade observability, scalability and security.
-- Get started for free on Windmill Cloud or self-host the open-source version. -
-