CLI tool
canonical/snapcraft avatar
canonical/snapcraft

Snapcraft: one snapcraft.yaml from a Python package to a container with its libraries inside

Package, distribute, and update any app for Linux and IoT.

1,291 stars564 forksPythonGPL-3.0

At a glance

What is it?
Snapcraft is Canonical's command line build tool for the snap container format, packaging a program together with its libraries so one artefact runs across major Linux distributions and IoT devices. The configuration is a single snapcraft.yaml, and the tool itself is distributed as a classic snap with a container runtime as a prerequisite.
Who is it for?
Snapcraft suits a project that wants to ship one self contained artefact to several Linux distributions, or to an IoT device, and that is willing to accept the snap sandbox and the store's review process as the price. It is the wrong choice for a Python library that only needs to be published to a package index, since the packaging overhead buys nothing there, and a poor fit for a project that cannot use a container runtime on the build machine.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Snapcraft solves is dependency bundling, not distribution alone

The README frames Snapcraft as the command line build tool for packaging and distributing software and apps in the snap container format, and then names the two problems it solves: dependency management and architecture support. The mechanism for both is the same, bundling all of a software's libraries into the container itself, which is what lets a single package work across all major Linux distributions and IoT devices. That is the trade in one sentence. You give up the idea that the target system already has the right library versions, and in exchange you stop maintaining a matrix of builds per distribution. The audience is therefore a project with a portable binary or script, not a Python library that lives comfortably in a virtual environment, and not an application that only ever runs on one distro and one version.

snapcraft.yaml is the entire configuration surface

A snap's build configuration lives in a single project file called snapcraft.yaml, written in what the README calls a simple language, and the stated reason for that choice is to make the format easy to add to an existing code base. The whole build definition is one file that you create and then fill in with the project's build and runtime details. The repository layout supports the idea that this is a data-driven tool rather than a code-driven one: there is a schema/ directory at the top level, which holds the definition of the valid shape of the project file, and an extensions/ directory, which holds reusable extension definitions. The README also notes that the documentation covers the full process of building a project file, debugging snaps and resolving interfaces, and that interfaces are a first class concept here, because a snap's access to the host system is described by interface connections rather than by configuration you invent per application.

The four commands that cover a whole release cycle

The basic usage section is the clearest part of the README, and it is a four step cycle. From the root of any software project's code base, snapcraft init creates a minimal snapcraft.yaml for you. You then fill in the build and runtime details and run snapcraft pack to bundle the project into a snap. Registration comes next, with snapcraft register handling both public and private app stores including the Snap Store. Publishing is the last step, and snapcraft upload sends versions and revisions, including parallel releases, to the store. The separation between pack, register and upload is worth noticing, because it is what lets a team produce a snap artefact in CI and decide separately who may publish it and when. The documentation points at a tutorial called crafting your first snap for the learning path.

bash
snapcraft init
snapcraft pack
snapcraft register
snapcraft upload

Installing Snapcraft needs a container tool, and there are two routes

Snapcraft is available on all major Linux distributions, Windows and macOS, and the README describes two ways to get it. The first is that Snapcraft itself has first-class support as a snap, so on a snap-ready system you install it on the command line with the classic flag, which allows the tool unrestricted access to the host. The second is a traditional package on many popular Linux repositories. Either way, the README says complete installation needs an additional Linux container tool, and that is the dependency that trips people up, because a build host without a container runtime cannot run Snapcraft properly. The classic flag on the snap is worth a second look for the same reason, since a sandboxed build tool cannot drive a container runtime without extra plumbing.

bash
sudo snap install snapcraft --classic

The dependency tree shows the craft stack, not just a CLI wrapper

