The SAFE stack is a set of F# libraries used together to create web applications. Tomasz Heimowski recently presented the stack at F# eXchange 2018 in a live coding session. He demonstrated the whole experience by creating and deploying a rating application for his talk.
The SAFE stack is composed of:
- Suave, a standalone web server library
- Azure
- Fable, a F# to Javascript transpiler
- Elmish, an UI library inspired by Elm
The development dependencies are .NET SDK 2.0 and Nodejs. To run the application only .NET Core is required. To get started, a template is available to create a basic application. The application contains sample code and build files.
dotnet new -i SAFE.Template
dotnet new SAFE
build run
Fable.Elmish provides declarative F# bindings for HTML elements. The html elements are built in F#, which allows for wiring event handlers along with the element definition.
let submit (model : Model) (dispatch : Msg -> unit) =
Button.aFa
[ Button.Color IsPrimary
Button.IsFullwidth
Button.OnClick (fun _ -> dispatch Submit)
Button.IsLoading model.Loading ]
[ str "Submit" ]
The SAFE template also includes webpack for hot reloading. Webpack is a client-side module bundler. The feature of interest for the SAFE stack is the Hot Module Replacement, allowing to replace only parts of the application without loosing state.
Fable.Remoting provides a way to share an interface between the client and server. It handles serialization and deserialization on both sides. The object's definition and service interface sit in a distinct library which is referenced by both client and server.
// Interface defining the service.
type IVotingProtocol =
{ getResults : unit -> Async<VotingResults>
addVote : Vote -> Async<VotingResults> }
// Typed service definiton used by the client code.
let api : IVotingProtocol =
Proxy.createWithBuilder<IVotingProtocol> Route.builder
On the server side, the interface implementation is wired in the server library using Fable.Remoting helpers for Suave.
let init : WebPart =
let votingProcotol : IVotingProtocol =
{ getResults = getResults
addVote = addVote }
// creates a WebPart for the given implementation
FableSuaveAdapter.webPartWithBuilderFor votingProcotol Route.builder
The application is deployed on Azure at the end of talk. The SAFE template does not integrate directly with Cloud providers. Instead, it allows for the creation of a Docker image that can be deployed afterwards to a provider, in this case Azure Containers.
Documentation on the SAFE stack is available on GitHub, along with code samples.