My first questions with any new tool of this kind is immediately:
- Can I run/validate branch versions of the scripts non-destructively, for example as part of pre-merge checks in an IaC CD workflow?
- Can I run my scripts locally without a lot of drama, while developing?
If the answer to either of these questions is no, then the tool is the moral equivalent of directly editing PHP files on the prod machine, unless you're committed to deploying an entire second instance of the tool for staging/dev purposes.
We are fully open-source (AGPLv3) with just one ee plugin for syncing the cache of the workers at large scale (more on that below). You can deploy it on a small ec2 instance with our docker-compose or on very large clusters with our helm charts: https://docs.windmill.dev/docs/advanced/self_host
We are an onion of 3 layers, which are usually separated verticals and the closest services we replace in each vertical are: Lambda + n8n/temporal + Retool:
- Workers implemented in Rust that can run any scripts from source in python/typescript(deno)/go/bash. They are extremely efficient, with most typescript scripts being able to run in 40ms e2e. This can be seen as a self-hosted lambda except it works very differently. Lambdas spawn microvms using firecracker and launch http servers within those micro-vms. We run the scripts bare (with isolation using nsjail on our multi-tenant instance) but cache very aggressively the dependencies. For instance, in python we analyze the dependencies using the AST: https://github.com/windmill-labs/windmill/blob/main/backend/..., infer the dependencies from there, have them go through pip-compile to generate a lockfile (and cache the result), then create a pathset similar to how virtualenv behave with the version of each dependency locked. For typescript, we leverage the very well made immutable deno cache. The cache works well but if you scale your cluster to more than 10 workers, the likelihood of having your worker see dependencies for the first time increase, which is why we reimplemented a pip scheme backed by s3 that is extremely fast (we do not compress, just tar individual wheels and s3 is very fast on local networks). For all the supported languages, we parse the signatures of the main function to infer the corresponding json schema of the payload to trigger them, and from that jsonschema we can then generate automatically the UI and infer the input shape required in the flows for that particular step.
- A workflow engine re-implemented from scratch which can be seen as a distributed FSM and whose state is stored in postgresql and every transition done through postgres transactions. Every worker is picking a job and progressing the fsm at completion. The full spec is at: https://docs.windmill.dev/docs/openflow. We support branches, for loop, suspend/sleep, approval steps, sharing the same folder between steps and everything you would expect from a temporal like engine (retries, error handlers).
- A dashboard/app builder that is very similar to Retool but much faster because it's implemented in Svelte and which can also run python scripts directly leveraging the 1st layer. We also support full react apps: https://github.com/windmill-labs/windmill-react-template
We have a CLI that allows you to sync from github directly: https://github.com/windmill-labs/windmill-sync-example or your local filesystem. Our scripts are absolutely normal scripts so there is no lock-in, and they are executable locally https://docs.windmill.dev/docs/advanced/local_development so you do not have to use our webeditor if you do not want to but our editor supports pyright and deno lsp through our dedicated backend communicating to monaco using websockets.
We also support worker groups to run some jobs on hardware accelerated machines (GPU) and a lot of other features (oauth syncing of the resources, schedules, granular permissioning, groups and folders).
Every script/flow deployed has a dedicated webhook endpoint to run synchronously and asynchronously. Scripts are never overwritten, they keep a lineage of hash for each version and have per-hash dedicated webhook to ensure their behavior never change.
We also have a hub for sharing re-usable scripts https://hub.windmill.dev to be used in flows to have some of the same convenience you can find in Pipedream or Zapier.
Our closest alternative would be Airplane.dev, but they're not open-source, not self-hostable air-gapped, less performant, less-featured and much more expensive. You can self-host us fully free.
We are used in production at scale in clusters of 50 nodes+ and thanks to the reliability of Rust and Postgresql have had no downtime to report.
I'm a solo founder, YC S22. The MVP got some attention at the very beginning: https://news.ycombinator.com/item?id=31272793 but was very bare. Now we're ready to bring this to the next level and enable all engineers to spend more time building and less time reinventing the wheel thanks to it :)
2) yes, https://docs.windmill.dev/docs/advanced/local_development
1) since you can run them locally, you can also run tests as part of your CI. You can also deploy a full windmill as part of your CI, deploy to that local instance, run some e2e tests by calling the webhooks, and then only deploy once those work.
Note that we have a full drafting system baked in into the webeditor as well: https://docs.windmill.dev/docs/core_concepts/draft_and_deplo... and have support for folders with different permissions and you can create workspaces so you may implement dev/staging/prod in any fashion you like (different folder, workspace, instances)
One nitpick: In my humble opinon, you should switch from Discord chat to Zulip.
It's completely open-source (Apache 2, self-hostable, free full cloud plan for open-source projects) and has an excellent threads-first (called "topics" model): https://zulip.com/why-zulip/
It can run fully in the browser, but it has desktop and mobile clients as well.
It also supports public channels which AFAIK discord doesn't. So you can link to specific messages inside a GitHub issue and anyone who doesn't even have an account can see the relevant messages and context.
Interestingly it's what the Rust language team (and community) uses for comms: https://rust-lang.zulipchat.com
(I'm not affiliated in any way with Zulip btw, I just love the product)
It's different in those fashions. Windmill can run python but also typescript, go and bash. Airflow/Prefect etc uses code annotation which mean the code is actually specific to the platform. We actually have the steps be directly scripts/code with a main function, and then have a low-code builder to compose them into powerful workflows. That low-code builder produces a yaml like that one: https://github.com/windmill-labs/windmill-sync-example/blob/... which you could theoretically write by hand.
The low-code builder is intuitive and similar to n8n except it has the feature-set of the above framework. It's easy to test the individual steps or to test the whole flow. The workflow engine is very efficient and running 50 steps will essentially have about 1s overhead total, and the steps are executed bare so it will take as much time as if you were running them without windmill on your node directly. They can be hardware accelerated easily in that fashion. We also support some features borrowed from temporal like the ability to suspend at no-cost flows until they are resumed by an external event such as an approval from slack.
What does windmill do that script-server can't? Or is windmill targeting a completely different area, and is thus irrelevant to me and my pile of 500+ python, shell, Golang, and java bin dir.
One suggestion: I think you could do improve the docs by (a) providing a direct comparison to Airplane and (b) providing more code-oriented documentation.
Most of you docs highlight the web editor which, frankly, I have little interest in. I want to write my scripts and views in my IDE and store them in GitHub. This is something Airplane really nails: their docs are clearly about how to use this as a developer. Compare your flows quick start [0] with their tasks quick start [1] and it really feels like Airplane is more suited to a developer audience. I'm worried I will be locked into static control flow with yours, whereas Airplane makes it clear I can do ~any code I want, as long as it runs in Temporal.
Of course, totally fair if you are trying to target more no-code use cases.
[0]: https://docs.windmill.dev/docs/getting_started/flows_quickst... [1]: https://docs.airplane.dev/getting-started/orchestration
For the temporal thing, that's absolutely fair and completely understand the worry but since most workflows are about the steps and not the glue between them, you will be able to reuse most of your code. However, temporal is quite an heavy format for writing workflows so of course it will still be a bit of work.
Our views support our retool like builder but also full react apps, or svelte, or vue, or anything that can compile to an iife. The example provided above can be iterated on with just a simple 'npm run dev': https://github.com/windmill-labs/windmill-react-template
interview highlights (4min): https://www.youtube.com/watch?v=_jsl0k7LX34
full interview (33min): https://www.youtube.com/watch?v=rPLVwFRjw7o
2. The webhook can contain a payload, and you can but the suspend step into a for-loop. You could literally say, for-loop forever the suspend until the result of the suspend step (which can be the result of the evaluation of the webhook payload by your rule is true). For that, you will need to use another primitive that we expose which is "Break" that will break out of the for-loop
3. I'm a bit unsure of the term synchronous call. We have a long list of APIs https://app.windmill.dev/openapi.html#/ and you fetch the status of the flow or trigger a flow in a synchronous http webhook to wait for the result. As to force the state of the workflow. We do not expose something like that but it could be added easily.
Happy to chat if we could be a good fit for your needs: ruben@windmill.dev
For the second part, you can just iframe the whole public app and we will provide a React component soon.
See https://github.com/windmill-labs/windmill-sync-example
it should be trivial to push that to a self-hosted setup if you need it.
I have not tried to take my entire workspace from self-hosted to cloud. But I have been exporting and importing individual scripts/flows/apps from self-hosted to cloud.
(no affiliation, just a happy user)
https://docs.windmill.dev/docs/core_concepts/webhooks#trigge... seems to cover a hello world for hooks.
And you would do exactly what you suggest in the last paragraph
or maybe just the Small Clojure Interpreter: https://github.com/babashka/SCI if it's a requirement for proper sandboxing