Skip to main content

Migrate from Airplane to Windmill

The migration from Airplane to Windmill is made easy by the same developer-first approach that both products adopt. The main concepts are very similar, and the vast majority of what you use in Airplane is possible in Windmill.

Windmill offers 3 months of Enterprise Edtion to Airplane users. To get started, contact us at [email protected].

The migration from Airplane is included in the Enterprise Edition. Upon subscription, we can organize a migration session from Airplane to Windmill. We can also recreate your scripts, flows, and applications from exports and screenshots of Airplane, in collaboration with you if your instance is self-hosted. If you are interested, contact us at [email protected].

The following section covers the main concepts of Windmill, starting from those of Airplane. To see all the Core Concepts of Windmill, see:


Windmill is open source, and can be self-hosted to access all of its features locally. You have the option to self-host Windmill on your own infrastructure using Docker for smaller setups or a Helm chart for larger, production use-cases.

The platform will continue to operate autonomously, even in the event of a discontinuation of the original software.

Version Control & Deployments

Deploying scripts is simple in both Airplane and Windmill. Basically you write one script (”Task” in Airplane) in an environment, and then you can promote it to another environment. The main advantage you get from this process is that your script can use a variable / resource, for example to reference a DB connection / URL, which is present in both environments but with different values.

This way you can test your script in your dev environment on a dummy DB, then once you promote it to prod, it starts running on the real data.



In Airplane, you declare as many "Environments" as you need, and set one to be the default one. Usually the Prod one. Then for each "asset" (task or view), you manually "promote" them to your Prod environment.
Effectively, this will copy the content of the script to the prod environment, nothing more.

Windmill does not have the concept of environment per-se. Here is how you it works in Windmill.

Deploy to Prod

Deployments in Windmill are commonly done from the same workspace using the Draft and Deploy buttons.

For finer control, you might want to deploy to a prod workspace from a staging area. Here are the options:

Deploy to Staging/Prod Web UI

From a workspace in Windmill, you can deploy a script/flow/resource/variable and all its dependencies to another workspace. This feature implies having at least 2 workspaces.

Deploy to Staging/Prod Web UI is Cloud plans and Self-Hosted Enterprise Edition only.

More details at:

Deploy to Prod using a Git Workflow

Windmill integration with Git repositories makes it possible to adopt a robust development process for your Windmill scripts, flows and apps.

