Getting started

  1. Install Visual Studio or Visual Studio for Mac and enable both Xamarin and .NET Core support, these are listed as ‘Mobile development with .NET’ and ‘.NET Core Cross-platform development’ respectively.

  2. Open a command prompt window and install the template pack by entering:

dotnet new -i Fabulous.XamarinForms.Templates
  1. Navigate to a folder in the command prompt window where your new app can be created and enter:
dotnet new fabulous-xf-app -n SqueakyApp
  1. Open, edit and build in Visual Studio or Visual Studio for Mac
SqueakyApp/SqueakyApp.sln
  1. Before deploying and running, first connect and enable your device, choose between iOS (Emulator, Device) or Android (Emulator, Device).

  2. To run, set either your Android or iOS project as the startup project, then use F5.

By default iOS and Android projects are created. But you can also target WPF with --WPF, UWP with --UWP, macOS with --macOS and/or GTK with --GTK. Here some common examples, but feel free to change the targets to the ones you require:

Android only:

dotnet new fabulous-xf-app -n SqueakyApp --iOS=false

iOS only:

dotnet new fabulous-xf-app -n SqueakyApp --Android=false

WPF only:

dotnet new fabulous-xf-app -n SqueakyApp --WPF --Android=false --iOS=false

UWP only:

dotnet new fabulous-xf-app -n SqueakyApp --UWP --Android=false --iOS=false

macOS only:

dotnet new fabulous-xf-app -n SqueakyApp --macOS --Android=false --iOS=false

GTK only:

dotnet new fabulous-xf-app -n SqueakyApp --GTK --Android=false --iOS=false

All 6 platforms:

dotnet new fabulous-xf-app -n SqueakyApp --WPF --UWP --macOS --GTK
  1. If you are using Visual Studio for Mac and you want to start with File -> New, make sure you target “.NET Standard” to add the references to Fabulous:

File -> New Solution Multiplatform App -> Blank Forms App (F#) Shared Code -> Use .NET Standard

Structure of a Project

The majority of your app logic will be in your shared code project, normally a .NET Standard 2.0 project.

Your project will also have iOS and Droid projects for actually running the core logic on these different platforms.

Running

To run, set your target to Any CPU (Android) or iPhone or iPhone Simulator, then choose your device and launch.

You may need to install Android, iOS and/or other SDK tooling.

If running on-device you may need to enable developer settings for your device, or, in the case of iOS, enable free provisioning.

A Basic Example

Here is a full example of an app:

// replace with the namespace of your app
namespace ExampleApp

open Fabulous
open Fabulous.XamarinForms
open Xamarin.Forms

module App =
 
    /// The messages dispatched by the view
    type Msg =
        | Pressed
 
    /// The model from which the view is generated
    type Model =
        { Pressed: bool }
 
    /// Returns the initial state
    let init() = { Pressed = false }
 
    /// The function to update the view
    let update (msg: Msg) (model: Model) =
        match msg with
        | Pressed -> { model with Pressed = true }
 
    /// The view function giving updated content for the page
    let view (model: Model) dispatch =
        View.ContentPage(
            View.StackLayout([
                if model.Pressed then
                    View.Label("I was pressed!")
                else
                    View.Button(
                        text = "Press Me!",
                        command = fun () -> dispatch Pressed
                    )
            ])
        )
    
 type App () as app =
     inherit Application ()

     let runner =
         Program.mkSimple App.init App.update App.view // use Program.mkProgram if your app contains commands (see 'update')
         |> Program.withConsoleTrace
         |> XamarinFormsProgram.run app

The init function returns your initial state, and each model gets an update function for message processing. The view function computes an immutable Xaml-like description. In the above example, the choice between a label and button depends on the model.Pressed value.

Some advantages of using an immutable model are:

  • It is easy to unit test your init, update and view functions
  • You can save/restore your model relatively easily
  • It makes tracing causality usually very simple

Samples

The sample CounterApp contains a slightly larger example of Button/Label/Slider elements.

The sample TicTacToe contains examples of the Grid and Image elements.

The sample AllControls contains examples of instantiating most elements in Xamarin.Forms.Core.

The sample Calculator (original external sample) is a small calculator app.

The external sample PocketPiggyBank is a small client-server app with login authentication. (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)

The external sample FabulousContacts is a multi-page contacts app featuring maps, group-lists and cross-page messages. (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)

The external sample FabulousPlanets is a multi-page app featuring facts on the planets in the Solar System. It uses Urho3D and Fabulous (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)

The external sample Fabulous + GraphQL Type Provider is a small app that demonstrates how to use the type provider for GraphQL FSharp.Data.GraphQL.

See also the curated list Awesome Fabulous.

Further Resources

Presentation: Making Mobile App Development Simple with F#

Presentation: Building mobile apps with F# using Xamarin - Jim Bennett - Xamarin University Guest Lecture

General Docs

Android Setup

iOS Setup

Contributing

Please contribute to this library through issue reports, pull requests, code reviews and discussion.