Repository F# setup
open System
open System.IO
open System.Threading
open System.Threading.Tasks
open Axial
open Axial.Layers
open Axial.Console
open Axial.FileSystem
open Axial.Hosting
open Axial.Hosting.Browser
open Axial.Hosting.Node
open Axial.HttpClient
open Axial.PlatformService
open Axial.Process
open Axial.State
open Axial.Telemetry
open Axial.Telemetry.JavaScriptWhy Flow?
Do you need Flow?
You do not need Flow for pure functions, local validation, or a single Task call. Keep using Result, Async, and
Task while they are enough. F# is good at those, and Flow adds a type parameter and a runtime that a small function
does not repay.
Reach for Flow when one call tree carries several of these at once:
- dependencies that a test has to replace;
- expected failures that callers must handle by name;
- cancellation that has to reach every inner call;
- retries, timeouts, or scheduled repetition;
- resources whose release must survive a failure;
- background work that needs an owner.
Any one of those is manageable by hand. The cost is that each is a separate mechanism, and each caller in the tree has to repeat the policy correctly.
The signature is the argument
Here is one operation with three of those concerns, written against Task:
val loadUser:
cancellationToken: CancellationToken ->
services: AppServices ->
userId: UserId ->
Task<Result<User, LoadUserError>>Flow puts the same three parts in one type:
val loadUser: UserId -> Flow<AppServices, LoadUserError, User>A Flow is a description
A Flow value is not an already-running Task. Nothing happens until you start it at an explicit boundary, and that
boundary owns cancellation, child fibers, scopes, and cleanup for the execution. Two consequences follow:
- Building a workflow twice and running it twice is safe, so retries and schedules are ordinary combinators rather than hand-written loops.
- A workflow value can be passed around, stored, and composed before anyone decides to run it.
Use Flow for application orchestration and operational work. Keep local validation and ordinary pure composition in
Result or another focused type until the code actually needs Flow's execution model.
Go further
- Task vs Flow: seven scenarios compares ownership, cancellation, retries, and background work in concrete examples.
- Flow compared with Effect-TS explains the shared model and the places where F# leads to a different API.
- Compiler-directed, AOT, and Fable describes the supported runtime targets and package boundaries.

