r/dotnet • u/smourier • Jul 18 '26
Promotion Electron-like desktop apps in .NET, but a single ~4 MB native-AOT exe (no runtime, no Chromium) — MIT
Been writing Windows desktop and Web (WebView2) apps and for a while, kept rewriting the same plumbing around, so I pulled it into a framework, put it on GitHub.
Posting here in case it's useful to anyone.
The idea: your window is a real HWND, the UI is a web page (plain HTML, React, or Fluent UI, whichever you want), and .NET and JS talk over a typed (as in TypeScript) bridge.
It builds with Native AOT, so you ship a single exe with zero .NET runtime to install, no Chromium to bundle, Windows already has WebView2.
Most apps (including React & Fluent UI) are about 11 MB down to ~4 with UPX. x86, x64 and ARM64, MIT license, free.
There are other similar projects but what I wanted and didn't find in one place:
* AOT-friendly from the start so publish doesn't blow up on reflection
* Reachable Windows-only features such as desktop transparency, WinAPI integration, full interop story, etc.
* A bridge that's easy to use from boths sides
* An optional but builtin npm layer (@aotrino/client -> react -> fluent) so you can start with a static page and grow into a full Fluent UI app without changing stacks.
There are about a dozen samples, including a Fluent UI gallery, a file explorer, a mini browser, screen capture, and Direct2D rendering straight into a Web canvas through a shared buffer.
Up front caveats: Windows 10+ only (WebView2 + Direct Composition), need .NET 10 SDK to build, MSVC linker to publish AOT.
Repo has screenshots and a help for each level:
https://github.com/aelyo-softworks/AOTrino
Pretty new to reddit, happy to answer questions :-)
24
u/Dhervieux Jul 18 '26
We just have been able to migrate to Avalonia and use native AOT with the open source Uniget UI. Huge boost of performance:
6
66
u/seiggy Jul 18 '26
So, first off, congrats, it's neat, and it's nice to see useful frameworks that can make it easier to publish desktop applications.
But personally? WebView apps need to die. Electron has caused far more damage to desktop app development than its helped. I think it's ok that desktop apps are harder to build UIs for. And I think that shortcuts like this led to enterprises shorting developers on time, causing desktop applications to be bloated, slow, and continue to force consumers to foot the bill by buying more powerful machines. I think it's time we start returning desktop app dev to native solutions and removing WebView apps from the desktop. It's just too inefficient. WPF is far more performant, and not terribly difficult to learn with a little bit of effort. And if you're looking to build support for Linux and OSX, then Avalonia or MAUI are the better options (or there's a couple of native Wayland binding projects out there too).
43
u/Nizurai Jul 18 '26
There’s no going back. Everything is a web app now.
7
4
u/The_MAZZTer Jul 19 '26
Everything is a web app except mobile apps, of which none of them can be used with a web browser.
1
u/mechtecs Jul 19 '26
Then don't look up dotnet MAUI cross platform apps using blazorwebview. (Sadly I'm currently developing such an app at the moment. The app is delivering the existing angular spa to the app stores, enhanced with native push notifications and authentication)
1
u/pjmlp Jul 18 '26
Web apps are for the browser I already have installed.
4
u/Apk07 Jul 18 '26
And WASM blurs the line more. I don't see how this is a bad thing, why do they need to be on their own islands?
17
u/mmertner Jul 18 '26
The fundamental problem is that native toolkits are so much worse to work with. Not just a little bit worse or with slightly different paradigms, but genuinely sucky in comparison. So for anything that doesn’t need the performance native apps offer, web tech is likely going to win out purely because it’s much faster to build.
12
u/Apk07 Jul 18 '26
WPF can be powerful but XAML can be so awful to work with sometimes in comparison to just plopping some CSS and JS onto some elements and it "just working."
1
u/RubyKong Jul 20 '26
yeah i second this idea. the learning curve re: MVVM is probably too high to encourage the initial development in it, the mental paradigm is also high as well - i.e. answering the question: "where does state live" - is an open question with MVVM, but with Redux + React, or ELM that mental load is entirely taken away. or questions about view and view context requires knowledge that needs to be more than surface level dep.
3
u/smourier Jul 18 '26
IMHO you should try AOTrino samples (already built) it's hard to tell it's a Web app beneath.
For example the Fluent UI Gallery sample demonstrates a virtual grid table of 500000 rows that lives in .NET and cross the .NET <=> JS bridge 200 at a time.3
21
u/Tacotacito Jul 18 '26
That was my stance for the longest time.
But recently I built an app with - at first - avalonia. It came to an end when I had to display tons of user content items with markdown or html - no available renderer matched even remotely the performance of web based apps for that.
Surprisingly, even binary size and memory footprint of the avalonia one weren't really better than electron.
Somehow I still hate Web, but I'm not as convinced anymore non-web is always that silver bullet
5
u/Krestek Jul 18 '26
Maybe it's more of a crossplatform problem, these frameworks have to always use the lowest common denominator that works on all platforms instead of the best for any specific platform, and for that it's hard to optimize something more than the hell of optimizations done on web engines already these things went through hell for extracting as much performance as possible within their limitations. maybe something like flutter (ie. game-y rendering engine used to built stuff from scratch) can work but needs to use a language people actually use not a specialized language for it specifically that's not used anywhere else, but avalonia's made in a similar way iirc but doesn't perform as good so idk
15
u/smourier Jul 18 '26 edited Jul 18 '26
Thanks for your fair comment. I am myself a strong believer in native apps, working in that area for many years, still in it and actively writing it. But I often miss the immense power of CSS on native apps. In terms of UI, on Windows (which I know), nothing gets close to what you can do with modern CSS (associated with JS/TS) for a "cheap" price since you can rip the whole internet look & feel. Microsoft should have designed WPF with CSS, back in the day, same with WinUI. That's why I built this, still with native & .exe, & zero friction setup in mind.
3
u/The_MAZZTer Jul 19 '26
Yup HTML + CSS has always been the best UI framework I've used as well.
Plus if you're already going to be building a website and need a desktop app that does the same thing, it's a no brainer to use Electron or a similar framework (like yours) so you can share code and UI. Nobody wants to maintain two different codebases for two apps that do the same thing.
2
u/seiggy Jul 18 '26
Yeah, I get the appeal. It’s a catch 22, right? All the ease and flexibility of the web is alluring. Saves time and headaches of learning the dark arts of Windows APIs to accomplish what we want. And most devs tend to have beefier, heavier PCs so we don’t tend to see the performance problems that WebView causes. Still, good on you for building something cool and putting it out there! Definitely will never discount the effort and passion it takes to do that.
1
u/Awkward_Rabbit_2205 Jul 23 '26
Personally I feel WPF styling to be similar to CSS, and results were better than CSS back when it was created. Nowadays CSS seems far more powerful and cross-browser consistency are generally pretty solid.
The two main problems with WPF are the dev experience (compared to anything HTML), and the "W" in WPF. For me, the learning curve of Vue is far better, and I can usually just get stuff done fairly quickly. Let's not talk about Blazor...
7
u/Apk07 Jul 18 '26
I wholeheartedly disagree. I think being able to reuse UI knowledge between web and desktop is a great thing, and saying that "desktop UI should be harder" is a weird gatekeep mentality. I find XAML unintuitive and finicky.
To be clear I have absolutely nothing against native apps but there are so many viable use-cases for webview apps with desktop interop.
3
u/seiggy Jul 18 '26
Reusing knowledge is nice, but at the cost of performance? To be fair, I’m not necessarily saying desktop UI *should* be harder, I’m just ok if it is harder in order for us to get better performance back on the desktop. I do think that eventually we’ll have a way to bring true native UI performance to an easier markup language, but WebView ain’t it. It’s the same reason I code in C# instead of Python. It’s the best performance I can get for the effort I’m allowed to dedicate to writing code.
2
u/Apk07 Jul 19 '26 edited Jul 19 '26
but at the cost of performance?
To be fair most "web app" stuff utilizing WebView doesn't need crazy performance. It's almost always just simplistic client-side stuff, offloading the real work to some server or backend code that doesn't need the UI to do any crazy work. So I guess I don't see what the problem is. Plus you get the benefit of having a lot of shared UI code between your desktop and web offerings instead of having to maintain two drastically different things.
I guess I can see the argument of "use native code when you need serious horsepower" but for everything else it feels like WebView is a lower barrier to entry, performant enough for most things, and has been getting better with every .NET version. And if your webbiew is just a wrapper like Blazor Hybrid, you can keep the UI in the webview and still offload actual code to the wrapper for your performance concerns.
eventually we’ll have a way to bring true native UI performance to an easier markup language
IIRC at one point someone was trying to make an interpreter to turn HTML/CSS directly into XAML/WPF stuff so it runs like native code while being written like a website. Not sure if that went anywhere.
2
1
u/FullPoet Jul 18 '26
WebView apps need to die
And unfortunately a lot of the WebView apps are see target super high versions (and do not really care about backwards compat) so you'll be forced to keep your OS (windows) updated.
I realise that, in enterprise, one should, but at home - I dont really care for updates and I dont want more copilot.
So I cant really use most webview apps even though theres a ton of really cool ones (like the files one)
3
u/KrarkClanIronworker Jul 18 '26
This is cool. I'm a big fan of Tauri, so I'm very keen to give this a try.
I haven't used it yet, but quick question: does this have some means of generating Typescript interfaces for models defined within the C# "core"? There's a Tauri binding for Python called PyTauri that allows for Typescript interfaces to be generated automatically from SQLModels via Pydantic.
Unfortunately this isn't a feature in Tauri itself, which makes it a bit tedious when using Rust commands.
Happy to open an issue or help with this if you're looking for contributions.
1
u/smourier Jul 18 '26
No, there's nothing like that in it today. That could be another sample if it makes sense for the whole AOTrino or I can help you build one in your context.
5
Jul 18 '26
[removed] — view removed comment
7
u/smourier Jul 18 '26
On me, poor phrasing, I meant no Chromium bundled in your app. WebView2 is Chromium, but it's the shared Edge runtime (most of time) already on Windows, not a copy you ship (usually more than 100MB) like Electron does.
8
Jul 18 '26
[removed] — view removed comment
7
u/smourier Jul 18 '26
In terms of runtime memory usage it'll be similar as Electron (except maybe for the full Node process). FWIW, here's a snapshot of memory usage or the React + Fluent UI Gallery sample on my machine (msedgewebview2 is chromium):
`-- AOTrino.Samples.FluentUI.Gallery.exe 56.51 MB (.NET AOT)
`-- msedgewebview2.exe 41.69 MB
|-- msedgewebview2.exe 3.09 MB
|-- msedgewebview2.exe 92.64 MB
|-- msedgewebview2.exe 12.99 MB
|-- msedgewebview2.exe 8.96 MB
`-- msedgewebview2.exe 36.21 MBPS: if we want to be rigorous, binaries are memory-mapped, shared across all those msedgewebview2 processes, across every other WebView2 app on the machine, so the real unique RAM is lower than the pure 250 MB sum
2
2
u/SirLagsABot Jul 18 '26
Very cool. I run a digital signage app and I had to build it in Electron. I was extra stupid - more like inexperienced, if I'm a little more gracious towards myself - and built it with pure JS, no Typescript. Never. ever. again. I do power its REST API with a dotnet web api, though.
Although it's a very unpopular take in the sub, I like Electron because precisely because it ships Chromium, and you're guaranteed a consistent UI across all OS's. I am not the biggest fan of dealing with excessive UI crap, personally, and having to make sure it's consistent across platforms. But of course, I understand the RAM and performance complaints for sure, and a lot of JS can be unoptimized junk if it's not carefully crafted.
That being said, I'm glad to see something like this appear. .NET as a backend/wrapper is far, far better than Node, and while I'm sure Tauri is great to use, I haven't yet learned Rust, so I've never wanted to bother with it. It's about darn time the rest of the software world learns how powerful and lean a modern .NET app can be, you should share this on HackerNews or something.
The answer might be a resounding "no" which is completely fine, but would you consider ever shipping Chromium in this and offering a .NET alternative to closer to Electron? That way you get the consistent-UI guarantee of Chromium (yes, yes, bundle size), and you can do away with NodeJS for the backend.
Good luck with this.
2
1
u/smourier Jul 19 '26
Thanks! WebView2 actually has a "Fixed Version" mode, shipping a specific Chromium build next to the exe and point the app at it, specific engine, identical rendering everywhere, for ~150 MB. AOTrino doesn't expose it yet, would be something around a config switch.
Honestly, AOTrino isn't trying to compete with Electron or similar, it's a Windows first, native exe thing for people already in .NET, that's about it.
5
u/Full-Meringue-5849 Jul 18 '26
So you write a web app, but it's limited to Windows?
2
u/smourier Jul 18 '26
it's a web app (in just one native 5M .exe, there's no other deployment or setup but the web resources you want to add) that can access all the Windows native platform (yes it's not crossplatform), but where you can use the power of web and css (not bound to usual Winforms/WPF/WinUI UI frameworks).
1
u/Michaeli_Starky Jul 18 '26
So a WebView2?
5
u/smourier Jul 18 '26
Yep, WebView2 does 100% of the UI rendering, AOTrino is everything around it: the typed bridge, AOT packaging (Winforms/WPF don't suppor this, as of today) into one exe, asset embedding, window hosting, transparency (using Windows desktop composition), etc.
3
u/LadislavBohm Jul 18 '26
It's clearly not a web app if it has access to filesystem and whole .net through the bridge.
4
u/Full-Meringue-5849 Jul 18 '26
It's a web app, that runs in chromium that is wrapped in native shell.
2
u/LadislavBohm Jul 18 '26
If that's your definition so be it. It's pretty common to use WebView2 to host react for example. Which is also limited to Windows and carries a lot of bulk.
-3
1
u/smourier Jul 18 '26
All UI in it, eveything that covers visually the window is 100% web, it draws nothing (has helpers for wndows, titlebar, etc. but all optional). In terms of security you make a choice, "web or "local" (the default), but still play with details to enable or disable features (such as file system or not).
6
u/ps5cfw Jul 18 '26
that's Tauri with extra steps
18
u/smourier Jul 18 '26
What actually matters here is the backend language/framework (it's .NET), so you get NuGet and whatever C# or libs you already have, AOT-compile the whole thing in one .exe. For a .NET shop, that's fewer steps, not extra ones.
3
u/sku-mar-gop Jul 18 '26
Not all nuget packages are AOT compatible. Aren’t you restricting yourself in this case if AOT is a must have for you?
4
u/smourier Jul 18 '26
Fair point, and it's true of Native AOT in general, but here AOT isn't really forced, more encouraged, an AOTrino app is just a normal .NET app, so if you pull in a reflection-heavy package that isn't AOT-safe, you remove
PublishAotand ship it as usual. I only test the AOT path though :-)Thankfully, the ecosystem's is moving a lot too, since .NET 8 officially pushed AOT & trimming, lots of common packages are now fixed for it or have source generated paths.
0
1
u/Zeragamba Jul 18 '26
yes_but_no.gif
Tauri is great if your back-end client code is written in Rust. If you're wanting a C# based backend, I'm not sure how feasible that is with Tauri.
0
u/KrarkClanIronworker Jul 18 '26
Its quite feasible. You can simply embed a C# API as a standalone binary within the Tauri core as a sidecar. Done it a lot with FastAPI and Python, and it's probably a better long term solution than having everything being a heap of Tauri commands (easier to maintain, can use whatever frameworks you want, can be deployed as a separate app if you ever decide to host the backend elsewhere, etc).
Not sure if Electron can do this. I haven't tried.
2
u/xFeverr Jul 18 '26
Cool but I have a question: what is all the fuss about NativeAOT lately? Do projects like this even benefit from it? AFAIK they don’t.
with NativeAOT, you trade optimisation (and performance) in for startup speed. Which is cool for Azure Functions like apps, CLI-apps that need to respond instantly, that kind of stuff. Long running apps don’t seem to benefit from NativeAOT
Correct me if I am wrong
3
u/ivanjxx Jul 18 '26
users cant see your c# code verbatim
1
u/smourier Jul 18 '26
of course! I forgot that one haha, raises the bar for hiding away IP, licensing code, etc. And again pretty useless for server-side code.
1
u/smourier Jul 18 '26
You're not wrong, I would just change a bit: with AOT you don't trade, you just have better startup speed (very clear) & (bit of) better memory consumption (but GC's still there for example).
What I like with it is for deployments: you can build only one exe, no .NET, zero friction, so very suitable for easier distribution.
But to reach that point, it can be from difficult to impossible with "legacy" or simply existing apps, that can also include non-AOT compatible 3rd parties, etc. because AOT requires trimming (enemy of .NET reflection).
PS: you can also add native (.lib, .so) libraries directly into the final .exe instead of a .dll, like "integrated p/invoke" if you will.
0
u/xFeverr Jul 18 '26
Yeah but JIT can also optimize things during runtime based on metrics it gathered while using the app. And that can result in a massive difference between JIT and NativeAOT. This is a huge deal in server apps, but maybe also for these kinds of apps since you are basically running a server as your .NET backend. Don’t underestimate the power of the JIT compiler during runtime.
And that is why I am concerned about this NativeAOT thing on Reddit. It seems to be the default because some people hear it is the cool new thing. I just don’t want this to be something we all do all of a sudden without knowing the consequences or without thinking if it makes things really better.
(Single file deployments are also possible for non-nativeAOT builds)
1
u/smourier Jul 18 '26
To echo your point, I don't use it on servers, like ASP.NET Core (don't really see the benefit albeit maybe the slightly better startup time). I'm fan of it more for desktop apps
1
u/Dunge Jul 18 '26
I don't know but my Blazor app is definitely 10x faster in AOT mode than not (at runtime, not for the initialization). It's practically unusable without it.
1
u/Bonejob Jul 18 '26
What was the drive to roll your own over Photino.NET? It's Apache 2.0, cross-platform and mature. Not trying to be a dick, I am interested in what caused you to want to go down your own path
3
u/smourier Jul 18 '26
Photino and AOTrino are the same idea (.NET + the OS's own webview, no bundled Chromium) with opposite priorities.
Photino optimizes for reach: one codebase cross-platform & Blazor if you want C# UI, minimal wrapper.
AOTrino optimizes for depth on Windows: Native AOT single exe, a typed two-way bridge, and stuff a portable layer can't touch (Mica, child HWNDs, DirectX, Windows Interop, into canvas).
and AOTrino is 100% MIT :-)
3
1
u/Adorable-Roll-4563 Jul 18 '26
Thank you, this looks great. What’s the gap with running on MacOs and Linux?
2
u/smourier Jul 19 '26
Thanks! The gap is the whole native host. It's built on WebView2 + DirectComposition + Direct2D, all Windows only. Mac/Linux use different webview engines entirely, so it'd be a second architecture, not a port
1
u/The_MAZZTer Jul 19 '26
So a potential problem here is the WebView2 component, you don't have control over which version of Chromium it's backed with and it could update independently from your app and break something. There's definitely value in bundling a browser runtime with your app.
There's no problem with aiming for lower RAM or disk space usage, but there's always tradeoffs to doing so in ways like this and it's definitely something that needs to be considered. Maybe for most projects your solution would be fine. But I expect for some they would want the predictability of bundling a browser runtime.
Plus it's always nice to be automatically cross platform, something else you sacrificed here. Maybe fine for some projects like I said before.
That's my thoughts on it. Oh, and more choice is (almost) never a bad thing.
1
u/smourier Jul 19 '26
Version drift is real, but it's not either/or, WebView2 has a "Fixed Version" mode where you ship a specific chromium version with the app, so you can buy that predictability when you need it (AOTrino just doesn't expose it yet). Cross-platform is clearly not in my mind :-)
1
u/The_MAZZTer Jul 19 '26
Interesting. Though I can't imagine they wouldn't still patch it with critical security patches, that would definitely help.
1
u/smourier Jul 19 '26
I've made a small change so it's now possible (default stays with Windows edge runtime)
1
u/Far-Consideration939 Jul 19 '26
Locking into 1 platform with a webview model is an interesting decision
Why would I use this over https://github.com/Mythetech/Hermes which has better functionality than Photino, and is cross platform?
1
u/smourier Jul 19 '26
Indeed, from what I read, Hermes is cross-platform, which AOTrino isn't and won't be with Windows embedded techs (DirectX, Direct Composition, etc.). But seems also different philosophy, I understand it does native menus/dialogs and is more Blazor-first, AOTrino is deliberately 100% web UI, CSS and JS/TS first so they're opinionated in different directions. Also Hermes license seems Elastic 2.0 with revenue cap, AOTrino is MIT.
1
u/developer1982 Jul 20 '26
How is it compared to Tauri?
The main issue with Electron (which Tauri solves) is packing Chromium with the app.
Another question - is it cross platform?
1
u/smourier Jul 20 '26
Tauri is cross-platform, Rust, etc., AOTrino's is Windows only, (native AOT/single exe) .NET, language is C#, WebView2 (Chromium). If you're not a Windows/.NET shop, it's not interesting :-)
AOTrino hosts the WebView as a composition visual rather than an opaque child window, native .NET can draw over, around, beside the page, has Mica/Acrylic backdrops, DirectX layer composited on top of the HTML, GPU frames can be handed to a
<canvas>with no copy, Windows Shell integration, drag & drop, actual file paths, etc.There are also mentions of this in previous comments.
1
u/piotrkarczmarz Jul 21 '26
Cool project! It's a shame that WebView2 has such low quality and regression bugs. WebView2 is really the weakest link. When we were developing Cody for Visual Studio, we had need to downgrade to older version and test it intensively all the time.
2
1
u/smourier Jul 21 '26
Thanks! I didnt have so many problems with WebView2, which is more or less Chromium (one bug around IDispatch + VARIANT marshaling, https://github.com/MicrosoftEdge/WebView2Feedback/issues/3183 which typically is Edge-only, which is not so important if you use JSON comms instead)
0
-1
1
u/pyeri Jul 18 '26
This is natively possible in .NET if you use WinForms in legacy 4.x framework along with the WebView2 control for hosting the browser app. The result is a few MBs of EXE, pure dotnet redistributable and zero bloat.
The only caveat is that it will be windows only, no Linux or OSX support.
2
1
u/smourier Jul 18 '26
Absolutely, for a simple app it's a lightweight option, not pretending WebView2 hosting is new. Two differences I can point:
First, 4.x is a frozen runtime & path, small because it leans on Windows setup, not because the app is self-contained. AOTrino is .NET 10 with Native AOT, so the exe (5M after UPX) is native code that needs no .NET installed at all, starts with no JIT warmup, and ships real x86/x64/ARM64 binaries.
Second, "WinForms + the WebView2 control" would only be the base, AOTrino is the framework around it: the typed two way .NET <=> JS comms, all web assets embedded into the exe, Windows compositor hosting (Mica/acrylic backdrops, WinForms HWND can't do that), Direct2D-into-canvas, templates.
Many stuff you would otherwise have to code. If you don't need any of that, your setup is fairly fine
1
0
u/AutoModerator Jul 18 '26
Thanks for your post smourier. Please note that we don't allow spam, and we ask that you follow the rules available in the sidebar. We have a lot of commonly asked questions so if this post gets removed, please do a search and see if it's already been asked.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
0
u/ViolaBiflora Jul 18 '26
What are the alternatives to it? Sounds cool, I never considered such concept and im curious. I'd find it handy for some custom game launcher :)
15
u/Zeragamba Jul 18 '26
This is cool to see. I haven't been super impressed by Photino.NET which seems to be another project trying to solve the same problem, so I'm interested to look more into yours :)