Open-source project
crystal-lang/shards avatar
crystal-lang/shards

Shards: the Crystal dependency manager behind every shard.yml

Dependency manager for the Crystal language

796 stars113 forksCrystalApache-2.0

At a glance

What is it?
crystal-lang/shards resolves and installs Crystal dependencies from a shard.yml manifest, locking versions into shard.lock for reproducible installs. The tooling is small and well specified, though the README and the Makefile disagree on the default install prefix.
Who is it for?
Crystal developers who want version constraints, a lockfile and reproducible installs should use Shards, since the manifest format is documented in a SPEC file and the workflow is three commands. Anyone who only needs one vendored library, or who works in a distribution without a Crystal package, will find the manual approach simpler.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Crystal, according to GitHub's language statistics.

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

Editorial analysis

Shard.yml is the manifest, and the SPEC is the contract

Shards is the dependency manager for the Crystal language. The README states that Crystal applications and libraries are expected to have a `shard.yml` file at their root, and it shows the shape of that file:

yaml
name: shards
version: 0.1.0

dependencies:
  openssl:
    github: datanoise/openssl.cr
    branch: master

development_dependencies:
  minitest:
    git: https://github.com/ysbaddaden/minitest.cr.git
    version: ~> 0.3.1

license: MIT

Two dependency sources appear there: a GitHub shorthand with a `branch` key, and a full `git` URL with a `version` constraint. Development-only dependencies sit in their own section, so a production install can differ from a development one.

The authoritative description of the format is not the README but a separate specification. The README points to the SPEC at `docs/shard.yml.adoc` for details, and a `SPEC.md` file sits at the top level of the repository. That separation matters when you need to know which keys are valid, since the example above covers only a fraction of what the format allows.

Version tags need a v prefix and a semver-like shape

Dependency resolution depends on how upstream repositories tag their releases, and the README sets out the convention plainly. When libraries are installed from Git repositories, the repository is expected to have version tags following a semver-like format, prefixed with a `v`.

The examples given are `v1.2.3`, `v2.0.0-rc1` and `v2017.04.1`. That last one shows the format tolerates calendar-style versions, which is why the rule is described as semver-like rather than strict semver. Pre-release identifiers such as `rc1` are part of the accepted tag shape.

The practical consequence for a library author is direct: if your tags do not carry the `v` prefix, a version constraint like `~> 0.3.1` in a consumer's `shard.yml` has nothing to match. Tagging conventions are therefore not a cosmetic detail, they are part of the dependency interface. The README does not document how Shards behaves when a repository has no matching tag at all, so that case has to be settled by reading the specification or by experiment.

shards init, shards install, and the shard.lock you commit

The everyday workflow is short. The README says you can type `shards init` to have an example `shard.yml` file created for your project, and `shards install` installs your dependencies, locking them into a `shard.lock` file.

sh
shards init
shards install

The locking step is the part that carries the weight. The README instructs you to check both `shard.yml` and `shard.lock` into version control, so that a later `shards install` always installs the locked versions, which the README calls reproducible installations across computers.

That is a two-file contract with your colleagues: the manifest states what you want, the lockfile states what you got. Reviewers who see a changed `shard.lock` know a transitive dependency moved. The README also mentions `shards --help` for the remaining commands and their options, which is where you would look for anything beyond install and init.

Building the binary with make bin/shards and the release flag

If your Crystal installation does not already ship Shards, the README points to a source tarball or a clone of the repository, then says to run `make release=1` and copy `bin/shards` into your `PATH`, for example `/usr/local/bin`.

The Makefile gives the finer-grained view. It defines `release`, `debug` and `static` switches, where `release=1` compiles in release mode with optimizations, `debug=1` adds symbolic debug info and `static=1` enables static linking, which the README notes only works with musl-libc. The default build target is simply `bin/shards`, and the recommended invocation is:

sh
make bin/shards

The Makefile also supports `make install`, `make docs`, `make test` and a `make build && sudo make install` combination, and it carries a `VERSION` file whose contents feed the version string baked into the binary, along with the current git commit hash. That build metadata means the binary can identify the exact source it came from, which matters when you are chasing a behaviour difference between two installations of the same tool.

libyaml and asciidoctor sit alongside Crystal as build requirements

The README is explicit that its requirements apply to compiling Shards rather than to using it. Crystal is the first, with installation instructions at crystal-lang.org/install. The second is libyaml, which is the YAML parser behind the `shard.yml` handling, and the third is asciidoctor, needed for building manpages.

The libyaml instructions are per platform. On Debian and Ubuntu Linux the package is `libyaml-dev`. On macOS it is installed with `brew install libyaml`, after which the library path needs adjusting:

sh
brew install libyaml
export LIBRARY_PATH="/usr/local/lib:$LIBRARY_PATH"

The README asks you to adjust that path for your own Homebrew installation, which is a reminder that the documented value is not universal.

For day-to-day development the README strongly recommends `make`, since the Makefile holds the recipes for compiling and testing. It also lists the individual suites: `make test_unit` runs the unit tests in `./spec/unit` and `make test_integration` runs the integration tests in `./spec/integration` against `bin/shards`. A devenv.sh configuration with a `devenv.lock` and `devenv.nix` is included for people who would rather have the toolchain assembled for them.

