Package any app for every Linux desktop, server, cloud or device, and deliver updates directly.

or Auto-build and publish from your GitHub repos

Quick to install

Snaps are quick to install, easy to create, safe to run, and they update automatically and transactionally so your app is always fresh and never broken.

Install snapd ›

Work anywhere

Snaps aim to work on any distribution or device, from IoT devices to servers, desktops to mobile devices.

Build snapd from source

GitHub and beyond

The public collection of snaps includes the best of GitHub and beyond, so you have the whole world of Linux at your fingertips.

Build a snap from GitHub

How do snaps work?

A snap is a fancy zip file containing an application together with its dependencies, and a description of how it should safely run on your system, especially the different ways it should talk to other software.

Snaps are designed to be secure, sandboxed, containerised applications isolated from the underlying system and from other applications. Snaps allow the safe installation of apps from any vendor on mission critical devices and desktops.

Try this: (you may need to install snapd)

$ sudo snap install hello-world

Now you have installed a snap. You can take a look inside the snap, since it is a new directory on your system:

$ cd /snap/hello-world/current/

$ tree
├── bin                 ← this directory structure is just for convenience
│   ├── echo              there is no hardcoded structure requirement other
│   ├── env               than meta/snap.yaml
│   ├── evil
│   ├── sh
│   ├── showdev
│   └── usehw
└── meta                ← your snap must have this directory
    ├── icon.png
    └── snap.yaml       ← this is the required metadata

So to create a snap, just put all the files you need into a directory, use whatever subdirectory structure you want. That directory will be compressed into a squashfs — a zipped directory — which will be mounted at /snap/<name>/current when the snap is installed. Your snap apps will know where they are mounted because that is provided as the $SNAP environment variable when they are run.

The only requirement of a snap structure is that it contains a file called meta/snap.yaml, which describes security requirements and how the snap should integrate with other parts of the system. Let’s take a look at that snap.yaml for the hello-world snap:

$ cat meta/snap.yaml
name: hello-world
version: 6.1
architectures: [ all ]
summary: "The 'hello-world' of snaps"
description: |
    This is a simple snap example that includes a few interesting binaries
    to demonstrate snaps and their confinement.
    * hello-world.env  - dump the env of commands run inside app sandbox
    * hello-world.evil - show how snappy sandboxes binaries
    *   - enter interactive shell that runs in app sandbox
    * hello-world      - simply output text
    command: bin/env
    command: bin/evil
    command: bin/sh
    command: bin/echo

The initial metadata describes the snap. The version is purely for humans; the snap system won’t ever treat it as special or try to compare versions between snaps.

Next is a list of “apps” provided by this snap. Each app is explicitly named (“env”, “evil”, ‘sh”, and “hello-world”) and each gets a distinctive command, which is path relative to $SNAP. The name of the app doesn’t have to match the command.

The special app here is “hello-world”, because it has the same name as the snap itself. This makes it the default app in the snap, so you can run it just by typing “hello-world” after the snap is installed. The others need to be namespaced, so “hello-world.evil” will execute the bin/evil command in the snap.

A snap can declare daemons to be started as well. This one just describes some apps.

  • intel
  • arm
  • power8

Snaps are read-only and have segregated data stores

Snaps are read-only for security. The aim is to prevent a hostile party from sneakily changing the software on your machine, so you cannot modify a snap that is installed on your system. This also means you can always check the signature on the snap, even long after you installed it, to make sure it is still exactly the software you intended. If you want to modify a snap, you can usually build your own version of it, especially if it is open source.

So where can a snap write data? Each snap gets its own set of writable directories which have specific properties. There are two directories which the snap can write to independent of the user. One of these is versioned: each time the snap is upgraded the data is saved and the new snap revision can upgrade its copy. The other common data directory is not versioned, and is used for big blobs of data that you don’t want to duplicate across revisions of the snap:

/var/snap/<name>/current/  ← $SNAP_DATA is the versioned snap data directory
/var/snap/<name>/common/   ← $SNAP_COMMON will not be versioned on upgrades

Typically, configuration is stored in one of these, along with system-wide data for the snap.

There are an equivalent two writable directories for each snap in the user’s home directory, which can be used to store snap data specific to that user:

~/snap/<name>/current/      ← $SNAP_USER_DATA that can be rolled back
~/snap/<name>/common/       ← $SNAP_USER_COMMON unversioned user-specific data

This way applications can be immutable for security reasons, while still offering a full and rich user experience. To learn more about the makeup of a snap please see the snap architecture article.

Snap integration with interfaces, plugs and slots

Snaps are safely confined in their separate sandboxes by sophisticated kernel security mechanisms. That means that snaps can’t peek at your data — other than the data you give them — if they are compromised or malicious. But what if you need your snap to talk to another snap? For example, what if your snap needs to talk to a database?

