# Crystal packaging in Fedora

**URL:** <https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690>\
**Category:** Community\
**Created:** [February 4, 2026, 12:31am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690 "2026-02-04T00:31:52Z")\
**Posts on this page:** 16\
**Page:** 2

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 4, 2026, 3:43am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/21 "2026-09-04T03:43:38Z")

</div>

### Fedora Packaging Update (2026-09-03)

Quick progress update from today’s coordination with Fedora leadership:

1. **Fedora Packaging Committee (FPC) Review**:

2. **Official Guidelines PR Submitted** :

3. **Infrastructure & Wiki Updated** :

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 4, 2026, 3:46am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/22 "2026-09-04T03:46:08Z")

</div>

Yep, you’re right. Because Crystal shards are identified by Git repository URLs rather than a single global registry, two independent upstreams could indeed choose the same name in their `shard.yml`.

Here is how the Fedora packaging model handles this:

1. **Dist-Git Package Review & Namespace Disambiguation** :  
In Fedora, source package names must be globally unique. If two distinct upstreams collide on a generic name (e.g., both named `cache`), Fedora packaging policy handles this via author/organization disambiguation at review time (e.g., `crystal-author1-cache` vs `crystal-author2-cache`), similar to how Fedora handles Go packages with conflicting base names.

2. **Decoupled RPM Macros (`%crystal_install_lib -n`)**:  
Our RPM macros explicitly decouple the RPM package name from the on-disk shard directory. If a disambiguated package name is needed, `%crystal_install_lib -n <shard_name>` can install the files into the canonical directory name expected by dependent shards.

3. **`shard.lock` Symlink Resolution** :  
Because `%crystal_setup` inspects the project’s `shard.lock` during `%prep`, it maps the exact dependency name the project expects into local `./lib/<name>`, pointing to the versioned system shard path in `%{_datadir}/crystal/shards/`.

In practice, this makes conflicts rare and manageable whenever two popular shards share a name.

---

<div class="post-metadata">

**Author:** ![crimson-knight](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/crimson-knight/32/1643_2.png) [@crimson-knight](https://forum.crystal-lang.org/u/crimson-knight)\
**Post date:** [September 5, 2026, 3:13pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/23 "2026-09-05T15:13:55Z")

</div>

I’ve been experimenting with how to do this. Mostly because I have so many projects running locally that the amount of copies of my dependencies is becoming problematic (I ran out of disk space!)

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 6, 2026, 1:43am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/24 "2026-09-06T01:43:30Z")

</div>

Hey everyone,

Quick update on the packaging effort, and a question for the core team on how you see shard discovery evolving.

Following up on the scheme I outlined earlier (installing shards to `/usr/share/crystal/shards/<name>-<version>` and symlinking them into `./lib`), it has solved my offline build requirements completely. Compiler, shards, ameba, flaw, db drivers, and kemal all build cleanly in offline chroots.

Because shards are source-only and RPM packages cannot have file collisions, we install into versioned directories (`kemal-1.13.0`, `kemal-1.12.0`) following the compat package pattern (like LLVM). The primary package drops an unversioned symlink (`kemal -> kemal-1.13.0`), while compat packages omit it so multiple versions can coexist on disk.

This works cleanly for isolated RPM builds, but I’m hitting friction with developer workflows on a live system:

1. **Standalone scripts** : If someone writes a quick script like `app.cr` with `require "kemal"` without a `shard.yml` or a `lib/` folder, `CRYSTAL_PATH` looks for `kemal`. That resolves via the primary package’s unversioned symlink, but only for whichever version is primary. Has there ever been any thought on the compiler natively understanding versioned directories in `CRYSTAL_PATH`?

2. **Dangling symlinks on patch updates** : When a developer links a local project against system shards (e.g. `lib/kemal -> /usr/share/crystal/shards/kemal-1.13.0`) and runs a routine `dnf upgrade`, the package updates to `1.13.1`. RPM removes the `1.13.0` directory and replaces it with `1.13.1`, which breaks the symlink in `./lib`.

Here is what I tried to address this, and why it didn’t work:

