Fable.Giraffe is a port of the Giraffe F# web framework to Fable. Write your web application once in F# and run it on Python (ASGI/uvicorn) or Erlang/BEAM (Cowboy).
let webApp =
choose [
route "/ping" >=> text "pong"
route "/json" >=> json {| name = "Dag"; age = 53 |}
]
let app =
WebHostBuilder()
.Configure(fun app -> app.UseGiraffe(webApp))
.Build()- .NET SDK 8+
- Python >= 3.12 with uv
- Erlang/OTP 28+ (for BEAM target)
just setup # restore dotnet tools + uv sync
just build # compile F# library to Python (output: build/lib/)
just build-beam # compile F# library to Erlang (output: build/beam/)For local Fable development (using a local Fable compiler checkout):
just dev=true buildjust appThis compiles the example app and starts it with uvicorn on port 8080.
just app-beamThis compiles the example app to Erlang, builds with rebar3, and starts a Cowboy server on port 8080.
just test # native F# tests + compiled Python tests
just test-native # native F# tests only (xUnit)
just test-python # compiled Python tests only (pytest)Simple /ping endpoint returning "pong", 10,000 requests with 100 concurrent
connections (oha):
| Metric | BEAM | .NET | Python |
|---|---|---|---|
| Requests/sec | 124,256 | 70,375 | 4,006 |
| Avg latency | 0.79 ms | 1.40 ms | 24.9 ms |
| P99 latency | 2.49 ms | 3.50 ms | 34.2 ms |
BEAM: Erlang/OTP 28, Cowboy. .NET: Giraffe on ASP.NET Core. Python: uvicorn, 1 worker.