3 Steps to Packaging NodeJS Apps as Snaps

Alperen Bayramoğlu
3 min readJun 25, 2023

--

There are several options for packaging NodeJS applications like debian packages, docker images, standalone executables like nexe, and many others.

If our NodeJS application will run only on Linux-based operation systems for example Debian, Fedora, Ubuntu, etc. we can also package our NodeJS application as snap and publish it to the snapstore.

For the repo: Github

Photo by Gabriel Heinzer on Unsplash

Snapcraft is a packaging and deployment system that is developed by canonical for the systems which use Linux kernel and systemd init system.

1. Creating the Project and the Git Repository

git init
npm init -y

Create the Entrypoint `main.js`

#!/usr/bin/env node

function helloSnap() {
console.log("This is my first NodeJS snap application.");
}

helloSnap();

Update the `package.json`

... 
"bin": {
"hello-snap": "main.js"
},
"main": "main.js",
...

2. Creating the Snap Definition File

Snaps are defined in the `snap/snapcraft.yaml` file which is relative to the project root directory.

---
name: hello-snap
version: git
summary: My first package to snapstore.
description: |
Run with:-
$ hello-snap

confinement: strict
base: core20

apps:
hello-snap:
command: bin/hello-snap

parts:
hello-snap:
plugin: npm
npm-node-version: 14.16.1
source: .

Explanation of the Definition

`metadata` defines the meta-information about the package for the snapstore.

name: hello-snap # Must be unique in snap store lower-case alphanumeric characters and hyphens
version: git # Current git commit can be used as version string
summary: My first package to snapstore. # maximum 79 characters
description: |
Run with:-
$ hello-snap

`base` specifies the base snap for the use which is Ubuntu 20.04 in our example.

base: core20

See also: Base snaps

`confinement` specifies the confinement level of application:

confinement: strict

Snaps are containerized for better security. `confinement` defines the authorities of the application:

  • strict — No access to the application excluding plug interfaces. The application cannot access the system resources like network, storage, and processes if explicitly not requested using interfaces.
  • classic — The application can use system resources like any other application in the system.
  • devmode — No restriction. If the devmode is specified the application cannot be released to the stable channel.

See also: Snap confinement

`apps` keyword defines commands and services that our application exposes. `command` is the full path to our binary. `command` path is relative to the snap content:

apps:
hello-snap:
command: bin/hello-snap

`parts` specifies sources that are required to assemble our application:

parts:
hello-snap:
plugin: npm
npm-node-version: 14.16.1
source: .

With the `npm` plugin the dependencies of our application are automatically installed. `npm-node-version` selects the NodeJS version to bundle with our application.

See also: Snapcraft NPM Plugin

3. Building the Snap

git add . 
git commit -am "initial commit"
snapcraft

Note: Since we are using `git` as the version in the metadata, the project should be a git repository, and at least one commit is required to create a version.

There should be a`hello-snap_*.snap` file after the build in the root directory if the build succeeds.

Installing the Snap

sudo snap install hello-snap_*.snap --dangerous

We are defining the `--dangerous` parameter because our snap is not signed from the snapstore.

Removing the Snap

sudo snap remove hello-snap

Clearing the Build Environment

snapcraft clean

Publish our Application to the Snapstore

Login to the Snapstore

snapcraft login

Reserve name from the Snapstore

snapcraft register hello-snap

Upload our Snap

snapcraft upload --release=edge hello-snap_*.snap

We are selecting the edge channel for the release. We can also select the stable channel with --release=stable . For more information about releases: Release Management

Thanks for reading…

For the repository: Github

--

--

No responses yet