# dracut: an initramfs that waits for devices instead of guessing them

> dracut is an event driven initramfs infrastructure that builds the early boot image by copying tools and files from the installed system and combining them with a module framework, relying on udev to create device nodes so the root filesystem can be mounted as soon as it appears. Its published tags stop in 2022 even though the branch is still being worked on.

**dracutdevs/dracut** — dracut the event driven initramfs infrastructure

- Repository: https://github.com/dracutdevs/dracut
- Website: https://github.com/dracutdevs/dracut/wiki
- Stars: 681 · Forks: 401
- Language: Shell
- License: GPL-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/dracutdevs-dracut

## The initramfs has one job, and everything else is negotiation

dracut is described as an event driven initramfs infrastructure, and the readme states the design goal in a sentence: the initramfs has basically one purpose in life, getting the rootfs mounted so that there can be a transition to the real rootfs.

The tool itself creates an initramfs image by copying tools and files from an installed system and combining that with the dracut framework, which is usually found in /usr/lib/dracut/modules.d. So the image is not built from a static template of a minimal system. It is assembled from what the running system already has, plus a framework that decides what to include.

What makes it event driven is how it gets to the root filesystem. Instead of scripts hard-coded to do various things, dracut depends on udev to create device nodes, and when the rootfs device node appears, it mounts and carries on. All of it is driven off device availability.

The stated reason for that design is boot time. Keeping the time required in the initramfs as small as possible is what stops things like a 5 second boot from being made impossible as a result of the very existence of an initramfs. That is a specific, measurable goal, and it explains the shape of the whole system.

The other half of the philosophy is stated as a contrast: unlike other implementations, dracut hard-codes as little as possible into the initramfs. If you have configured a machine with a particular disk controller, a particular filesystem and a particular encryption setup, none of that needs to be baked into the image, because the image asks udev what is there.

## Generator modules decide what the image contains

Most of the initramfs generation functionality in dracut is provided by generator modules, and the readme describes how they fit together.

The modules are sourced by the main dracut script, they live in the modules.d subdirectory, and they use functionality provided by dracut-functions to do their work. So the mechanism is shell: a module contributes a function, the main script calls it, and the result is a set of files copied into the image and some code that runs inside it.

The naming convention with numeric prefixes is visible in the Makefile, which lists the man pages for the systemd module. The module directory 98dracut-systemd contributes a large set of units, each with its own man page: dracut-cmdline.service, dracut-initqueue.service, dracut-mount.service, dracut-shutdown.service, dracut-pre-mount.service, dracut-pre-pivot.service, dracut-pre-trigger.service and dracut-pre-udev.service. The ordering implied by the numbers, with 98 sitting near the end of a two digit range, is how a boot gets sequenced into distinct phases.

That phasing is the point. A pre-mount stage, a pre-pivot stage, a pre-trigger stage and a mount stage are separate concerns, and separating them in the module naming lets a system builder add or remove a whole stage without rewriting the boot sequence.

The main script itself is dracut.sh at the repository root, alongside dracut-functions.sh which is the shared function library the modules use, dracut-init.sh which runs inside the image, dracut-initramfs-restore.sh for putting an initramfs back into an image, dracut-catimages.sh for concatenating images, dracut-logger.sh and dracut-version.sh. There is also lsinitrd.sh, the tool for listing the contents of an initramfs, and an install.d directory for install hooks.

## The repository is mostly shell, and the tooling expects that

The primary language of dracut is Shell, and the repository layout says so plainly. There is a src directory for the compiled pieces, a modules.d directory for the generators, a test directory, a tools directory, a man directory, a docs directory, a shell-completion directory, a dracut.conf.d directory for drop-in configuration, and a set of top level shell scripts.

The build system is a hand written Makefile with a configure step, and the compiler flags are strict by default: -O2 with -g, -Wall, -std=gnu99, -D_FILE_OFFSET_BITS=64, a format security error, and _FORTIFY_SOURCE=2 enabled. The Makefile also probes for shellcheck and shfmt, and the repository carries a .shellcheckrc and an .editorconfig, so the shell sources are treated as code with a linter attached.

That combination is unusual and worth understanding. An initramfs has to run before most of the system exists, so it cannot depend on a language runtime that is itself in the image, and a statically linked binary would need to be built for the target. Shell is the pragmatic answer, and it is why the project invests in shellcheck and shfmt rather than in a build system for a C rewrite.

The version handling in the Makefile is also worth noting. The main and full version numbers are derived from git describe against the tags, with a fallback to the DRACUT_VERSION value, so a build from a checkout can report a version derived from the history rather than from a hard coded string.

