Write F#, run Python - a practical guide to Fable.Python
This is a comprehensive guide to Fable.Python, written as literate F# that transpiles to Python and generates its own documentation.
- Introduction - What is Fable.Python and why use it
- For Python Developers - F# concepts explained for Pythonistas
- Getting Started - Setup, your first project, hello world
- Interop - Using existing Python libraries and Fable.Python bindings
- Bindings - Creating your own type-safe bindings for Python libraries
- Compatibility - Supported F# features and limitations
- Fable v5 - What's new in Fable v5 for Python
- Libraries - Existing ecosystem (Thoth.Json, AsyncRx, Siren, etc.) (coming soon)
- Pydantic - Pydantic interop with Decorate and ClassAttributes
- Units of Measure - Compile-time dimensional analysis
- Testing - XUnit and Fable.Pyxpecto (coming soon)
- Fabletext: The Strange Loop - The self-documenting finale
This guide is self-documenting: each chapter is an .fs file with embedded Markdown comments. Fabletext (the final chapter) processes these files to generate the documentation you're reading - including itself.
The chain:
- Write F# with embedded Markdown (
chapters/*.fs) - Compile to Python with Fable
- Run Fabletext (F# compiled to Python) to extract documentation
- Output: the Markdown you're reading
The blog post is its own proof of concept.
# Install dependencies
just setup
just restore
npm install
# Build everything (F# → Python → Markdown)
just all
# Or generate just the blogpost
just blogpostjust setup # Install Fable and Python dependencies (uv)
just restore # Restore NuGet packages
just build # Compile F# to Python with Fable
just generate # Convert chapters to individual markdown files
just blogpost # Generate concatenated blogpost.md for publishing
just format # Format F# (fantomas) and Python (ruff) files
just lint # Lint Python (ruff) and Markdown (markdownlint)
just all # Full pipeline: restore, build, generate, format, lint
just clean # Remove generated fileschapters/
├── introduction.fs # What is Fable.Python
├── python.fs # F# for Python developers
├── getting-started.fs # Setup and first project
├── interop.fs # Using Python libraries
├── bindings.fs # Creating bindings
├── compatibility.fs # F# feature support
├── fable-v5.fs # What's new in Fable v5
├── pydantic.fs # Pydantic interop
└── units-of-measure.fs # Dimensional analysis
tools/
├── fabletext.fs # Fabletext converter (F#)
└── fabletext.fsproj
output/
├── chapters/ # Generated Python from chapters
└── tools/
└── fabletext.py # Generated converter (Python)
docs/
├── introduction.md # Individual chapter docs
├── python.md
├── ...
└── blogpost.md # Concatenated for Hashnode
Defined in justfile:
chapters := "introduction python getting-started interop bindings compatibility fable-v5 pydantic units-of-measure"To add a new chapter, just add the file and update this list.
- Fable 5 (alpha) - F# to Python compiler
- uv - Python dependency management
- just - Command runner
- ruff - Python formatter/linter
- fantomas - F# formatter
- markdownlint - Markdown linter
- Thoth.Json.Python - Type-safe JSON
- AsyncRx - Reactive extensions
- Fable.Giraffe - Web framework
- Feliz.ViewEngine - HTML DSL
- Siren - Mermaid diagrams
- Fable.Pyxpecto - Testing
- ARCtrl - Real-world multi-target library
- Fable
- Fable.Python Documentation
- Fable.Python GitHub
- BINDINGS_GUIDE.md - Comprehensive binding patterns
Part of F# Advent 2025