Desktop applications are somewhat of a niche for developers. The vast majority of user interfaces are developed for the Web using HTML, CSS, and JavaScript. When we build desktop apps, we've had to use different tech. We've built desktop applications with Windows Forms (WinForms), with Windows Presentation Foundation (WPF), with Universal Windows Platform (UWP), with Xamarin, and with Xamarin Forms. All of those products are different technologies, different tech stacks, and have their own learning curve - and most of them only run on Windows. Only Xamarin can run cross-platform.

Photino is an open-source project that lets developers use HTML, CSS, and JavaScript to develop the UI for desktop applications. One UI stack to rule them all! (Sorry, JRR Tolkien)

A Photino is a hypothetical subatomic particle, the fermion WIMP superpartner of the photon predicted by supersymmetry. Even though no photino has ever been observed so far, it's one of the candidates for the lightest supersymmetric particle in the universe. – Wikipedia

If you're familiar with Electron, Photino is a similar concept, except that it uses .NET 5 for the host application instead of Node.js, and it uses the OS's default browser control instead of downloading Chromium. In keeping with a photino being the lightest particle in the universe, Photino applications are more lightweight than Electron applications. You can find more information on Photino at https://www.tryphotino.io. You can see this in Figure 1.

Figure 1: Cross-platform .NET 5 desktop apps with HTML, CSS, and JavaScript UI on Windows, Mac, and Linux
Figure 1: Cross-platform .NET 5 desktop apps with HTML, CSS, and JavaScript UI on Windows, Mac, and Linux

Quick Start

If you're using Visual Studio 2019 or later, you can get started by clicking Manage Extensions from the Extension menu, going to Online in the left tab and searching for Photino, as you can see in Figure 2.

Figure 2: Visual Studio 2019 and later. Install the Photino Project Templates.
Figure 2: Visual Studio 2019 and later. Install the Photino Project Templates.

When you're creating a new project, just search for Photino in the New Project dialog to see the sample projects you can choose from to create starter projects.

If you're a .NET CLI user on Windows, Mac, or Linux, you should install the Photino for .NET CLI and VSC Code Project Templates NuGet package from NuGet.org. Assuming you've already installed the .NET 5 SDK (not just the runtime), type dotnet new –install TryPhotino.VSCode.Project.Templates to install the templates, dotnet new -l to list installed templates, dotnet new photinoxxxxxx to create new projects from the templates, and dotnet run to run the samples.

I recommend using the photinoapp template for your first project. It creates the most basic HTML UI I could come up with to demonstrate how Photino works. Use that template to create the sample project and press F5 (Visual Studio) or .NET run (dotnet CLI), as shown in Figure 3.

Figure 3: A basic Photino application created from the photinoapp project template
Figure 3: A basic Photino application created from the photinoapp project template

Figure 4 shows the source code for this basic Photino project opened in VS Code. The user interface consists of the index.html file, the main.css file, and the photino-logo.svg image file. The HTML is pretty simple and relatively boring. In this case, I included JavaScript for handling the button click in a <script> tag, but I could have put that in a separate .js file. In fact, you can do pretty much anything in a Photino UI that you can do on a Web page intended for the Internet, plus a few more things.

Figure 4: The source code for the basic Photino application
Figure 4: The source code for the basic Photino application

In the script tag, you'll see a basic method of communicating between the UI and the host app (the hidden console app) depicted in Figure 5). When the button is clicked, it calls window.external.sendMessage('Hi .NET!'), which sends the string via a memory buffer to the C# code in Program.cs. The C# code prepends Received message: to the incoming string and sends the full string back to the UI. JavaScript also sets up a handler for those responses with window.external.receiveMessage(message => alert(message)); which just displays whatever string comes back from C#.

Figure 5: Basic inter-process communication (IPC) via memory buffer
Figure 5: Basic inter-process communication (IPC) via memory buffer

In the additional templates, you'll see examples of communication using WebAPI and gRPC. These examples show how to call into the host application with the same built-in JavaScript AJAX REST mechanisms that Web developers are used to for calling services and how to build host functionality the same way you build a service. And of course, you can mix and match and extend all of these mechanisms.