- **Hybrid SONAME approach** : Since we can’t use ELF SONAMEs, I tried emulating them with minor-version symlinks (`kemal-1.13 -> kemal-1.13.1`) so patch updates wouldn’t break `./lib`. But `shard.lock` pins exact patch versions (`1.13.0`), so linking against minor versions bypasses the lockfile’s pinned version.
- **`shard.override.yml`** : I tried generating an override file so `shards install` could manage the links. But running `shards install` mutates `shard.lock` with local absolute paths and `# Overridden` comments, which dirties git and breaks CI for anyone else pulling the repo. Plus, if any transitive dependency is missing from the overrides, `shards install` tries to hit the network, which fails in offline/air-gapped environments.

Where I landed for now is a small helper tool called `shards-link`. It reads `shard.lock` (or falls back to `shard.yml`), matches the version against `/usr/share/crystal/shards/`, and symlinks the dependencies into `./lib` without touching `shard.lock` at all. If a system update removes an old patch version, running `shards-link` again relinks to the newest matching installed version.

It works, but it feels like a downstream hack for something that might be better addressed upstream.

Has there been any discussion around `shards` having an offline or shared cache mechanism (similar to Cargo or Go), or a native way to consume system-installed shards without dirtying `shard.lock`?

I’d love to hear your thoughts before I cement too many conventions on the Fedora side.

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [September 6, 2026, 8:29am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/25 "2026-09-06T08:29:43Z")

</div>

My first thought on this is that `shards` is a dependency manager, `rpm` a package manager. Those are different concerns. Each tool does its job and does it well. But mixing concerns can be quite a challenge.

Packaging shards as RPM source packages works well as dependencies for other RPM packages.

But for non-packaged uses, there’s considerable friction. And I don’t think there’s a clean way to avoid all of that. We can maybe alleviate it a bit, though.

> [@renich](#):
>
> 1. **Standalone scripts** : If someone writes a quick script like `app.cr` with `require "kemal"` without a `shard.yml` or a `lib/` folder, `CRYSTAL_PATH` looks for `kemal`. That resolves via the primary package’s unversioned symlink, but only for whichever version is primary. Has there ever been any thought on the compiler natively understanding versioned directories in `CRYSTAL_PATH`?

I guess I’m lacking understanding of the RPM ecosystem: What denotes a package as primary?  
Anyway, I’m wondering if it’s even a good idea to put all RPM-installed shard sources in the default `CRYSTAL_PATH`. What’s the point of it? It hides dependencies instead of making them explicit.

I suppose adding support for version suffixes in `require` could be discussed. But honestly, it feels kinda off. The compiler shouldn’t worry about dependencies.

A generic solution for standalone scripts could be embedded dependency declarations directly in the source file. I think @bcardiff floated this idea internally a while ago.  
Then the behaviour for standalone scripts would be the same as for a full repo with a `shard.yml`.

> [@renich](#):
>
> 1. **Dangling symlinks on patch updates** : When a developer links a local project against system shards (e.g. `lib/kemal -> /usr/share/crystal/shards/kemal-1.13.0`) and runs a routine `dnf upgrade`, the package updates to `1.13.1`. RPM removes the `1.13.0` directory and replaces it with `1.13.1`, which breaks the symlink in `./lib`.

IMO dependencies should always be explicit about versions. So if you want to use RPM to provide source dependencies for a local project, you should pin the exact version, just like shards would do: install `kemal-1.13.0`, not floating `kemal`. That ensures the symlink stays valid.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 6, 2026, 12:49pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/26 "2026-09-06T12:49:43Z")

</div>

Fair point on keeping the compiler lean, @straight-shoota. Looking at upstream’s default `CRYSTAL_PATH` (`/usr/share/crystal/src:lib`), `/usr/share/crystal/shards` was indeed our own distro-level injection to make quick scripts work, and I see how implicit resolution hides dependencies.

That said, the core issue here isn’t the compiler; it’s `shards`.

Right now, `shards` is strictly git-and-network-first. The only way to consume local source trees is via `path:` overrides, but running `shards install` with overrides rewrites `shard.lock` with local paths and `# Overridden` comments. That dirties git and breaks CI for anyone else pulling the repo.

In contrast, Cargo (Rust) and Go both use a shared local cache (`~/.cargo/registry/src`, `GOPATH/pkg/mod`). When they resolve a lockfile, they look in the local cache first. If the files are there, they build offline immediately without touching git or lockfiles.

If `shards` had a shared or system cache lookup path (e.g. `$SHARDS_PATH` or `/usr/share/crystal/shards`), we wouldn’t have this friction:

1. `shards install` could resolve locked dependencies offline during package builds and in air-gapped environments without mutating `shard.lock`.
2. Developers with multiple local projects wouldn’t have to duplicate dependencies on disk (which was actually brought up in this thread earlier by @crimson-knight).

As for standalone scripts: @bcardiff’s idea of embedded dependency metadata in the source file header (similar to PEP 723 in Python or Cargo-script in Rust) makes total sense. That would give single-file scripts explicit, reproducible version pins without turning the compiler into a package manager or forcing people to spin up a full git repo just for a 20-line tool.

For now, `shards-link` is our stopgap in Fedora to wire `./lib` against system-installed shards without touching `shard.lock`. If upstream ever considers a shared cache or script manifest in `shards`, I’d be happy to share our findings and test cases.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 6, 2026, 3:09pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/27 "2026-09-06T15:09:04Z")

