Windmill is the open-source platform that turns your scripts into internal tools, workflows, and scheduled jobs. Write TypeScript/Python/Go, get a UI and API automatically.
What Is Windmill?
Windmill takes your scripts and generates: auto-generated UIs, REST API endpoints, approval flows, scheduled jobs, and webhook handlers.
Quick Start
# Docker Compose
docker compose up -d
# Open http://localhost:8000
Write a Script
// Windmill auto-generates a form UI from the function signature
export async function main(
customer_id: string,
start_date: string,
end_date: string,
include_refunds: boolean = false
) {
const orders = await getOrders(customer_id, start_date, end_date)
const filtered = include_refunds ? orders : orders.filter(o => o.status !== 'refunded')
return {
customer_id,
total_orders: filtered.length,
total_revenue: filtered.reduce((sum, o) => sum + o.amount, 0),
orders: filtered,
}
}
This automatically gets a web form with inputs for each parameter, plus a REST API endpoint.
Workflows (DAG)
// Step 1: Fetch data
export async function fetchUsers() {
const resp = await fetch('https://api.example.com/users')
return resp.json()
}
// Step 2: Process (runs after step 1)
export async function processUsers(users: User[]) {
return users.filter(u => u.active).map(u => ({ ...u, score: calculateScore(u) }))
}
// Step 3: Send notifications (runs after step 2)
export async function notifyUsers(processed: ProcessedUser[]) {
for (const user of processed) {
if (user.score > 80) {
await sendEmail(user.email, 'You are a top user!')
}
}
return { notified: processed.filter(u => u.score > 80).length }
}
REST API
export WINDMILL_TOKEN="your-token"
# Run a script
curl -s -X POST 'http://localhost:8000/api/w/main/jobs/run_wait_result/p/f/scripts/my_script' \
-H "Authorization: Bearer $WINDMILL_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"customer_id": "cust-123", "start_date": "2026-01-01", "end_date": "2026-03-30"}'
# Run a flow/workflow
curl -s -X POST 'http://localhost:8000/api/w/main/jobs/run_wait_result/p/f/flows/my_workflow' \
-H "Authorization: Bearer $WINDMILL_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"trigger": "manual"}'
# Schedule a job (cron)
curl -s -X POST 'http://localhost:8000/api/w/main/schedules/create' \
-H "Authorization: Bearer $WINDMILL_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"path": "f/scripts/daily_report", "schedule": "0 9 * * *", "timezone": "UTC"}'
Supported Languages
- TypeScript/JavaScript (Deno runtime)
- Python 3
- Go
- Bash
- SQL (direct database queries)
- GraphQL
Free Tier (Self-Hosted)
| Feature | Community (Free) | Pro |
|---|---|---|
| Workers | Unlimited | Unlimited |
| Scripts | Unlimited | Unlimited |
| Users | 50 | Unlimited |
| Audit logs | No | Yes |
| SAML/SSO | No | Yes |
Windmill vs Alternatives
| Feature | Windmill | n8n | Retool |
|---|---|---|---|
| Code-first | Yes | No-code | Low-code |
| Self-hosted | Yes | Yes | Limited |
| Auto UI | Yes | No | Manual |
| Workflows | DAG | Visual | No |
| Languages | TS/Py/Go/Bash | JS | JS |
| Open source | Yes | Fair-code | No |
Automate web scraping workflows? Scrapfly + Windmill = scheduled data extraction with auto UI. Email spinov001@gmail.com for custom solutions.
Top comments (0)