Synthesize
Synthesize is a DAG-shaped workflow runner for local development.
In Synthesize, a flow is a graph (potentially disjoint) of nodes, each of which runs a recipe whenever one of that node's triggers activates. Synthesize has a wide variety of triggers:
- Recipe
Bshould run after recipeAruns. - Recipe
Wshould run every time fileFchanges. - Recipe
Rshould be restarted if it ever exits. - Recipe
Oshould run once when the flow starts.
These can all coexist as part of same flow, and can even be combined for a single recipe,
allowing for complex nodes like
"restart recipe W if it exits or if file F changes".
Features
- Nodes naturally run concurrently based on their triggers.
- Recipe and trigger definitions can be factored out and shared across multiple nodes and flows.
- Recipes are just shell commands, so you can use any tools you'd like. Synthesize works with your existing tools, it doesn't replace them.
- Recipes can be parameterized with arguments (each recipe is actually a Jinja template) and environment variables. Arguments and environment variables can also be provided at the flow and recipe levels (most specific wins).
- Nodes can have multiple triggers, allowing you to express complex triggering conditions.
- All command output is combined in a single output stream, with each node's output prefixed with a timestamp and its name.
- The current time and the status of each node is displayed at the bottom of your terminal.
- You can generate Mermaid diagrams of your flows for debugging and documentation.
Examples
As an example, here is Synthesize's own synth.yaml configuration file:
flows:
dev:
description: run tests, type-checking, and docs dev server
nodes:
tests:
recipe: tests
triggers:
- code-changes
types:
recipe: types
triggers:
- code-changes
docs:
recipe: docs
triggers:
- delay: 1
- watch: ["docs/hooks/"]
recipes:
tests:
commands: |
uv run pytest
types:
commands: |
uv run mypy
docs:
commands: |
uv run mkdocs serve --strict
triggers:
code-changes:
watch:
- src/
- tests/
- docs/examples/
- docs/hooks/
- pyproject.toml
- .coveragerc
flowchart TD
tests(tests)
w_bb19edcd7b45bfcfbfcab4096798a339f9610617[("src/
tests/
docs/examples/
docs/hooks/
pyproject.toml
.coveragerc")]
w_bb19edcd7b45bfcfbfcab4096798a339f9610617 -->|👁| tests
types(types)
w_bb19edcd7b45bfcfbfcab4096798a339f9610617 -->|👁| types
docs(docs)
docs -->|∞ 1s| docs
w_f8192994ea74c4d2311ffd6eb936c7c30e96617f[("docs/hooks/")]
w_f8192994ea74c4d2311ffd6eb936c7c30e96617f -->|👁| docs
Installation
Add Synthesize as a development dependency in your project:
Then use uv run synth --help to see what's available.
Synthesize does not work on Windows
We recommend using the Windows Subsystem for Linux (WSL) to run Synthesize on Windows.