Other templates show projects using Angular, React, and Vue for building the UI and are a quick way to get a project using one of these frameworks up and running, so you can take it from there and build an awesome desktop application with your favorite Web UI framework. There's even a template that shows using the 3D.js framework to build a 3D UI. In addition, there's an Advanced template that shows interactions with the host operating system, including showing the Swagger documentation for the WebAPI exposed by the host, running PowerShell cmdlets (many of which run on Windows, Linux, and Mac) without requiring PowerShell to be installed on the host and using native dialog boxes, such as the Open File dialog for the OS the application is running on. There's even a template that runs Blazor.

What Magic Is This?

You might be wondering how all of this works. If so, read on! Photino's origin was a demo project called WebWindow created by Steve Sanderson (the guy who brought us things like knockout.js and who now works on the .NET 6 team). Photino started with the somewhat raw WebWindow code, stabilized and extended it, and packaged it for easy use. Photino actually lives in a set of GitHub repositories.

The core of Photino is the Photino.Native repo (GitHub.com/tryphotino/photino.native), which is a native C/C++ wrapper around the WebView2 (Chromium) browser control for Windows, a native Objective C/Objective C++ wrapper around the WKWebView (WebKit) browser control for Mac and a native C/C++ wrapper around the WebKitGTK (WebKit) browser control for Linux. These browser controls typically come with the operating system and don't have to be downloaded. This produces three small native wrappers, one for each OS, that opens a native window on that OS, fills the window with a native browser control and provides a standard interface to the native window and the native browser control to the hosting application. You wrap all three libraries in a single NuGet package. Notice that at this point, there's nothing specific to .NET. In fact, any language that's capable of using a native library (.dll for Windows, .dylib for Mac, and .so for Linux) can use Photino.Native. I'd love to see Photino.cpp, Photino.rust, photino.go, etc., ecosystems in the future.

Nobody but C developers actually likes calling DllInvoke, marshalling references, or allocating memory. So for .NET developers, the Photino developers wrapped the Photino.Native libraries in a friendly .NET wrapper named Photino.NET (GitHub.com/tryphotino/photino.net). Photino does all that low-level stuff for you and creates a NuGet package with a dependency on the Photino.Native package, so all you have to do is install the Photino.NET package and start writing .NET 5 desktop apps with Web UIs that can run on Windows, Mac, and Linux.

Although .NET 6 promises Blazor on the desktop, it's still in early days, so the developers of Photino built on the Photino.NET package to create the Photino.Blazor package (GitHub.com/tryphotino/photino.blazor). It adds everything you need to build desktop apps with a Blazor UI, including Razor pages. It uses some of the .NET 5 Blazor source code from the open source repo to keep it as slim and lean as possible. Open source contributors created a NuGet package for it with a dependency on the Photino.NET package, so all you have to do to write cross-platform Blazor desktop apps is install the package.

The Photino.Samples repo is a collection of samples that highlight things you can do with Photino in .NET and are used as the basis for the project templates (GitHub.com/tryphotino/photino.samples). In most cases, you can just use the templates and get to a running sample app. You can find out more about Photino by checking out the docs from the link on http://tryphotino.io.

Did I Mention That It's Open Source?

If you want help extending or improving Photino, open source always welcomes new contributors. Although the Photino project is sponsored by CODE, outside contributors promote a vibrant community and ensure that Photino stays around for a long, long time and ensures that it can do what you need it to do. If there's a feature you need, you can suggest it to the community or you can write it yourself and get it included in Photino. Or maybe you just want to dig into Photino and see how something was done or troubleshoot an issue you're having. The source code is there for you!

Summary

In this article, you've gotten hands-on experience with creating, exploring, and playing with Photino applications. You've seen some of the basics for communication between the UI and host app, heard about using popular JavaScript frameworks on the Desktop, seen where to find examples of some advanced features and even how to use Blazor. For those of you who're curious, you got the skinny on how Photino was created and how you can dig into it even deeper. I can't wait to see what you can do with Photino.