I created a starter desktop app using HTML/CSS/F# for the front end and F# .NET for the back end. All hosted in WPF.
This post mostly covers the "why". Hit the repo if you just care about "how".
Developers at my company are mostly coding for the web. But once in a while we need to create a Windows desktop app. Because some situations require direct access to hardware and running software. But a big challenge with desktop apps is their UI tech.
Why web UI?
Our devs have a lot of skill investment in web tech. And I don't mean React and Webpack -- although we know a little about those. I'm talking about the open standards of HTML, CSS, and Javascript. Because of standardization I can use web tech to make a consistent-looking UI, no matter what device is consuming it.
Meanwhile desktop UI techs tend to be opinionated and proprietary. We develop for desktop infrequently, so non-transferrable learning investments into desktop UI tech is a hard sell.
Which web UI?
It has been possible to use web tech in Windows desktop apps for a while. Problem was, the solutions were full of compromises.
UWP, for example, allows you to build apps using web tech. But it runs sandboxed, making it hard to do the one job it needs to do: direct access. WebBrowser and WebView have also existed for a while. They are embeddable browsers for WinForms/WPF apps. But they use IE or EdgeHTML for rendering. Need I say more?
Why not Electron?
The elephant in the room is Electron. The main downside for us is the Node.js back-end. Some of our vendors do not provide libraries for it. And even if it can be awkwardly made to work using unsupported libraries, Node requires us to work in Javascript.
Electron's cross-platform support is probably its biggest benefit... but we don't need that.
Yes, earlier I did list Javascript as a positive thing for web tech. I do like the standardized browser APIs available thru JS -- Media, Storage, Intl, etc. But let's be honest, JS also has footguns baked into the standard. And I strongly prefer to use something else: F# on .NET.
WebView2
WebView2 is an embeddable browser for WinForms/WPF like WebView before it. WebView2 uses Chromium-based Edge for rendering. So unlike its predecessor, WebView2 keeps evolving with the web standards. And I get to use F# on .NET.
We have actually used WebView2 since shortly after its release. We used it to show HTML5 video content in a computer lab. It was a rush job and WebView2 was only a month old at the time. I wasn't ready to trust it, much less consider it for other uses. And I forgot about it.
Then earlier this year, Microsoft announced Blazor Desktop based on WebView2. And then I found out Microsoft Teams is ditching Electron for WebView2. This got me to take another look at it. One thing led to another and over the weekend I created a working demo: a WPF app with an F# web UI and F# .NET backend API.
How does it work?
The UI is a webpack-built JS app just like you would expect. It uses F# and Elmish for a functional (as in functional programming) UI. The F# code gets transpiled to JS and uses React for DOM rendering.
The "backend" API is an F# library. In this starter app, the backend is very simple. So there is nothing interesting to demonstrate yet.
A messaging library is shared between the front and back. It defines all the requests and responses that can pass between them.
The host application is WPF. WinForms would work too. Either way there is not much to it. The only control is the WebView2 control. And about 40 lines of wiring code.
For communication between the JS front and .NET back, I used WebView2's string-based messaging. Each side gets some functions to send/receive messages. Types from the messaging library are converted to JSON strings for transport.
The repo
kspeakman / FSharpHtmlDesktopApp
A starter desktop app which uses HTML and F# for the UI and F# .NET for the API.
Closing thoughts
This was a fun weekend project. It has a lot of promise to make desktop apps more manageable for our dev team. I'll try it out this coming month and let you know how it goes. For now, let me know what you think about making desktop apps with web tech and F#.
Top comments (4)
This is an approach I've been wanting to use more frequently, I started with .NET using UWP + JS apps and I loved it
These days with a WebView with a modern JS engine, the development setup could be much much simpler, no need for crazy bundlers (with ESModules and soon CSS imports)!
I'll further check this one out thanks for sharing it 😁!
Thanks for the article! I wonder if you ran into any of these keyboard/focus issues with
WebView2
?It's quite worse with
BlazorWebView
, I wonder if they'll actually ship it like that.Thank you for discovering and reporting those issues! That is a community service.
I haven't run into them myself. Our users do not tend to use keyboard shortcuts. I do not plan to use any WPF-side UI elements, so split focus should not be an issue. But these issues should be fixed.
Nice article! This is an approach that I am wanting to start using too. I've signed up to Isaac Abraham's upcoming SAFE stack course and I'm wanting to apply that for both web and desktop.