The process is as follows:

  • Users iterate and make their changes in a "staging" Windmill workspace.
  • Every time a Windmill App, Flow or Script is deployed to that workspace (via Windmill's UI), Windmill automatically commits it to this repo and creates one branch per app/flow/script.
  • On every commit from Windmill, PRs are automatically created via a GitHub Action. Approved GitHub users can review and merge those PRs.
  • Every time a PR is merged, another GitHub Action automatically deploys the change to a "production" Windmill workspace.

This gives the flexibility to fully test new Windmill scripts, flows and apps, while having them version-controlled and deployed in an automated way to the production environment.

Deploy to Prod using a Git Workflow is Cloud plans and Self-Hosted Enterprise Edition only.

More details at:

Using Windmill CLI in GitHub Actions

Finally, you can define your own GitHub Actions to pull Windmill workspace regularly from GitHub using Windmill CLI. To automatically deploy a PR to the Windmill workspace, the push-on-merge.yaml can be used.

And another GitHub Action can be created to regularly pull Windmill workspace to the GitHub repo using Windmill CLI. This action can be run on a schedule to keep the repo and the workspace in sync.

Version Control

Manage changes to scripts workflows, apps and resources using commits & push on remote repositories.

Git Sync

From the workspace settings, you can set a git_repository resource on which the workspace will automatically commit and push scripts, flows and apps to the repository on each deploy.

The first 5 minutes of this video show how to set up a Git repository for a workspace (Git Sync - workspace mode), the rest of the video shows how to use it to deploy to a Prod workspace using GitHub Actions (Git Sync - item mode):

Git Sync is Cloud plans and Self-Hosted Enterprise Edition only.

More details at:

CLI Sync

You can use Windmill CLI to sync workspace to a git repository.

More details at:

Tasks / Scripts



Tasks are functions that anyone on your team can execute. A task can be a SQL query, custom TypeScript/JavaScript/Python, or even a wrapper around a REST API call. Users can execute tasks through a simple Airplane-generated UI, complete with rich components and validation.

Windmill’s equivalent of Tasks are Scripts. Scripts are the basis of all major features (they are the steps of flowslinked to apps components, or can be run as standalone).

A Script can be written in: TypeScript (Deno & Bun)PythonGoBash or SQL. Its two most important components are the input JSON Schema specification and the code content.

Scripts in Windmill must fit Windmill's execution model: a main function with typed parameters used to infer the script's inputs in an autogenerated UI.

Scripts can are created from within Windmill app (cloud or self-hosted). Then can be modified and tested from the platform or VS Code.




Schedules allow you to automatically run tasks on a recurring cadence using CRON expressions.

Just like Airplane, Windmill provides schedules that allow to run scripts & flows at a given frequency, just like CRON but with a user interface and control panels.

Schedules are set from the UI, either directly from the scripts and flow settings, or from a dedicated Schedules menu in Windmill platform. For each schedule, the flow or script’s arguments are filled.

All schedules can be attached to a custom Error Handler (or workspace error handler) and Recovery Handler for when the schedule was successful again. Also, Retries can be set for every schedule, they allow to retry execution upon error, either at constant or exponential intervals.

Permissions & RBAC



Airplane's permissioning system allows for fine-grained, role-based access control using groups and roles.

Windmill provides a very similar comprehensive roles and permissions system that allows you to manage access within your Windmill instance and workspaces. Here is how permissions work in Windmill:

  1. Users: Users are identified by their email and have unique usernames within each workspace they belong to.
  2. Workspace: Each entity in Windmill, including users, belongs to a workspace. Workspaces are partitioned in Windmill's database to prevent data leakage. A user who creates a workspace becomes its admin and can invite others .
  3. Roles in Windmill: Users can have different permission levels:
    • Superadmin: Has the highest level of access, managing the entire Windmill instance and all workspaces by default .
    • Admin: At the workspace level, they manage specific workspaces and all entities within. At the folder level, they manage access and permissions for folder contents .
    • Developer: Can execute, view, and create/edit scripts, flows, and apps within a workspace.
    • Operator: Limited access to execute and view scripts, flows, and apps within their allowed paths or folders .
    • Anonymous app viewers: Can view Windmill apps without being a user if they have the secret URL but cannot execute scripts and flows .
  4. Permissions and Access Control: Windmill uses an Access Control List (ACL) for fine-grained permissions. Admins, Writers, and Viewers have varying access levels to entities, and ACLs are defined by the item's path, which includes user space and folders .
  5. Groups and Folders: Groups classify users with shared permissions, while Folders group items and assign role-based access. Groups can be included within folders to manage access control efficiently.




Airplane Tasks make it possible to orchestrate processes that span multiple steps and engage with human operators, thanks to execution of tasks from within other tasks.

Windmill embeds a native way to create workflows, in the form of DAGs (Directed Acyclic Graphs) that represent dependencies between steps in the OpenFlow format.

The Windmill Flow Editor is designed as a low-code builder that allows orchestrating scripts (fetched from the workspace or WindmillHub, or written directly inline) with branches or for loops, and adding configurations to each step or at the flow-level (human-in-the-loop, retries, cache, concurrency limits, error handling, etc.).

From that, can orchestrate any script together, from a simple SQL query to sending Slack or Email messages, or any type of code interacting with APIs.

It is also possible to define the flows as code in YAML through the VS Code extension.

Approval flows & Prompts



Airplane used prompts to gather input from operators through parameter forms. Approvals can be made conditional by wrapping them in an if clause to the prompt reviewer. \

For approval flows, Windmill uses Approval Steps that will suspend the execution of a flow until it has been approved through the resume endpoints or the approval page by and solely by the recipients of the secret urls.

You can then have a Windmill equivalent of prompts with a custom form to your approval step that the UI shows to operators when running:

Custom UIs



Airplane developed Views, which is a React component library that integrates with other Airplane features.
Views are defined as code.

Windmill also allows for the creation of customized UIs to build internal dashboards, customer-facing apps, etc. Windmill adopts a different approach as the UIs are created in the App Editor, a low-code drag-and-drop builder.

The user can pick from a library of over 60 components and link them to custom code (scripts in all covered languages or flows).

Users can also create their own React components that integrate with the rest of the application. It is also possible to import your own applications in React, Vue, or Svelte and have them interact with all your Windmill elements.

Connecting your data



Airplane uses Resources that allow you to easily configure connections to external systems like databases and APIs and use them in your tasks and runbooks.

Secrets are managed through config variables that are stored encrypted at rest.

Windmill employs the exact same concept of Resources, which are essentially rich objects in JSON that allow for the storage of configuration and credentials. Each Resource has a Resource Type that defines the schema the resource of this type needs to implement. Schemas implement the JSON Schema specification.

The platform contains more than 70 integrations created by the community on WindmillHub and approved by the Windmill team. It is very easy to create your own Resource Types to interact with new external systems.

Just like Airplane, secrets are handled with Variables. Variables are dynamic values that have a key associated to them and can be retrieved during the execution of a Script or Flow. All Variables (not just secrets) are encrypted with a workspace specific symmetric key to avoid leakage. There are two types of Variables in Windmill: user-defined and contextual.

Resources can embed variables, for example creating a new PostgreSQL resource will create for field password a variable found at the same path.

Auditing & Observability



Task executions (runs), changes to resources, changes to team members, and other important events are captured in Airplane's audit log, accessible from Airplane’s Activity page.

Windmill provides 2 ways to monitor activity.

Runs Menu that allows to visualise all past, current and future (scheduled) runs with filters (datetime, user, status, argument, results, etc.)

Audit Logs provided for every operation and action that has side-effects. These logs capture the user responsible for the operation and include metadata specific to the type of operation.

By the end of January, Windmill will also support streaming logs to log management services (Datadog, Splunk, AWS CloudWatch etc.)

Routing jobs to different VPC / Worker Groups / Queues / Tags



In Airplane it is possible to assign jobs to a given VPC using run constraints.

In Windmill, there is a concept of Worker groups and tags which correspond to queues. Worker groups are assigned to listen to those different queues.

Tags are assigned to scripts but they can also be dynamically overriden by API or in the UI when the script is executed:

The tag can also be dynamic (tag-$workspace) where $workspace is replaced with the workspace_id so that one can define one worker group that listen to ‘tag-prod’ and another to ‘tag-staging’ even though it is the same tag that is assigned to the script but on different workspaces.


Migrate from Airplane a Scheduled Script Using Secrets

Airplane Tasks have their equivalent in Windmill Scripts. They can be built from the Script Editor or from VS Code.

This tutorial covers how to migrate from Airplane to Windmill a scheduled script connected to Discord using resources and variables.

Migrate an Airplane View to Windmill and Make it an App

In Airplane, views are custom UIs made in react. This tutorial covers from an Airplane View how to build the equivalent App using Windmill low-code App Editor.