</div>

Hello everyone,

We have major, game-changing news regarding the Fedora packaging effort for Crystal:

### 1. Dual-Track Packaging Model Formally Adopted

The biggest historical hurdle for compiled, lockfile-centric languages (like Go, Rust, and Crystal) in traditional Linux distributions has always been the tension between distribution unbundling orthodoxy and upstream dependency pinning:

- **Traditional unbundling purism** required packaging every micro-dependency as an independent RPM. For complex applications, this created an overwhelming barrier to entry (reviewing and maintaining 40-60 separate packages in dist-git just to ship one CLI tool), and led to severe maintainer burnout whenever minor SemVer bumps collided across applications.
- **Uncontrolled bundling** was unacceptable for distribution security, CVE tracking, and offline reproducibility.

Following recent precedent approved by the Fedora Engineering Steering Committee (FESCo) for Go, we have updated our official Fedora Packaging Guidelines draft ([PR #1568](https://forge.fedoraproject.org/packaging/guidelines/pulls/1568)) to formally establish the **Dual-Track Packaging Model** for Crystal:

1. **Track 1: Shared Shard Libraries (Unbundled)**
  - Core libraries and shared building blocks are packaged as unbundled source RPMs installed into versioned paths: `%{_datadir}/crystal/shards/<name>-<version>`.
  - Supports parallel minor-version coexistence without RPM filesystem collisions.
  - Designed for local development and system administration scripts (`crystal run script.cr` with `require "kemal"`) executing out of the box via `CRYSTAL_PATH` without needing local `lib/` or Git access.

2. **Track 2: Vendored Dependencies for Leaf Applications**
  - For standalone end-user applications, CLIs, and daemons where unbundling transitive shards is disproportionately burdensome, maintainers are permitted to ship an offline companion vendor archive (`Source1: %{name}-%{version}-vendor.tar.xz`).
  - The archive is unpacked offline during `%prep`.
  - Security and auditability are preserved via mandatory virtual provides: `Provides: bundled(crystal-shard(<name>)) = <version>` for every vendored shard, alongside aggregate SPDX license expressions in the `License:` field.
  - Applications compile into fully hardened, LTO-optimized, debuginfo-complete native ELF binaries in a single spec file.

This gives the Fedora Crystal ecosystem the best of both worlds: unbundled modularity for shared libraries, and a friction-free on-ramp for packaging applications like Kemal apps, CLI tools, and background services.

* * *

### 2. Full Ecosystem Deployed & Verified in Copr (12/12 Succeeded)

To validate this architecture end-to-end under genuine distribution build conditions, we ran a complete mass build and deployment of the Crystal stack in Fedora Rawhide Copr ([`renich/crystal`](https://copr.fedorainfracloud.org/coprs/renich/crystal/)).

All 12 packages across all four architectural tiers succeeded on both **`fedora-rawhide-x86_64`** and **`fedora-rawhide-aarch64`** with zero chroot skips and zero test failures:

- **Foundation** : `crystal-lang` (1.21.0 compiler), `shards` (0.20.0), `crystal-rpm-macros`
- **Tier 1 (Core Shards)**: `crystal-db` (0.14.0), `crystal-radix` (0.4.1), `crystal-backtracer` (1.2.4)
- **Tier 2 (Database Drivers & Middleware)**: `crystal-sqlite3` (0.23.0), `crystal-pg` (0.30.0), `crystal-mysql` (0.17.0), `crystal-exception_page` (0.5.0)
- **Tier 3 (Core Web Framework)**: `crystal-kemal` (1.13.0)
- **Tier 4 (Ecosystem Extensions & Apps)**: `crystal-kemal-session` (1.6.0), `crystal-kemal-basic-auth` (2.0.0), `crystal-spec-kemal` (1.3.0), and the multi-core load testing binary `cryload` (6.0.0)

**Highlights from the build runs** :

- **100% Hermetic & Offline** : Every single shard library resolved its dependencies strictly through `/usr/share/crystal/shards/<name>` with zero network calls during build time.
- **Upstream Test Suites Pass** : The entire test suite (`crystal spec`) for Kemal, spec-kemal, and the database drivers executed cleanly inside isolated Mock roots against system-installed shards.
- **Native Hardening** : Binaries built with full Fedora distribution flags (`-specs=/usr/lib/rpm/redhat/redhat-hardened-ld`, branch protection on `aarch64`, full debuginfo/debugsource generation) cleanly passed through the LLVM toolchain.

* * *

### 3. Links & Get Involved

- **Fedora Packaging Guidelines PR** : [packaging/guidelines PR #1568](https://forge.fedoraproject.org/packaging/guidelines/pulls/1568)
- **Fedora Copr Repository** : [`copr.fedorainfracloud.org/coprs/renich/crystal/`](https://copr.fedorainfracloud.org/coprs/renich/crystal/)
- **Fedora Crystal SIG Wiki** : [fedoraproject.org/wiki/SIGs/Crystal](https://fedoraproject.org/wiki/SIGs/Crystal)
- **Packaging Sources** : [codeberg.org/fedora-crystal](https://codeberg.org/fedora-crystal)
- **Matrix Channel** : `#crystal:fedoraproject.org`

The road is wide open for packaging Crystal applications in Fedora! Feedback, testing, and new packagers are warmly welcome.

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [September 6, 2026, 3:19pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/28 "2026-09-06T15:19:03Z")

</div>

> [@renich](#):
>
> Right now, `shards` is strictly git-and-network-first. The only way to consume local source trees is via `path:` overrides, but running `shards install` with overrides rewrites `shard.lock` with local paths and `# Overridden` comments. That dirties git and breaks CI for anyone else pulling the repo.

Two corrections on that:

- Shards has a local repo cache (`$SHARDS_CACHE_PATH`). The `--local` flag instructs shards to use only that cache without fetching remote repositories (see [shards/docs/shards.adoc at master · crystal-lang/shards · GitHub](https://github.com/crystal-lang/shards/blob/master/docs/shards.adoc#general-options)). So offline installs should be possible.
- Local overrides can be defined in a separate file `shard.override.yml` (see [shards/docs/shards.adoc at master · crystal-lang/shards · GitHub](https://github.com/crystal-lang/shards/blob/master/docs/shards.adoc#files)). Dependencies defined there take precedence over any `shard.yml` in the dependency tree.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 6, 2026, 3:30pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/29 "2026-09-06T15:30:09Z")

</div>

Thanks, @straight-shoota. We tested both, but ran into two blockers for distro packaging:

1. **`$SHARDS_CACHE_PATH` expects Git repositories:** It resolves tags and commits from bare git objects. RPM packages install extracted source trees into `/usr/share/crystal/shards/<name>-<version>` without `.git` directories or VCS metadata, so `shards` can’t consume them as a cache.

2. **`shard.override.yml` mutates `shard.lock`:** Running `shards install` with overrides rewrites `shard.lock` with local paths and `# Overridden` comments, which dirties git and breaks CI on other platforms. Running with `--frozen` rejects the overrides altogether. Also, path overrides still attempt to fetch un-overridden transitive dependencies over the network.

Directly symlinking from `/usr/share/crystal/shards/` into `./lib` sidesteps the solver entirely: it needs no Git objects, leaves `shard.lock` untouched, and works offline in air-gapped/chroot builds.

---

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [September 19, 2026, 9:43am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/30 "2026-09-19T09:43:47Z")

</div>

Wow, really cool!!

I never use fedora on my local laptop, before read this post, I thought this is a post about for fixing `def install crystal`.

After I read, I know this is create a complete first-class Crystal ecosystem in fedora, this is really a wonderful contribution to Crystal.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [September 19, 2026, 1:33pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/31 "2026-09-19T13:33:47Z")

</div>

Thank you for your kind comments. Indeed, this is about making crystal a first class citizen in fedora.

I think Crystal has huge potential. And I know that it will be very useful in air -ap environments.

If developers take heart to it, which I think it’s very easy, Crystal will thrive in this ecosystem.

---

<div class="post-metadata">

**Author:** ![alanmsant2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/alanmsant2/32/2317_2.png) [@alanmsant2](https://forum.crystal-lang.org/u/alanmsant2)\
**Post date:** [September 19, 2026, 4:31pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/32 "2026-09-19T16:31:28Z")

</div>

I’ve been using Fedora with KDE Plasma (Qt) on my personal laptop for a few years now, and I’m very happy with the system’s stability.  
I made this choice after trying various Debian-based distros, which would eventually run into issues and instability, despite having a larger ecosystem.

I am delighted to hear about this valuable contribution to both the Fedora distro and Crystal.

Congratulations on the excellent work.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [October 1, 2026, 1:47pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/33 "2026-10-01T13:47:27Z")

</div>

It’s almost official! We’re part of Fedora 46! \0/

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/crystal_lang/original/2X/7/717a5249080bd4e8d95a28fd834651165e9eb1b6.png)

Here’s the ticket: [Making sure you're not a bot!](https://forge.fedoraproject.org/fesco/tickets/issues/3690)

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [October 14, 2026, 11:54pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/34 "2026-10-14T23:54:12Z")

</div>

> **[Change: Crystal Language](https://forge.fedoraproject.org/fesco/tickets/issues/3690)**
>
> This proposal introduces official native support for the Crystal programming language compiler (source package crystal-lang, producing binary crystal), its dependency manager (shards), an automated spec generator (cr2rpm), and standard RPM packaging...

And we have many +1s!!

There is a pushback on vendroing by one of the members but they agree to allow it if things get complex. The good thing is that we have both pathways covered.

Not a single complaint or pushback on the language. I am very happy to say I think we’re almost there.

---

<div class="post-metadata">

**Author:** ![renich](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/renich/32/2137_2.png) [@renich](https://forum.crystal-lang.org/u/renich)\
**Post date:** [October 19, 2026, 10:57pm UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/35 "2026-10-19T22:57:34Z")

</div>

Approved! Fedora has approved Crystal as a feature for Fedora 46!

> **[Change: Crystal Language](https://forge.fedoraproject.org/fesco/tickets/issues/3690#issuecomment-1367378)**
>
> This proposal introduces official native support for the Crystal programming language compiler (source package crystal-lang, producing binary crystal), its dependency manager (shards), an automated spec generator (cr2rpm), and standard RPM packaging...

\0/

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/crystal_lang/original/2X/f/fff4c9bb09cca130bdcddafbf46146e1e5507de1.jpeg)

---

<div class="post-metadata">

**Author:** ![paulocoghi](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/paulocoghi/32/1429_2.png) [@paulocoghi](https://forum.crystal-lang.org/u/paulocoghi)\
**Post date:** [October 20, 2026, 9:16am UTC](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690/36 "2026-10-20T09:16:11Z")

</div>

What a journey! Congrats @renich! 👏 🎉

[Previous page](https://forum.crystal-lang.org/t/crystal-packaging-in-fedora/8690.md?page=1)