It can use “interfaces” — standard and well-defined ways to provide and consume services from one another. Snaps can offer “slots” to provide services, and declare “plugs” that connect to other snap slots to consume those services. Imagine two snaps A and B that need to talk to each other:

These two snaps can be connected because they have a plug and a slot with a matching interface.

The interfaces are declared in the snap.yaml metadata:

There are many interfaces defined that can be used by snap developers to describe the ways their snaps should be connected. A snap can be connected to the host system OS using plugs, too, which is how it can access shared user documents or other services like OpenGL.

Snaps can share files with other snaps from the same vendor, or with community-maintained shared snaps which act as libraries of common data or code, for example using the content-sharing interface. This reduces duplication while still ensuring rigorous security and update control.

When you install a snap, the system will automatically connect up the standard, safe plugs and slots. For example, your new game will automatically get access to the OpenGL libraries on your system because that’s considered normal behaviour for a game. But there may be other plugs and slots you can connect up by choice, and snaps will document those individually.

The architecture of a snappy system

So a snappy system has a collection of snaps, each of which is read-only, each of which has its own set of independent writable directories, and each of which can talk to other snaps and the host OS through a set of plugs and slots with matching interfaces.

The snap system will present all the snap apps under /snap/bin/, so with that on your $PATH you can easily run snap commands. It will also integrate all the snap daemons (services) with your init system so that they are automatically started and stopped as needed.

Using snaps — the snappy “hello world” tour

To install a snap, you’ll start by looking for available snaps. Anybody can publish a snap, but if you search the default Ubuntu store you will only see snaps that have been reviewed and judged to be of good quality, and which can be installed securely. We call these the ‘promoted’ snaps, and you can search them for a matching name:

$ snap find hello
Name         Version  Developer  Notes  Summary
hello        2.10     canonical  -      GNU Hello, the "hello world" snap
hello-huge   1.0      noise      -      A really big snap
hello-world  6.1      canonical  -      Hello world example

In the future, you will be able to refine snap find queries with more parameters.

These examples use the Ubuntu store; your snap implementation might be different. Other stores are available, and it’s easy to create your own. There is an open-source simple snap store implementation to get you started making your own store.

We’ll start by installing GNU Hello, from the Free Software Foundation:

$ sudo snap install hello

Just like any other app, we can then launch the snap from the command line, or from the desktop if it has a launcher:

$ hello
Hello, world!

See the snaps installed on your system with “snap list”, which will also tell you the software version, the unique revision, the developer of the installed snap, and any extra information such as whether the snap is in developer mode or not:

$ snap list
Name     Version   Rev     Developer     Notes
hello    2.10      26      canonical     -
core     16.04-55  109     canonical     -
snapweb  0.17      21      canonical     -

Always fresh – update fast and reliably

Snaps are updated automatically in the background every day. You can manually get the latest version of all your snaps with “snap refresh”, which will bring you completely up to date for all snaps, unless you specify particular snaps to refresh.

$ sudo snap refresh hello
hello already up to date
$ sudo snap refresh
core 64.75 MB [=====================================>___]   12s
core updated

Revert if something goes wrong

It is simple to roll back to a previous version of an application for any reason.

$ snap list
 Name              Version               Rev  Developer  Notes
 hello-world       6.1                   26   canonical  -

 $ sudo snap revert hello-world
 Name             Version                Rev  Developer  Notes
 hello-world      6.0                    25   canonical  -

Stable, candidate, beta and edge channels

Developers can release stable, candidate, beta and edge versions of a snap, at the same time, to engage with a community who are willing to test upcoming changes. You decide how close to the leading edge you want to be.

By default, snaps are installed from the “stable” channel. By convention, developers use the “candidate” channel to provide a heads-up of a new stable revision, putting it in “candidate” a few days before “stable” so that people can test it out. The “beta” channel is for unfinished but interesting milestones, and the “edge” channel is conventionally used for regular or daily development builds that have passed some lightweight smoke-testing.

$ sudo snap refresh hello --channel=beta
hello (beta) 1.2 installed

Now, you can run the beta version of the snap:

$ hello
Hello, snap padawan!

You can also install a snap from the “beta” channel directly:

$ sudo snap install hello --beta
Hello (beta) 1.2 installed

Get crafting!

Snaps have a very simple internal structure — you can easily craft them by hand.

But if your code is on GitHub, the easiest way to build a snap is with our auto-build service. Every commit is auto-built, and every successful build is released to the “edge” channel.

Otherwise, you can use Snapcraft, which allows building from source and from existing packages. Snapcraft also handles releasing your snaps to the world.

Read how to create a snap, join the snap-crafting community on our forum or ask questions real-time on Rocket Chat.

Learn more

Want to know more about snaps, snapd, Snapcraft and Ubuntu Core?


Interested in helping build Snapcraft and expand its reach?