· projects · 5 min read

PC Specs

Cross platform desktop app that displays your computer specs

Cross platform desktop app that displays your computer specs

The struggle

What do you use to make a cross-platform desktop app? This is not rhetorical, please tell me.

Before embarking on this project, I spent a long time looking for answers to this question. I wanted to make an app that has decent performance and has a small binary size that works on Windows, Mac, and Linux.

The best choices I could find are:

  • Flutter 👎
    • Requires Android Studio and is mainly geared towards mobile apps.
  • Electron 👎
    • Uses Chromium, which is a huge dependency. Also, it’s not very performant.
  • NW.js 👎
    • Massive binary size, includes Nodejs.
  • Tauri 👎
    • This is a new project that looks promising. However, each build must be done on the target OS and takes a looong time. The setup is also a bit complicated.
  • Qt 🤷
    • For good performance this would require using C++ and Qt Widgets, which can be complicated to learn. PyQT is also an option, but it’s not very performant. The distribution is also a bit complicated. However, I do think this is the best option if you’re willing to put in the work.
  • Neutralinojs 👍
    • This is the best option I found for my use case. It’s easy to use and has a small binary size.

I recommend XPDA and this comparison for more information.

Not again…

sun position

”Too many js frameworks”, taken from devrant.com.

Copyright © 2019 DevRage.

Since Neutralinojs uses JavaScript, I had to choose a framework for the job. There are way too many options, each with their ups and downs. I decided on Solid.js because I haven’t used it before, and I’ve heard good things about its performance and approach to state management.

For the app itself, I wanted to make something simple that I could use to learn the framework. I decided to make a simple app that displays your PC specs. I used the systeminformation package to get the data, which nicely displays what information you can obtain on each OS.

To access the system information, I used the Extensions API. This allows you to run a binary on the computer and communicate with it using JSON over WebSockets. I decided to use Nodejs for the extension so everything is using the same language, cross-platform bundling and packaging is also easy using esbuild and pkg.

Findings

Neutralinojs

Neutralinojs is a great tool for building cross-platform desktop apps. It’s easy to use and has a lot of features, but the documentation is a bit lacking and confusing. The security is also disappointing, but it’s not a big deal for my use case.

Size

📂 .
├── 📂 dist
│   ├── 📂 pc_specs
│   │   ├── 📂 extensions
│   │   │   └── ...
│   │   ├── 💾 pc_specs-linux_x64      [~2MB]   (app binary)
│   │   ├── 💾 pc_specs-mac_x64        [~2MB]   (app binary)
│   │   ├── 💾 pc_specs-win_x64.exe    [~2MB]   (app binary)
│   │   ├── 💾 resources.neu           [~100KB] (app resources)
│   │   ├── 💾 WebView2Loader.dll      [~400KB] (app resources)
│   │   └── ...
│   ├── 📦 pc_specs_linux_x64.zip  [~20MB]  (app + extension binaries)
│   ├── 📦 pc_specs_mac_x64.zip    [~20MB]  (app + extension binaries)
│   ├── 📦 pc_specs_win_x64.zip    [~15MB]  (app + extension binaries)
│   └── ...
├── 📂 extensions
│   └── 📂 hardware
│       ├── 📄 build.cjs       [~1MB]   (extension bundle)
│       ├── 📄 build-linux     [~50MB]  (extension binary)
│       ├── 📄 build-macos     [~50MB]  (extension binary)
│       ├── 📄 build-win.exe   [~40MB]  (extension binary)
│       ├── 📄 main.js         [~5KB]   (extension module)
│       └── ...
└── 📂 my-app
    └── 📂 dist            [~100KB]  (solidjs+vite build)
        └── ...

As you can see in the diagram, the frontend is very small. The extension is also small, but the binaries are huge. The bundled extension is around 1MB, but the binaries are around 50MB each.

50MB each is a lot, especially considering that without the extension the app is usually less than 5MB. This is because the extension is a Nodejs app, and Nodejs is huge.

Since you don’t have to use Nodejs for the Extensions API, using something like Rust or Go might be a better option for creating the extension. This would allow you to create a much smaller binary. However, then you have to handle the cross-compiling and packaging of this binary.

Thankfully, compressing everything using zip reduces the size to around 20MB for each system, not bad! The .zip files above only include the files needed for their respective platforms.

Bundled using esbuild, packaged using pkg

I haven’t looked into how much size a self-extracting archive would use e.g. using makeself.

Conclusion

If you’re looking to build a cross-platform desktop app, Neutralinojs is a great option. I would still recommend Qt and C++ or Python for more complex apps, but Neutralinojs is a great option if you’re trying to make something quickly and easily.

I think a lot of programs are turning to web apps, e.g. Microsoft Teams or Discord, and I think Neutralinojs is the best option right now if you don’t want to include a whole browser in you app.

To include your own code that interacts with the computer you have to use the Extensions API. I think this is fine, but having to handle the cross-compilation for whatever language you use is a bit annoying, especially if you need to compile on each platform separately.

Here is the final code on GitHub!

Share:
Back to Blog

Related Posts

View All Posts »

Sun Tracker

Website that displays the current position of the sun in a variety of countries.