Phlow is a high-performance, scalable, and Low Code flow runtime built with Rust — designed to revolutionize the way you build backends. With Phlow, you can create APIs, automations, and event-driven systems using just YAML, JSON, or TOML, composing logic like building blocks.
Thanks to its modular architecture and clear separation between control and behavior, Phlow lets you orchestrate complex flows without writing code — and when you need more power, just plug in lightweight scripts or Rust modules.
It also comes with native observability powered by OpenTelemetry, giving you full visibility into your flows, modules, and executions. Easily export traces and metrics to Jaeger, Grafana Tempo, or AWS X-Ray, all with simple environment variables.
If you're looking for speed, flexibility, and full insight into your backend — Phlow is the Low Code revolution you’ve been waiting for.
📚 Table of Contents
- 🎯 Philosophy
- 🔌 Module Types
- 🧱 Example:
main.yamlfor an HTTP Gateway - 🧩 YAML Superpowers
- ⚙️ Install & Usage
- 🧠 Creating Your Own Module:
log - 📦 Project Structure
- 📡 Observability
- 🧪 OpenTelemetry + Jaeger (Local Dev Setup)
- 🌍 Environment Settings
- 📜 License
🎯 Philosophy
Phlow was built around the following principles:
1. Flow over Frameworks
Forget bulky frameworks. Phlow embraces flows. Each step is modular, each behavior is pluggable. You define what happens, when, and how — all through configuration and small, focused modules.
2. Composability
Phlow encourages building small pieces that fit together. Each module can:
- Run logic (
step module) - Start the system (
main module) - Interact via
inputandoutput - Be swapped, reused, or extended easily.
3. Extensibility with Scripts
Need logic? Use phs (Phlow Script) or rhai. Define logic inline or in external files. You don't need to recompile to change behavior — just change the YAML.
4. Observability First
Every module, flow, and step can be traced using tracing and OpenTelemetry. You'll always know where, why, and how something happened.
5. Separation of Control and Behavior
Control lives in YAML (steps, conditions, includes). Behavior lives in modules and scripts. You can mix and match at will.
🔌 Module Types
| Type | Purpose |
|---|---|
main module |
Entry point. Starts the app (HTTP, CLI, AMQP, etc). |
step module |
Logic executed within a flow (log, fetch, transform, etc). |
🧱 Example: main.yaml for an HTTP Gateway
main: gateway
modules:
- name: gateway
module: rest_api
with:
host: 0.0.0.0
port: 3000
- name: request
module: http_request
with:
timeout: 29000 # 29s
steps:
- condition:
assert: main.path.start_with("/public")
then:
module: request
input:
method: main.method
url: `public-service.local${main.uri}?`
headers:
x-forwarded-for: main.client_ip
x-original-path: main.path
body: main.body
- use: authorization
id: auth
input:
api_key: main.header.authorization
- condition:
assert: steps.auth.authorized == true
then:
module: request
with:
method: main.method
url: `private-service.local${main.uri}?`
headers:
x-forwarded-for: main.client_ip
x-original-path: main.path
body: main.body
- return:
status_code: 401
body:
🧩 YAML Superpowers
Phlow extends YAML with:
!eval: execute inline expressions using Phlow Script (phs).!include: include other YAML files into the flow tree.!import: import external script files (.phs or .rhai) and evaluate them with!eval.
⚙️ Installation & Usage
Install Phlow globally using Cargo:
🔧 Running a Flow
By default, Phlow will look for a `main.yaml` in the current directory:
To run a specific file:
If you provide a directory path and it contains a `main.yaml`, Phlow will automatically run that:
# → runs path/to/directory/main.yaml
🆘 Help
For all available options and usage info:
# or
🧠 Creating Your Own Module: log
Phlow modules are written in Rust and compiled as shared libraries. Here’s a real example of a simple log module that prints messages at various log levels.
🔧 Code (src/lib.rs)
use ;
plugin!;
🛠️ Example usage in a flow
steps:
- id: notify
module: log
with:
level: info
message: "Process started"
- use: log
with:
level: error
message: "something went wrong: " + main.error
📦 Project Structure
All compiled .so modules must be placed inside the phlow_packages/ directory.
To build all modules at once, this project includes a utility script:
📡 Observability
Phlow integrates with:
- OpenTelemetry (OTLP)
- Tracing (Spans and Logs)
- Prometheus Metrics
- Jaeger, Grafana Tempo, AWS X-Ray
Enable it with:
PHLOW_OTEL=true
PHLOW_LOG=DEBUG
PHLOW_SPAN=INFO
🧪 OpenTelemetry + Jaeger (Local Dev Setup)
To enable observability with Jaeger during development, you can run a full OpenTelemetry-compatible collector locally in seconds.
🔄 1. Run Jaeger with OTLP support
This container supports OTLP over HTTP and gRPC, which are both compatible with Phlow's OpenTelemetry output.
⚙️ 2. Configure environment variables
Set the following environment variables in your shell or .env file:
🔍 3. Open the Jaeger UI
Once running, access the Jaeger web interface at:
Search for your service using the name defined in OTEL_SERVICE_NAME.
✅ Tips
- Combine this with
PHLOW_OTEL=true,PHLOW_SPAN=INFO, andPHLOW_LOG=DEBUGfor full observability. - You can also integrate with Grafana Tempo or AWS X-Ray by replacing the collector backend.
🌍 Environment Settings
Below is a list of all environment variables used by the application, combining those defined in both files, along with their descriptions, default values, and types.
Environment Variables Table
| Variable | Description | Default Value | Type |
|---|---|---|---|
| PHLOW_PACKAGE_CONSUMERS_COUNT | Number of package consumersDefines how many threads will be used to process packages. | 10 |
i32 |
| PHLOW_MIN_ALLOCATED_MEMORY_MB | Minimum allocated memory (MB)Defines the minimum amount of memory, in MB, allocated to the process. | 10 |
usize |
| PHLOW_GARBAGE_COLLECTION_ENABLED | Enable garbage collectionEnables or disables garbage collection (GC). | true |
bool |
| PHLOW_GARBAGE_COLLECTION_INTERVAL_SECONDS | Garbage collection interval (seconds)Defines the interval at which garbage collection will be performed. | 60 |
u64 |
| PHLOW_LOG | Log levelDefines the log verbosity for standard logging output. Possible values typically include TRACE, DEBUG, INFO, WARN, ERROR. |
WARN |
str |
| PHLOW_SPAN | Span levelDefines the verbosity level for span (OpenTelemetry) tracing. Possible values typically include TRACE, DEBUG, INFO, WARN, ERROR. |
INFO |
str |
| PHLOW_OTEL | Enable OpenTelemetryEnables or disables OpenTelemetry tracing and metrics. | true |
bool |
Notes
- If an environment variable is not set, the default value indicated in the table above will be used.
- Set the corresponding environment variables before running the application to override the defaults.
- The log level (
PHLOW_LOG) and span level (PHLOW_SPAN) control different layers of logging:PHLOW_LOG: Affects standard logging (e.g., error, warning, info messages).PHLOW_SPAN: Affects tracing spans (useful for deeper telemetry insights with OpenTelemetry).
- The
PHLOW_OTELvariable controls whether or not OpenTelemetry providers (for both tracing and metrics) are initialized.
📜 License
MIT © 2025 — Built with ❤️ and Rust.