The man pages are generated from asciidoc sources, with the introduction in man/dracut.asc and the user manual in man/dracut.usage.asc, and the Makefile lists one page per configuration file and several page 7 pages for the command line, the boot sequence and the module system.

## Tags stop in 2022 while the branch keeps moving

The release history is the one place where a reader has to be careful, because the tags and the development activity tell different stories.

The published releases are 059 from 2022-12-24, 058 from the same day, and 057 from 2022-06-19. The last push was on 2026-09-20, and the readme says dracut is currently developed on GitHub, with the release tarballs on the releases page.

So the code is being worked on while the tags have not moved in nearly four years. The readme points at NEWS.md for information about changes in the releases and at the wiki for sharing information, which is where a user would look to find out what has changed since a version they last installed.

That gap is not unusual for a project of this kind. A distribution ships its own dracut package, built from a specific commit chosen by that distribution, and the upstream tags are a convenience rather than the release channel most people install from. The practical consequence is that when you read a dracut version number, you should find out which distribution build you actually have rather than assume the tag.

The project also has the usual community infrastructure: a Contributor Covenant, a code of conduct, a Gitter chat channel, a GitHub issue tracker, a Hacking document in docs, a mailing list at initramfs@vger.kernel.org for discussion, and a note that the list is a typical vger list with a subscribe procedure. The Hacking document and the mailing list are the real entry points for anyone planning to change behaviour, since the wiki and the issue tracker are for discussion rather than patches.

## What this design costs

There is a real price to the approach, and it is worth being explicit about it since dracut is often presented as strictly better than the alternatives.

The first cost is that the image is assembled by running the generator on the system doing the assembling. That makes the result dependent on the machine the image was built on, which is fine for a distribution building one generic image, and awkward for anyone who wants a small bespoke image for their own hardware. The alternative, a generator that probes the target machine and includes only what it needs, produces a different kind of artifact, and both approaches exist for that reason.

The second cost is complexity in the boot sequence. The dracut boot process is divided into named phases, and each phase has its own unit in the systemd module. That is what makes the sequence debuggable and what lets modules be added and removed, but it also means the early boot is a program with many stages rather than a single script.

The third is that the image contains more than a minimal boot would. Copying tools and files from the installed system means the image reflects what the builder had installed, including things you may not want in early boot. Keeping it lean therefore requires configuration discipline, which is what dracut.conf and the dracut.conf.d drop-in directory are for.

What you get in exchange is an image that does not need to know in advance what hardware it will meet, and a boot that reacts to devices as they appear rather than probing for them in a fixed order. On a machine with a slow or unusual storage stack, that difference is the difference between an initramfs that works and one that needs a rebuild.

## Conclusion

Adopt dracut if you maintain a Linux distribution, an appliance image or a boot flow where the set of modules in the early userspace is a policy decision rather than something you want to hard code, and if you need the result to be the same on every machine regardless of hardware. Do not adopt it if you only need a working initramfs on one machine, because the module system carries real complexity that a host specific generator avoids. Before you commit, read the introduction and user manual man pages, and check the NEWS file and the wiki to see what has changed since the last tagged release.

## FAQ

### What is dracut?

dracut is an event driven initramfs infrastructure. The tool creates an initramfs image by copying tools and files from an installed system and combining them with the dracut framework, usually found in /usr/lib/dracut/modules.d, and it hard-codes as little as possible into the image.

### How does dracut mount the root filesystem?

It depends on udev to create device nodes and is driven off device availability. When the rootfs device node appears, dracut mounts it and continues, instead of running scripts hard-coded to look for specific devices.

### How do dracut modules work?

Most initramfs generation functionality is provided by generator modules that are sourced by the main dracut script, live in the modules.d subdirectory, and use functionality provided by dracut-functions to do their work. The systemd module, numbered 98dracut-systemd, contributes the separate boot phase units.

### How do I see what is inside a dracut initramfs?

The repository ships lsinitrd.sh, the tool for listing the contents of an initramfs, and the Makefile installs a man page for it. The main dracut script and its function library are dracut.sh and dracut-functions.sh at the repository root.

### What is the latest dracut release?

The published tags are 059 from 2022-12-24, 058 from 2022-12-24 and 057 from 2022-06-19, while the last push to the repository was on 2026-09-20. The readme points at NEWS.md for changes in the releases and at the wiki for further information.

## Sources

- [dracutdevs/dracut on GitHub](https://github.com/dracutdevs/dracut)
- [License: GPL-2.0](https://github.com/dracutdevs/dracut/blob/master/LICENSE)
- [Project website](https://github.com/dracutdevs/dracut/wiki)
- [README](https://github.com/dracutdevs/dracut/blob/master/README.md)
- [Releases](https://github.com/dracutdevs/dracut/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dracutdevs-dracut
