
Immutable by default. Powerful pattern matching. Lightweight syntax. Units of measure. Type providers. Enjoy!
Fable is a compiler that makes F# a first-class citizen of the JavaScript ecosystem
Immutable by default. Powerful pattern matching. Lightweight syntax. Units of measure. Type providers. Enjoy!
Don't panic about verbose signatures. Let the compiler infer the types and catch the bugs for you before they ever get into runtime!
Fable produces readable JavaScript code compatible with ES2015 standards and popular tooling like Webpack!
Call JavaScript from Fable or Fable from JS! Use NPM packages! Everything's ready for you!
Choose your favorite tool: from Visual Studio Code to JetBrains Rider. Check the whole list here.
Fable supports most of the F# core library and some of most commonly used .NET APIs. But don't worry about huge bundle sizes, you only pay for what you get.
Try Fable online or get started in your local machine with our set of samples (more info):
git clone https://github.com/fable-compiler/fable3-samples cd fable3-samples/browser npm install npm start
These are some of the main F# features that you can use in your web apps with Fable.
Model your domain with union types and match complex patterns with ease. The compiler will warn you if you're forgetting some cases!
type Face = Ace | King | Queen | Jack | Number of int
type Color = Spades | Hearts | Diamonds | Clubs
type Card = Face * Color
let aceOfHearts = Ace,Hearts
let tenOfSpades = (Number 10), Spades
match card with
| Ace, Hearts -> printfn "Ace Of Hearts!"
| _, Hearts -> printfn "A lovely heart"
| (Number 10), Spades -> printfn "10 of Spades"
| _, (Diamonds|Clubs) -> printfn "Diamonds or clubs"
// warning: Incomplete pattern matches on this expression.
// For example, the value '(_,Spades)' may indicate
// a case not covered by the pattern(s).
There's a lot of code involving continuations out there, like asynchronous or undeterministic operations. Other languages bake specific solutions into the syntax, with F# you can use built-in computation expressions and also extend them yourself.
// JS promises made easy
promise {
let! res = Fetch.fetch url []
let! txt = res.text()
return txt.Length
}
// Declare your own computation expression
type OptionBuilder() =
member __.Bind(opt, binder) =
match opt with Some value -> binder value | None -> None
member __.Return(value) = Some value
let option = OptionBuilder()
option {
let! x = trySomething()
let! y = trySomethingElse()
let! z = andYetTrySomethingElse()
// Code will only hit this point if the three
// operations above return Some
return x + y + z
}
Let the compiler verify arithmetic relationships for you to help prevent programming errors.
[<Measure>] type m
[<Measure>] type s
let distance = 12.0<m>
let time = 6.0<s>
let thisWillFail = distance + time
// ERROR: The unit of measure 'm' does
// not match the unit of measure 's'
let thisWorks = distance / time
// 2.0<m/s>
Build your types using real-world conditions and make the compiler warn you if those conditions change.
let [<Literal>] JSON_URL = "https://jsonplaceholder.typicode.com/todos"
// Type is created automatically from the url
type Todos = Fable.JsonProvider.Generator<JSON_URL>
async {
let! (_, res) = Fable.SimpleHttp.Http.get url
let todos = Todos.ParseArray res
for todo in todos do
// If the JSON schema changes, this will fail compilation
printfn "ID %i, USER: %i, TITLE %s, COMPLETED %b"
todo.id
todo.userId
todo.title
todo.completed
}
These are some of the projects and companies using Fable. Send us a message to include yours!