From a drawing to a typed plan to a measured run.
Fletch has one contract between every part of the system: the Fletch IR document. The canvas edits it, the validator canonicalises it, the planner compiles it, the runtime executes it and the tests check it. This page follows one workflow down that path.
Draw it
Pick steps from a palette of operators grouped the way analysts think. Drag ports together or build it entirely from the keyboard.
Canonicalise it
Every structural change posts to the validator. The crate returns the canonical document, its hash, and any errors by code.
Compile it
The planner splits the graph into SQL fragments pushed to each source and operator fragments run locally, with bounds in sandbox mode.
Measure it
The runtime executes with per-step telemetry. Workflow tests compare schema, then cardinality, then rows against named expectations.
The same nine steps, as the canvas, the crate, the planner and the runtime see them.
Switch views. Nothing is translated between them; each one reads the same Fletch IR document.

| Step | Operator | Rows in → out | Duration | Kernel |
|---|---|---|---|---|
| n1 | source.table | — → 8,412 | sql · hana | |
| n2 | source.table | — → 1,206 | sql · snowflake | |
| n3 | core.join | 8,412 + 1,206 → 8,390 | duckdb · threads=1 | |
| n5 | core.formula | 8,390 → 8,390 | duckdb | |
| n6 | core.summarize | 8,390 → 42 | duckdb | |
| n7 | core.sort | 42 → 42 | duckdb | |
| n8 | sink.browse | 42 → preview | persisted, capped |
Built for people who build workflows all day.
A one-click palette replaced a thirty-six entry dropdown. Labels say what the step does; the operator id stays underneath for the engine. Drag from an output port to connect, or select a node and press Enter on its target. Arrange lays out the graph.
- Groups: Data in & out, Tidy, Combine, Extract, Reshape, Measure, Flow
- Keyboard-only construction is a tested path, not an afterthought
- Light and dark themes, WCAG 2.1 AA as the target
Fifty core operators, each with an ordering rule and telemetry.
Relational kernels run on an embedded DuckDB pinned to a single thread, so results are deterministic. Each operator documents how it orders its output and reports rows in, rows out, bytes and duration for every run.
| Group | Operators | Notes |
|---|---|---|
| Data in & out | source.table · source.query · source.inline · sink.browse · sink.file · sink.materialize | Browse puts a branch's table on screen; a file sink can sit beside it so a delivered branch stays inspectable. |
| Tidy | select · filter · formula · sort · sample · unique · record_id · cleanse · rename · select_where · tile · generate_rows · rank | Formula expressions use Arrow types; a math function outside its domain yields NULL, as the Alteryx engine does. |
| Combine | join · join_multiple · union · append_fields · find_replace · make_group · find_scan · similarity_join | Join emits the left, joined and right outputs as a sequence, so no output is silently dropped. |
| Reshape | summarize · transpose · crosstab · window_formula · scan_formula · running_total · make_columns · arrange · broadcast_formula | Crosstab reads its data-dependent columns from the document, the way the original tool writes them into the file. |
| Extract | text_to_columns · text_to_rows · datetime · json_parse · json_build · xml_parse · regex | Multibyte-safe; a proptest found and fixed a panic before it shipped. |
| Measure · Flow | pearson · message · detour · detour_end · block_until_done · throttle · blob_convert · field_info | Flow operators keep an estate's control structure instead of flattening it. |
Push down what the source does well. Run the rest next to it.
A plan is a set of fragments: SQL sent to each source, and operator fragments executed in the runtime. In sandbox mode every fragment carries a bound the runtime refuses to run without, so a preview can never become a full extract by accident.
- Sandbox run: bounded, the default
- Full run: a separate, explicit act with its own grant
- Lineage is a mode of the runner, read from the document, no data touched
Unit tests for workflows, with named cases.
A workflow can carry a suite: inputs per source node, expected output per sink. The runner compares schema first, then row count, then rows after deterministic ordering, and reports the first difference in plain words. A workflow with tests is gated; a save that omits them leaves them alone.
- Many independent cases per workflow: typical, empty input, nulls, a known regression
- The same runner certifies Alteryx conversions against captured outputs
- Mutation testing of the operator kernels has its own standing ledger
Results stay inside Fletch.
A Browse step shows any branch's table on screen. Deliveries are kept as a capped, access-controlled preview per run, so a result is something you open, not something you export. The Run area lets a colleague who did not build a workflow find it, run it bounded under the owner's connections, and read the result.
Browse
Put a table on screen from any point in the graph. Sits beside a file sink when both are wanted.
Persisted preview
A bounded preview per run, stored, access-controlled, and rendered by the same table renderer everywhere.
Run
A portal of workflows you may run. Running one spends the owner's credentials under a separate grant and is audited as you.
The same governed surface, from a script or a sentence.
REST API shipped
Token-authenticated, documented in an OpenAPI specification, driving the same routes the console uses. Every call is audited.
Python SDK shipped
A buildable wheel with Databricks and Fabric quickstarts. Validate, plan, run and read results from a notebook.
Fletch agent design stage
Turns an instruction into Fletch IR and nothing else. Invalid operators are unrepresentable by construction; missing information surfaces as a question, never a guess. Bring your own model; no customer data leaves the tenant unless you configure it.
See the canvas on your own sources.
A working session with your schemas and one of your real workflows.