The pyproject.toml shows what Snapcraft actually is under the hood, and the answer is that it is the front end of a stack of craft libraries. The direct dependencies include craft-application with the remote extra, craft-archives, craft-cli, craft-grammar, craft-parts, craft-platforms, craft-providers and craft-store, along with click for the command line interface, craft-parts pinned to a compatible release with the ~= operator, and pydantic for data validation. The entry point is a single console script, snapcraft = 'snapcraft.application:main', and the version is dynamic, derived from version control rather than written into the file. Two details in the dependency list are the kind of thing that only shows up when you read the manifest. jsonschema is pinned to an exact version, and pygit2 is pinned to the 1.18 series with a comment explaining that pygit2 and libgit2 need matching versions and that 1.18 is the last minor release supporting Python 3.10, which is also the floor the project declares.

Extension definitions and a JSON schema are how the project file stays validated

Two directories in the repository carry most of the design decisions. The schema/ directory holds the definition of what a valid project file looks like, which pairs with the pydantic dependency in the manifest: the file you write is not parsed by ad hoc code, it is validated against a declared shape. The extensions/ directory holds reusable pieces that a project can pull in rather than reimplementing, and the presence of that directory reflects where the effort in a packaging tool actually goes, since the base format is small and the reuse across ecosystems is where the work accumulates. The repository also carries a spread.yaml, and the README shows a Spread tests badge, so the project tests the tool by running real snaps under real system conditions rather than only unit testing the code. The osv-scanner.toml at the top level is a further sign that dependency vulnerability scanning is part of the workflow.

Release cadence, licence and the test matrix built into the Makefile

The version numbers move quickly. The listed releases are 9.1.3 on 2026-09-24, 9.1.4 on 2026-10-08 and 9.2.0 on 2026-10-13, and the last push to the repository was on 2026-10-15, so a new minor version can arrive within days of a patch. The licence is GPL-3.0, with the copyright held by Canonical Ltd. for 2015 to 2025, which matters if you intend to modify Snapcraft itself, though building a snap with the tool does not place your own package under the same terms. The Makefile shows the engineering discipline behind the tool, with a format target that chains ruff, codespell, prettier, shfmt and pre-commit, and a lint target that runs code, docs, twine, uv lockfile and actions linters. It also reads the OS codename from /etc/os-release and adds a matching dependency group per Ubuntu release, so the test matrix follows the distributions the project supports rather than a single environment.

Editorial conclusion

Snapcraft suits a project that wants to ship one self contained artefact to several Linux distributions, or to an IoT device, and that is willing to accept the snap sandbox and the store's review process as the price. It is the wrong choice for a Python library that only needs to be published to a package index, since the packaging overhead buys nothing there, and a poor fit for a project that cannot use a container runtime on the build machine. Before adopting it, read the documentation on building a project file, debugging snaps and resolving interfaces, and check that a container tool is available on your build hosts, because the README states that a complete installation needs an additional Linux container tool alongside the Snapcraft snap.

Frequently asked questions

How do I package a project as a snap with Snapcraft?

Run snapcraft init from the root of your code base to create a minimal snapcraft.yaml, fill in the build and runtime details, then run snapcraft pack to bundle the project. Use snapcraft register to register it on a public or private app store, and snapcraft upload to publish versions and revisions.

How do I install Snapcraft itself?

On a snap-ready system you can install it from the command line with sudo snap install snapcraft --classic, and Snapcraft can also be installed as a traditional package on many popular Linux repositories. The README notes that a complete installation needs an additional Linux container tool.

What does a snap actually package?

The README says Snapcraft solves dependency management and architecture support by bundling all of a software's libraries into the container itself, so a single package can target all major Linux distributions and IoT devices. The build configuration is stored in a project file called snapcraft.yaml.

What are the extensions and schema directories in the Snapcraft repository?

The repository layout shows that the format is defined as data rather than code, with a schema/ directory holding the definition of the project file and an extensions/ directory holding reusable extension definitions. The manifest also depends on pydantic and jsonschema for validation.

What licence is Snapcraft released under?

Snapcraft is released under the GPL-3.0 license, with the copyright held by Canonical Ltd. for 2015 to 2025. The project also publishes on GitHub, the Snapcraft Forum and a Matrix channel, and issues are tracked on the GitHub repository.

Official sources

  1. canonical/snapcraft on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/canonical-snapcraft.svg)](https://hysenlabs.com/projects/canonical-snapcraft)

Was this useful?