Best option to do desktop apps in Elixir

Background

I have a little pet project that does some requests to an external site. The logic is pretty much figured out and now I want to do a Desktop app with it.
This desktop app has 2 requirements:

  1. it needs to be in an executable file that one can run by double clicking.
  2. it has to work for Linux and Windows.

Options

So, I have made a small research and found 2 main options:

  1. Make a webapp using PhoenixLiveView and turn it into a desktop app using webengine_kioks. A blog post describing this can be found here (https://puddleofcode.com/story/how-to-create-desktop-application-with-elixir).
  2. Using Scenic to make a desktop app

The first option looks rather gimmicky. Communication between Phoenix and my app would be done in HTTP and I would have to add some workarounds to make it feel like a desktop app. I would also have to link the Qt library to the release for Linux and Windows.

The second option looks rather promising, but I am not sure on how to use it with mix release, nor how it would work with Windows.

Questions

With this in mind, I have some questions:

  • Is there a default way to make desktop apps in Elixir? (If so, what is it?)
  • Which of the two options I studied would be the best way to go?
  • Is it possible to create an executable that launches the app when I double click it?

Scenic do not work well with window resizing due to the nature of their approach to positioning the widgets. This makes it hard to work in non-embedded/non-kiosk solutions where the screen resolution and window size may vary.

Well, OTP ships with WxWidgets integration that is used by built-in projects (Observer) and few external ones (Wings 3D).

Depends on what you mean by “double click”. You can package it for Linux to be installed via system package manager (DPKG/RPM) and on Windows you can create installer with Inno Setup or other tool like that. Then you will provide user with shortcut that will give them “click-to-run” experience by hiding whole complexity. It will also provide you with a way to have nice icon for your application.

1 Like

Isn’t this the same solution Scenic uses behind? Wouldn’t I have the same issue?

So, if I understand, Scenic may have troubles with resizing.
But besides doing my front end in Erlang and using the base WxWidgets library directly, is there an Elixir alternative out there?

Scenic doesn’t have any troubles with resize, as far as I remember it simply doesn’t allow for it.

It expects a fixed size on window/screen creation and sticks to that until destruction of the “window”.

WXWidgets though is a windowing framework on top of the wx framework which works well on Linux if installed in the correct version, but I never even dared to try it on windows.

To be honest, the simplest way is to have a wrapper that ensures the phoenix server beeing started and then opens a browser in “app mode”.

Remember though, you still need to build for Windows and Linux separately, due to the well known “same platform” constraint.

3 Likes

Do you know of any libraries or examples that already do this?

You mean, to use mix release on a Windows machine and on a Linux one, right?

Sorry to ask, but what is the advantage of using Elixir versus something like Electron?

Even if I dislike JS and much prefer Elixir, I would choose JS to build a cross compatible application, that looks like a desktop application.

Having a self-healing app. Plus the fact that I already have the logic in Elixir and I don;t want to remake it in JS xD

Ok, that’s fair :slight_smile:

Electron also has a reputation for being a memory hogger, I’m not sure if it is still the case.

That does remember me an old topic…

But I see some advantages, cross compatibility, browser window management, simplicity.

So the big difference between e.g. the web and native UI (desktop or mobile) is the factor “browser”.

Small headsup: The following I’m not very knowledgeable in and might not be 100% correct and/or simplified.

For rendering thing to your display you need some OS specific code to send pixels to the graphics card and whatever else is involved in rendering. The second part is a rendering engine. That one takes the code programmers produce and runs it turning it to a bunch of pixel color values x amount of times per seconds.

Browsers being installed on any system do have those parts taken care of and programmers can just ship the “runtime” (html).

Without the browser you need something to talk to the various (or shared) graphics libraries of the target OSs. Things like open_gl (cross platform), metal (mac), vulcan (linux), directx (win). Then you need something, which can take in code and translate to whatever those graphics libraries need. Those are tools like qt, wxwidgets, scenic, flutter, gtk or “browsers” (installed manually or with like an electron app) which can work cross platform, or things like .NET UI libs for windows, swift UI for macs / idevices or whatever linux uses (gtk?).

And that’s only talking about the part of being able to “program ui” and being able to display graphics.

The next part to consider is UI libraries. Just like html has preexisting elements (e.g. form elements, …) the same is true for for UI in desktop apps, but with even more prebuild components, which are often also “higher level”. Each OS comes with one of those, which runs the “OS” itself and is therefore inplemented only in the OS specific tools. The cross platform ones have to implement their own either by creating a “custom” look&feel or trying to mimic native UI per platform or a mixture of both. This also means they’ll unlikely ever be perfect replications of the native UI.

When you’ve chosen for the above then you’ll additionally need to care to run whatever elixir code there is left for you to run cross platform.

1 Like

I don’t have much experience to agree with the article’s title but it sure me laugh.

I agree that the idea is really interesting behind electron but I never really got into it.

One day maybe, when the time to get something for desktop arrives.

Well, I would call it a trouble :wink:

I do not remember, but even if, the Scenic uses Wx only to create window with OpenGL context inside. After that everything is handled via OpenGL. Wx is fully fledged widgeting system that passes everything to C(++?) where it is handled in platform dependant way. So the approach is quite different even if some components are shared.

You can use Erlang libraries from Elixir code without any problems. And if you need, you can create wrapper that will make it easier.

Apple M1 with Big Sur may be the step into the right direction, where you can write native application once and share it through whole ecosystem without any recompilation. That may be interesting to see how it will go.

3 Likes

I can think of two apps that do this: Unifi Controller (for controlling Ubiquiti wireless APs and other such products), it starts a Java app that just has a button “open in browser”. The other example is CUPS, which can be viewed on localhost port 631 by default if you have cupsctl running.

What do you guys think of this snippet? Would it be useful?

Do you know/recommend any in specific?

No, that is why I have written “you can create […]” :slight_smile:

But not Revery:

The new editor one the block uses it.

3 Likes

Have you used the editor already? How is it with elixir?

Not yet, just saw it yesterday here:

1 Like

I was thinking of looking into Chromium Embedded Framework (https://github.com/chromiumembedded/cef) with LiveView as source for its web views.