Three ways to package your Electron apps as snaps

by Igor Ljubuncic on 25 February 2022

Software comes in many shapes and forms. One of the popular cross-platform, cross-architecture frameworks for building and distributing applications in Electron, which combines the Chromium rendering engine and the Node.js runtime. This makes Electron-based applications relatively easy to create.

If you want to deploy Electron apps in Linux, you can also use snaps as your delivery mechanism. This allows developers to package and ship apps to end users without worrying about the necessary tooling being available on client machines. If an operating system supports snaps, they will run. The only question is, how do Electron apps and snaps work together?

Electron Builder

Building snaps with Electron Builder is relatively easy. The framework includes the top-level snap key, with several options that the developers can set. These include snapcraft-supported declarations like confinement, environment variables, build and stage packages, plugs, slots, layouts, compression, and more. By and large, you should be able to build and package snaps with Electron Builder without too many problems.

As outlined in the Snapcraft documentation, the basic process behind Electron Builder targeting snaps is to add a script (named dist in the example), which will then build the application as a snap.

 "scripts": {
    "start": "electron .",
    "dist": "electron-builder --linux snap"
  },

Additional declarations and configurations can be added to the package.json file in the Electron app project directory. However, if you require further charges that are not covered by the snap key, you will need a slightly different approach.

Electron Packager

If you feel Electron Builder may be somewhat limited in configurability, you may want to try Electron Packager. In essence, this a command line tool and Node.js library that bundles Electron-based application source code with a renamed Electron executable and supporting files into folders ready for distribution.

Where this gets really interesting is when you use Electron Packager as part of the snap building process. In a way, the approach here is the opposite of what we’ve seen earlier. Instead of using Electron Builder to produce snaps as its artifact, we will embed Electron Packager inside the snaps.

This approach gives more flexibility into what components and overrides get included in the snaps, and you have full control of the snapcraft.yaml as well as all the available, supported keywords.

The basic idea, as outlined in this sample snapcraft.yaml file, is to use the Snapcraft nil plugin, point to the relevant Electron-based app source, and then use electron-packager to build the application in the override-build step:

parts:
  electron-app:
    plugin: nil
    source: some source somewhere
    override-build: |
      npm install electron electron-packager
      npx electron-packager . --overwrite --platform=linux --output=release-build --prune=true
      cp -rv electron-app* $SNAPCRAFT_PART_INSTALL/electron-app
  build-snaps:
    - node/14/stable
  build-packages:
    - unzip
  stage-packages:
    - libnss3
    - libnspr4

For this step to work correctly, you will need a number of build and runtime dependencies, which will differ from project to project. In the example above, we use the node snap, which contains the npm utility, the unzip tool to open the downloaded archives, as well as several runtime dependencies.

The rest of the snapcraft.yaml will include the other necessary declarations, including the app itself, any environment variables it may need, interfaces, and possibly other stage packages.

Build, package yourself

A third approach, very similar to Electron Packager is to build an app for Linux and place it in a target directory. Then, you can ingest the built artifact into a snap, and provide the additional changes (like interfaces or stage packages) to allow the software to run. This method is outlined in the ubports-installer snapcraft.yaml. However, if you are proficient enough building Electron apps and snaps, the actual implementation is entirely up to you.

Summary

Electron apps bring a fair deal of portability and flexibility to the Linux desktop space. With snaps, you can further expand on these capabilities. However, adding abstraction layers can sometimes introduce some complexity. Hopefully, with the use of Electron Builder, Electron Packages and some manual tricks outlined in this article, you can combine the best of both worlds, and create robust, high-quality apps for Linux users.

 If you have any suggestions or new ideas on how to snap Electron apps, we would love to hear from you. Please join the forum and let us know what you think.

Photo by FLY:D on Unsplash.

Newsletter Signup

Related posts

Snapcraft 8.0 and the respectable end of core18

‘E’s not pinin’! ‘E’s passed on! This base is no more! He has ceased to be! ‘E’s expired and gone to meet ‘is maker! ‘E’s a stiff! Bereft of life, ‘e rests in peace! If you hadn’t nailed ‘im to the perch ‘e’d be pushing up the daisies! ‘Is software processes are now ‘istory! ‘E’s […]

Craft team welcomes you to another episode of its adventures

Welcome to the second article in the Craft team saga. Previously, on Craft Team, we gave you a brief introduction into the team’s function, we announced our desire to share the ins and outs of our day-to-day work with the community, and gave you an overview of roughly two weeks of coding and fun. Today, […]

The long ARM of KDE

With over 100 applications available in the Snap Store, KDE is by far the biggest publisher of snaps around. What unifies this impressive portfolio is the fact that all of these snaps are made for the x86 platform. Not anymore. Now, don’t panic! The x86 snaps are not going anywhere. But ARM-supported KDE snaps are […]