{"id":9112204,"url":"https://fsprojects.github.io/Fabulous","last_synced_at":"2025-08-13T19:32:53.776Z","repository":{"id":37734219,"uuid":"120334619","full_name":"fabulous-dev/Fabulous","owner":"fabulous-dev","description":"Declarative UI framework for cross-platform mobile \u0026 desktop apps, using MVU and F# functional programming","archived":false,"fork":false,"pushed_at":"2024-11-08T14:48:32.000Z","size":31022,"stargazers_count":1159,"open_issues_count":10,"forks_count":122,"subscribers_count":53,"default_branch":"main","last_synced_at":"2024-11-08T19:05:55.653Z","etag":null,"topics":["declarative-ui","fabulous","fsharp","mvu"],"latest_commit_sha":null,"homepage":"https://fabulous.dev","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabulous-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["TimLariviere","edgarfgp"]}},"created_at":"2018-02-05T17:00:17.000Z","updated_at":"2024-11-08T14:47:07.000Z","dependencies_parsed_at":"2023-02-13T19:45:53.375Z","dependency_job_id":"5dcad240-b1aa-49a4-af6d-d93a3203e435","html_url":"https://github.com/fabulous-dev/Fabulous","commit_stats":{"total_commits":795,"total_committers":8,"mean_commits":99.375,"dds":"0.30817610062893086","last_synced_commit":"47ce174abd1b639a2c3b897b9f5998219821638c"},"previous_names":["fsprojects/fabulous","fsprojects/elmish.xamarinforms"],"tags_count":131,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabulous-dev%2FFabulous","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabulous-dev%2FFabulous/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabulous-dev%2FFabulous/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabulous-dev%2FFabulous/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabulous-dev","download_url":"https://codeload.github.com/fabulous-dev/Fabulous/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229680825,"owners_count":18106673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["declarative-ui","fabulous","fsharp","mvu"],"created_at":"2024-05-05T06:03:30.401Z","updated_at":"2024-12-15T03:30:25.570Z","avatar_url":"https://github.com/fabulous-dev.png","language":"F#","funding_links":["https://github.com/sponsors/TimLariviere","https://github.com/sponsors/edgarfgp"],"categories":["Mobile","Fabulous"],"sub_categories":[],"readme":"\u003ca href=\"https://fabulous.dev/\"\u003e\n  \u003ch1 align=\"center\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"logo/logo-title.png\"\u003e\n      \u003cimg alt=\"Fabulous\" src=\"logo/logo-title.png\" height=\"180px\"\u003e\n    \u003c/picture\u003e\n  \u003c/h1\u003e\n\u003c/a\u003e\n\n[![build](https://img.shields.io/github/actions/workflow/status/fabulous-dev/Fabulous/build.yml?branch=v2.1)](https://github.com/fabulous-dev/Fabulous/actions/workflows/build.yml) [![NuGet version](https://img.shields.io/nuget/v/Fabulous)](https://www.nuget.org/packages/Fabulous) [![NuGet downloads](https://img.shields.io/nuget/dt/Fabulous)](https://www.nuget.org/packages/Fabulous) [![Discord](https://img.shields.io/discord/716980335593914419?label=discord\u0026logo=discord)](https://discord.gg/bpTJMbSSYK) [![Twitter Follow](https://img.shields.io/twitter/follow/FabulousAppDev?style=social)](https://twitter.com/FabulousAppDev)\n\nFabulous is a modern declarative UI framework for crafting cross-platform mobile and desktop apps in .NET.  \nIt aims to bring you a great development experience and confidence in your code by combining an expressive UI syntax, the simple \u0026 robust Model-View-Update (MVU) architecture, and functional programming.\n\n## Documentation\n\nThe full documentation for Fabulous can be found at [docs.fabulous.dev](https://docs.fabulous.dev).\n\nOther useful links:\n- [The official Fabulous website](https://fabulous.dev)\n- [Get started](https://docs.fabulous.dev/get-started)\n- [API Reference](https://api.fabulous.dev)\n- [Contributor Guide](CONTRIBUTING.md)\n\nAdditionally, we have the [Fabulous Discord server](https://discord.gg/bpTJMbSSYK) where you can ask any of your Fabulous related questions.\n\n## About Fabulous\n\nWe believe declarative UI, functional programming, and the MVU state management are a perfect fit for app development.\n\nFabulous will help you create mobile and desktop apps quickly and with confidence thanks to declarative UI and the [MVU](https://zaid-ajaj.github.io/the-elmish-book/#/chapters/elm/) architecture, all in one single language: [F#](https://fsharp.org) - a functional programing language.\n\nFabulous also aims to be performant by having low memory consumption and efficient view diffing mechanisms.\n\nNote that Fabulous itself does not provide any UI rendering. You'll need to combine it with another framework like:\n- [.NET MAUI](https://dotnet.microsoft.com/en-us/apps/maui) with [Fabulous.MauiControls](https://github.com/fabulous-dev/Fabulous.MauiControls)\n- [AvaloniaUI](https://avaloniaui.net) with [Fabulous.Avalonia](https://github.com/fabulous-dev/Fabulous.Avalonia)\n\n### Declarative UI\n\nTypical UI development can be a nightmare if not done properly.  \nIt is generally created in one place, then mutated here and there based on the need and what the user is doing. Related UI pieces end up in several places, making it hard to mentally think of all the possibilities; until the inevitable race condition or bug due to an unintended user flow.\n\nFabulous makes it easier to reason about UI thanks to its declarative UI inspired by SwiftUI.  \nThe UI of a component is defined in a single place and Fabulous will call it everytime the state of that component is changed.  \n\nYou don't need to think about how to mutate the UI, Fabulous will handle it for you to always match the latest UI you need.\n\n```fs\n/// A simple Counter app made with Fabulous.MauiControls\ntype Model =\n    { Count: int }\n\ntype Msg =\n    | Increment\n    | Decrement\n\nlet view model =\n    Application(\n        ContentPage(\n            \"Counter app\",\n            VStack(spacing = 16.) {\n                Image(Aspect.AspectFit, \"fabulous.png\")\n\n                Label($\"Count is {model.Count}\")\n\n                Button(\"Increment\", Increment)\n                Button(\"Decrement\", Decrement)\n            }\n        )\n    )\n```\n\n### MVU architecture\n\nMVU makes every state and transition between those states explicit.  \nYou don't need to worry about unintended actions that could lead to an invalid state which would crash the app.\n\nInstead, you can very easily model the state of your app or component and transitions between them using F# records and discriminated unions types.  \nWhen starting, Fabulous will initialize the state. Then, when messages are being dispatched, Fabulous will let you transition from one state to the other given a specific message.\n\nIf several messages are received at the same time, Fabulous will queue them to let you update the state properly.\n\n```fs\nlet init () =\n    { Count = 0 }\n\nlet update msg model =\n    match msg with\n    | Increment -\u003e { model with Count = model.Count + 1 }\n    | Decrement -\u003e { model with Count = model.Count - 1 }\n```\n\nAnd finally, given the functional nature of MVU, it is extremely simple to unit test each and every possible state of your application.\n\n```fs\n[\u003cTest\u003e]\nlet ``When clicking the Increment button, increment the count by one``() =\n    let previousState = { Count = 10 }\n    let expectedState = { Count = 11 }\n\n    let actualState = App.update Increment previousState\n\n    actualState |\u003e should equal expectedState\n```\n\n### Powered by .NET\n\n.NET is a very mature and broad framework by Microsoft. It can run on any device and platform, is very efficient, and has a vast ecosystem of open-source and licensed libraries, plugins, and other frameworks.  \nYou will be able to benefit from the .NET ecosystem by using 3rd party packages directly in your Fabulous application.\n\n## Supporting this project\n\nThe simplest way to show us your support is by giving the project a star.\n\nYou can also support us by becoming our sponsor on the GitHub Sponsors program.  \nThis is a fantastic way to support all the efforts going into making Fabulous the best declarative UI framework for dotnet.\n\nIf you need support see Commercial Support section below.\n\n## Contributing\n\nHave you found a bug or have a suggestion of how to enhance Fabulous? Open an issue and we will take a look at it as soon as possible.\n\nDo you want to contribute with a PR? PRs are always welcome, just make sure to create it from the correct branch (main) and follow the [Contributor Guide](CONTRIBUTING.md).\n\nFor bigger changes, or if in doubt, make sure to talk about your contribution to the team. Either via an issue, GitHub discussion, or reach out to the team either using the [Discord server](https://discord.gg/bpTJMbSSYK).\n\n## Commercial support\n\nIf you would like us to provide you with:\n\n- training and workshops,\n- support services,\n- and consulting services.\n\nFeel free to contact us: [support@fabulous.dev](mailto:support@fabulous.dev)\n\n## Star History\n\n\u003ca href=\"https://star-history.com/#fabulous-dev/Fabulous\u0026fabulous-dev/Fabulous.Avalonia\u0026fabulous-dev/Fabulous.MauiControls\u0026Date\"\u003e\n \u003cpicture\u003e\n   \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=fabulous-dev/Fabulous,fabulous-dev/Fabulous.Avalonia,fabulous-dev/Fabulous.MauiControls\u0026type=Date\u0026theme=dark\" /\u003e\n   \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=fabulous-dev/Fabulous,fabulous-dev/Fabulous.Avalonia,fabulous-dev/Fabulous.MauiControls\u0026type=Date\" /\u003e\n   \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=fabulous-dev/Fabulous,fabulous-dev/Fabulous.Avalonia,fabulous-dev/Fabulous.MauiControls\u0026type=Date\" /\u003e\n \u003c/picture\u003e\n\u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/fsprojects.github.io%2FFabulous","html_url":"https://awesome.ecosyste.ms/projects/fsprojects.github.io%2FFabulous","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/fsprojects.github.io%2FFabulous/lists"}