blogccasion

Cross platform software frameworks

Cross Platform Software Frameworks

The other day, I came across Elk Native, a native version of the rather excellent, if early-stage, Mastodon Web client Elk. To be honest, I wondered why they would build a native version, if the Web client works so well. I downloaded the 7.8 MB Elk_0.4.0_macos_x86_64.dmg and immediately ran into Issue #74, that is, a blank screen.

To better understand the motivation behind the Elk Native developers, I tried the same for one of my apps, with different frameworks. This repository contains the same PWA, SVGcode, wrapped five times with different cross platform software frameworks.

Running the apps

SVGcode is included as a git submodule in each framework folder. To run the apps, you first need to build SVGcode, and then start the wrapper app. In each subfolder, run the following commands.

npm run build-svgcode
npm start

Included frameworks

Screenshots

  • Electron.js
  • NW.js
  • Tauri
  • Neutralinojs
  • Gluon

Issues

⚠️ I'm a Web developer, not a desktop app developer. I simply followed the "Getting started" guides and may well be holding the frameworks wrong.

While I managed to get all apps to run, none of them worked perfectly out of the box, and there was always a strange error I could not explain. SVGcode works fine on Chrome, Safari, and Firefox when run in the standalone browsers. To see what's under the hood of the frameworks, I looked at the user agent data via DevTools.

// If `navigator.userAgentData` is available, use it.
copy(
  JSON.stringify(
    await navigator.userAgentData.getHighEntropyValues([
      'architecture',
      'bitness',
      'model',
      'platformVersion',
      'uaFullVersion',
      'fullVersionList',
    ]),
    null,
    2
  )
);

// Else use the user agent.
copy(navigator.userAgent);

Electron.js

Clicking the Copy SVG button causes an Uncaught (in promise) ReferenceError: Cannot access 'P' before initialization. error.

{
  "architecture": "arm",
  "bitness": "64",
  "brands": [
    {
      "brand": "Not A(Brand",
      "version": "24"
    },
    {
      "brand": "Chromium",
      "version": "110"
    }
  ],
  "fullVersionList": [
    {
      "brand": "Not A(Brand",
      "version": "24.0.0.0"
    },
    {
      "brand": "Chromium",
      "version": "110.0.5481.100"
    }
  ],
  "mobile": false,
  "model": "",
  "platform": "macOS",
  "platformVersion": "13.3.0",
  "uaFullVersion": "110.0.5481.100"
}

NW.js

Clicking the Copy SVG button causes an Uncaught (in promise) ReferenceError: Cannot access 'P' before initialization. error.

{
  "architecture": "arm",
  "bitness": "64",
  "brands": [
    {
      "brand": "Not A(Brand",
      "version": "24"
    },
    {
      "brand": "Chromium",
      "version": "110"
    }
  ],
  "fullVersionList": [
    {
      "brand": "Not A(Brand",
      "version": "24.0.0.0"
    },
    {
      "brand": "Chromium",
      "version": "110.0.5481.97"
    }
  ],
  "mobile": false,
  "model": "",
  "platform": "macOS",
  "platformVersion": "13.3.0",
  "uaFullVersion": "110.0.5481.97"
}

Tauri

Clicking the Save SVG button does nothing.

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)

Neutralinojs

Clicking the Open Image button does nothing. Clicking the Save SVG button does nothing.

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)

Gluon

Fails with a RangeError Failed to execute 'createImageBitmap' on 'Window': The crop rect width is 0..

{
  "architecture": "arm",
  "bitness": "64",
  "brands": [
    {
      "brand": "Chromium",
      "version": "110"
    },
    {
      "brand": "Not A(Brand",
      "version": "24"
    },
    {
      "brand": "Google Chrome",
      "version": "110"
    }
  ],
  "fullVersionList": [
    {
      "brand": "Chromium",
      "version": "110.0.5481.177"
    },
    {
      "brand": "Not A(Brand",
      "version": "24.0.0.0"
    },
    {
      "brand": "Google Chrome",
      "version": "110.0.5481.177"
    }
  ],
  "mobile": false,
  "model": "",
  "platform": "macOS",
  "platformVersion": "13.3.0",
  "uaFullVersion": "110.0.5481.177"
}

Building the apps (incomplete)

I started looking into building the apps, but didn't get too far. Electron.js looks like it has the most developed toolchain, but when I ran electron-forge make, I ended up with a 332,1 MB executable called svgcode-electron.app that only showed a white screen, despite the electron-forge start development app working mostly fine.

To build the apps, run the following command in each subfolder. (So far I have only worked on Electron.js.)

npm run build

I didn't even look into the signing part, which is required for proper distribution.

Conclusions

I'm not sure what to make of this. To be honest, I didn't see anything that would be more compelling than just browsing to svgco.de, clicking Install, and be good. But then I obviously didn't tap into any of the native features that cross platform frameworks allow you to do. I only noticed how features that I get for free in the Web version, like Window Controls Overlay or File Handling were broken. But again, I may just be holding these frameworks wrong. For now, it was a worthwhile exercise, but I think I'll stick to the Web.

You can edit this page on GitHub.

Webmentions

7 Replies

@bmann I get it, but to be honest: Nothing beats going to a URL and hitting Install. Installed PWAs run in their own “alt-tab”-able window and (even not installed, unless it’s iOS) can receive notifications.
@tomayac ironically … distribution is one of the things I see. The native platforms have app stores and the act of “downloading”.And is in some ways expected by the average user of an app that they’ll go back to more than once. For desktop users, window management and notificatio […]
@tomayac that’s unfortunately not true for mass market, neither on desktop nor mobile. The patterns and muscle memory aren’t there, and the popular mentality is “go to an App Store”As much as anything else, a large market player would need to invest heavily in culturally changing […]
@crispinb I would love to understand this point more. Do you have an example of such a situation? Note: I’m not talking about apps that tap into the native APIs (there I get it), I’m talking about wrapped Web apps that don’t need that.
@bmann Right, muscle memory is a good analogy. But as I just wrote in another toot, just try searching for Facebook’s Messenger. It’s a total mess. But yeah, collectively, we have trained people to go to stores first. That can be undone, though.

1 Mention