The install prefix differs between the README and the Makefile

Here is a concrete documentation conflict worth knowing about before you install. The README says the install target path can be adjusted with `PREFIX` and gives the default as `PREFIX=/usr/bin`. The Makefile declares `PREFIX ?= /usr/local`, and derives the binary directory from it as `BINDIR ?= $(PREFIX)/bin`.

So the two documents point at different locations, and the one that actually takes effect is the Makefile, unless you pass `PREFIX` yourself. Running `make install` on a default setup therefore places the binary under /usr/local/bin, while a reader of the README alone would look in /usr/bin.

The Makefile is also more adjustable than the prose suggests. `DESTDIR` is available for staged installs, `MANDIR ?= $(PREFIX)/share/man` controls where manpages land, and `INSTALL ?= /usr/bin/install` selects the install program. The README also mentions a `Makefile.win` in the repository for native Windows builds, while the main Makefile carries MSYS2 support.

Vendored solver code, fossil tests and the platform gaps

The repository layout tells you more than the README does. The Makefile compiles `src/*.cr` together with a separate set of sources found under `lib/molinillo`, so the dependency solver is vendored into the tree rather than pulled in as a dependency. A `shard.lock` at the root of the Shards project itself shows that the tool is dogfooded.

The test setup has platform-shaped holes. The Makefile exposes `skip_fossil`, `skip_git` and `skip_hg` switches, and the comment header shows `make test skip_fossil=1` for running the suite without the fossil tests. Fossil, git and Mercurial are separate version control systems, so the integration suite covers installs from repositories hosted on each of them. On a machine with only git available, some of those tests cannot run, and the switches exist to skip them.

There is also a Makefile.win, a `man/` directory for the manpage sources and a `docs/` directory that holds the shard.yml specification, so the documentation is built rather than merely stored as prose.

Apache-2.0, REUSE bookkeeping and a slow release cadence

Shards is licensed under the Apache License, Version 2.0, with the terms in the `LICENSE` file. The repository also carries a `LICENSES/` directory and a `REUSE.toml` file, which is the REUSE specification mechanism for recording the licence of individual files. That is worth knowing if you vendor Shards into a larger distribution, because you will need to preserve the licence notices alongside any files you redistribute.

The repository is not archived and the last push was on 2026-10-21. Releases are less frequent than that push date suggests: the recorded versions are v0.20.0 on 2025-12-19, v0.19.1 on 2025-01-23 and v0.19.0 on 2024-12-18. A `CHANGELOG.md` at the root records what changed between them.

For a tool shipped alongside Crystal itself, the practical upgrade path is often the language package rather than the Shards release. The README says Shards is usually distributed with Crystal, through Homebrew and Debian packages among others, and that a `shards` package may exist for your system, so upgrading Crystal usually means upgrading Shards with it.

Editorial conclusion

Crystal developers who want version constraints, a lockfile and reproducible installs should use Shards, since the manifest format is documented in a SPEC file and the workflow is three commands. Anyone who only needs one vendored library, or who works in a distribution without a Crystal package, will find the manual approach simpler. Before adopting, check the SPEC at docs/shard.yml.adoc against the constraints your team actually needs, confirm whether your Crystal installation already ships a shards binary, and note that the two documented install prefixes disagree, so you should decide whether the binary lands in /usr/local/bin or /usr/bin before running make install.

Frequently asked questions

What is Shards and what does it do for Crystal projects?

Shards is the dependency manager for the Crystal language. It reads a shard.yml manifest at the project root, installs the dependencies declared there, and locks the resolved versions into a shard.lock file.

How do I install Shards?

The README says Shards is usually distributed with Crystal itself, for example through Homebrew and Debian packages, and that a shards package may be available for your system. Otherwise you can download a source tarball or clone the repository, run `make release=1` and copy `bin/shards` into your PATH.

What is the difference between shard.yml and shard.lock?

shard.yml declares your dependencies and their version constraints, while shard.lock records the versions that were actually installed. The README tells you to commit both to version control so later installs are reproducible across computers.

What tag format do my dependencies need to use?

Repositories installed from Git are expected to have version tags following a semver-like format prefixed with a `v`, for example `v1.2.3`, `v2.0.0-rc1` or `v2017.04.1`.

How do I build and test Shards from source?

Run `make bin/shards` to build the binary, with `release=1` for an optimized build, `debug=1` for symbolic debug info and `static=1` for static linking, which only works with musl-libc. Run `make test` for the suites, with `make test_unit` and `make test_integration` for the individual parts.

Is the Shards repository still being worked on?

The repository is not archived and the last push was on 2026-10-21. The recorded releases are v0.20.0 on 2025-12-19, v0.19.1 on 2025-01-23 and v0.19.0 on 2024-12-18.

Official sources

  1. crystal-lang/shards on GitHub
  2. Issues
  3. License: Apache-2.0
  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/crystal-lang-shards.svg)](https://hysenlabs.com/projects/crystal-lang-shards)

Was this useful?