mkinitcpio or Dracut, which initramfs tool fits you?

mkinitcpio and Dracut solve the same problem - building the initial RAM filesystem that mounts your real root - but they use opposite philosophies. mkinitcpio reads an ordered list of hooks (small shell snippets) declared in /etc/mkinitcpio.conf, while Dracut uses self-contained modules with deeper systemd integration that auto-detect what your system needs. If you run an Arch-family distro
(Arch, EndeavourOS, Manjaro, CachyOS), stick with mkinitcpio; it is the default, it is what every Arch wiki page assumes, and the hook model is easy to reason about. If you run Fedora
, RHEL, Rocky, Alma, openSUSE, or Ubuntu 26.04 LTS or later, use Dracut; it is the upstream default across the entire non-Arch ecosystem and has the best UKI and Secure Boot story in 2026.
What an Initramfs Is and Why You Need a Generator
The Linux kernel has a chicken-and-egg problem. To mount your real root filesystem, it needs drivers like dm-crypt, lvm, btrfs, or nvme, plus userspace helpers such as cryptsetup, lvm2, and mount.btrfs. Those drivers and binaries live on the very root filesystem the kernel has not mounted yet. The initramfs breaks that cycle: a compressed cpio archive containing a minimal /init (or systemd), a tiny /bin, kernel modules, firmware blobs, udev rules, and any decryption or unlock tooling required to pivot to the real root.
Distros ship a generator rather than a prebuilt image because kernels update, hardware changes, and encryption layouts differ per machine. The initramfs must be rebuilt locally on every kernel upgrade, and that is exactly what a generator does.
Two tools dominate in 2026. mkinitcpio comes from Arch, is written in Bash, uses a hook-based model, and ships as the default on Arch, EndeavourOS, Manjaro, CachyOS, and Garuda. Dracut has Red Hat origins, is also mostly Bash but organized around modules, and is now the upstream default for Fedora, RHEL, openSUSE, and Ubuntu 26.04 LTS .
A few other tools still exist but no longer matter much. initramfs-tools (the Debian/Ubuntu legacy) is deprecated in Ubuntu 26.04 per the release notes. genkernel remains a Gentoo niche. booster, the Go-based Arch alternative, produces smaller and faster images but has not displaced mkinitcpio because the surrounding ecosystem is too entrenched.
How the bootloader hands off is the part most people picture correctly: GRUB, systemd-boot
, rEFInd, or a UKI-aware EFI stub loads vmlinuz-linux plus initramfs-linux.img. The kernel unpacks the cpio archive into a tmpfs and /init takes over as PID 1. A broken initramfs means an unbootable system, so understanding which tool you have and how to regenerate it is core sysadmin literacy, not optional trivia.
mkinitcpio Architecture and the Four Arrays
mkinitcpio is easiest to understand as an ordered list of Bash functions that each add stuff to the cpio. The entire configuration lives in four arrays in /etc/mkinitcpio.conf:
MODULES=()for kernel modules to force-include.BINARIES=()for extra userspace binaries to ship.FILES=()for arbitrary files to copy in.HOOKS=()for the ordered build-script list, which is where most of the action happens.
A typical Arch HOOKS line looks like this:
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)Each word is a script under /usr/lib/initcpio/install/ that adds files, paired with a runtime script under /usr/lib/initcpio/hooks/. Order is foot-gun number one: encrypt must come before lvm2 and filesystems, keyboard must come before encrypt if you want to type your LUKS password, and autodetect must come early to actually shrink the image. Put autodetect last and you get a 300 MB fallback-sized image by accident.
Presets live in /etc/mkinitcpio.d/linux.preset and define which images get built (default, fallback), with what config, and where they land. This is what pacman
triggers via the mkinitcpio hook on every kernel upgrade.
The commands you actually type are short:
mkinitcpio -P # rebuild every preset for every kernel
mkinitcpio -p linux # rebuild just the linux preset
mkinitcpio -g /boot/test.img -k 6.13-arch1 # one-off image for a specific kernelThe strengths are worth listing honestly. mkinitcpio is trivially auditable because it is just Bash. Builds are fast. The Arch Wiki mkinitcpio page documents every hook in painful detail. The hook list fits in a short line you can diff across machines.

Dracut Architecture and Module-Based Configuration
Dracut takes the opposite approach. Instead of asking you to list hooks in the right order, it ships around 100 modules under /usr/lib/dracut/modules.d/ that each declare their own dependencies and probe the host. The result is host-only images that are smaller and auto-configured, at the cost of being harder to predict.
Every module is a self-contained subdirectory like 90crypt/, 90lvm/, 95udev-rules/, 98systemd/, containing a module-setup.sh with check, depends, and install functions. When you run Dracut, it walks those modules, asks each one “do I need you?”, and pulls in the dependency closure.
Two build modes matter. hostonly=yes (the Fedora/RHEL default) probes your actual hardware and filesystems and only includes what you need, producing tiny ~20 MB images. hostonly=no builds a portable image with everything, useful for installer media, rescue USBs, or VMs you plan to clone.
Configuration happens through drop-in files in /etc/dracut.conf.d/*.conf:
# /etc/dracut.conf.d/10-local.conf
add_dracutmodules+=" crypt lvm "
omit_dracutmodules+=" plymouth "
compress="zstd"
hostonly="yes"The real Dracut advantage is systemd integration. The systemd module pulls systemd into the initramfs, so you get proper unit ordering, systemd-cryptsetup for LUKS unlock, systemd-networkd for network-root scenarios, and journal logs you can inspect with journalctl -b -1 after boot. When something goes wrong in the pre-pivot phase, Dracut tells you why instead of dumping you into a bare Bash shell with no log.
The daily-use commands:
dracut --force # rebuild for the running kernel
dracut --regenerate-all --force # rebuild for every installed kernel
dracut --print-cmdline # print the kernel cmdline Dracut expects
lsinitrd /boot/initramfs-$(uname -r).img # list the contentsThe current upstream is dracut-ng
, a community fork that has replaced the original dracutdevs/dracut (last tagged 2022) across every major distro. Recent dracut-ng releases (102 through 110+ in 2026) added compatibility fixes for kernels up to 6.9+, systemd 256+, a new net-lib module, and improved UKI handling.
Ubuntu 25.10 switched to Dracut as the default
, and 26.04 LTS completes the migration by dropping initramfs-tools from the default install. The Canonical rationale is UKI support, systemd alignment with the rest of the ecosystem, and less Debian-specific maintenance burden. Fedora Silverblue and other immutable Linux distributions
go further still, pairing Dracut with atomic image updates and a read-only root that makes initramfs regeneration part of the deployment pipeline.

Hooks vs Modules: LUKS-on-LVM Side by Side
Abstract architecture comparisons are forgettable. LUKS-on-LVM (the most common Linux encryption layout in 2026) shows exactly what changes between the two tools, line by line.
With mkinitcpio you edit /etc/mkinitcpio.conf, run the generator, then update your bootloader cmdline:
# /etc/mkinitcpio.conf
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont
block encrypt lvm2 filesystems fsck)
# then:
mkinitcpio -P
# bootloader kernel cmdline:
cryptdevice=UUID=<luks-uuid>:cryptroot root=/dev/mapper/vg-rootWith Dracut you drop a config file, run the generator, and update the cmdline:
# /etc/dracut.conf.d/10-crypt.conf
add_dracutmodules+=" crypt lvm " # often unnecessary; hostonly auto-detects
compress="zstd"
# then:
dracut --force
# bootloader kernel cmdline:
rd.luks.uuid=<luks-uuid> rd.lvm.lv=vg/root root=/dev/mapper/vg-rootThe cmdline syntax is the most visible divergence. mkinitcpio parses a single cryptdevice=UUID=...:name pair inside its encrypt hook. Dracut uses the structured rd.luks.* namespace (rd.luks.uuid, rd.luks.name, rd.luks.options, rd.luks.key) inherited from systemd-cryptsetup-generator. The Dracut style is more verbose but composes better with other systemd generators.
| Scenario | mkinitcpio | Dracut |
|---|---|---|
| Keyfile on rootfs | cryptkey=rootfs:/etc/keyfile + FILES=(/etc/keyfile) | rd.luks.key=/etc/keyfile |
| TPM2 auto-unlock | sd-encrypt hook (systemd flavor) | rd.luks.options=tpm2-device=auto |
| Detached LUKS header | :header=/path/to/hdr | rd.luks.hdr=/path/to/hdr |
| Remote SSH unlock | AUR mkinitcpio-netconf + mkinitcpio-dropbear | built-in 90crypt-ssh module |
| Emergency shell | break=premount, break=postmount | rd.break=pre-pivot (or pre-udev, pre-mount, mount) |
TPM2 unlock via systemd-cryptenroll is where Dracut pulls ahead. Because Dracut ships real systemd-cryptsetup, rd.luks.options=tpm2-device=auto works with no extra glue. mkinitcpio needs the sd-encrypt hook (the systemd-flavored replacement for plain encrypt) to get equivalent behavior, which in turn requires dropping the encrypt hook and adding sd-vconsole for keymaps.
Debugging feels different too. When mkinitcpio’s boot fails, you drop into a Bash emergency shell at whatever break= you specified, with whatever binaries happened to be included. Dracut drops you into a real systemd rescue shell with journalctl available, so you can scroll back through structured logs instead of guessing what the pre-pivot phase was doing.
Image Sizes and the Compression Story
Size differences between the two tools are real but often overstated on forums. A fresh install measurement looks roughly like this on a typical laptop with LUKS + LVM + Btrfs:
| Configuration | Typical size |
|---|---|
mkinitcpio default (autodetect) | 10-18 MB |
| mkinitcpio fallback (no autodetect) | 100-180 MB |
Dracut hostonly=yes | 20-35 MB |
Dracut hostonly=no | 80-150 MB |
Arch’s mkinitcpio defaults to zstd -19 (highest compression), while Dracut defaults closer to zstd -15. The wall-clock impact on boot time is negligible because modern CPUs decompress zstd faster than SSDs can read, but build time differs noticeably: a full dracut --regenerate-all takes 20-40 seconds on a kernel upgrade, while mkinitcpio -P finishes in 5-10 seconds on similar hardware. If you rebuild the initramfs ten times a day while debugging, that adds up. To measure the actual contribution of initramfs decompression to your total boot sequence, systemd-analyze is the right starting point for pinpointing which boot phase is the real culprit
.
The larger “3x bigger” numbers reported on some Arch forums when users first try Dracut usually come from forgetting to set hostonly=yes or from Dracut pulling in modules (like plymouth or full systemd) that mkinitcpio omits by default. A tuned Dracut config sits within 2x of mkinitcpio on the same machine, and in exchange you get the systemd tooling inside the image.
UKI Support and Secure Boot in 2026
A Unified Kernel Image bundles the kernel, initramfs, cmdline, and optionally a splash and devicetree into a single signed PE binary that the EFI firmware loads directly. There is no separate GRUB entry, no loose initramfs file sitting on an unsigned ESP, and one signature to verify. Both generators support UKI generation natively in 2026, which is why most distros no longer treat the choice of initramfs tool as an argument worth having.
The reason UKIs exist is the security model. With a separate vmlinuz plus initramfs.img plus bootloader cmdline, an attacker with write access to the ESP can swap the unsigned initramfs and bypass Secure Boot, because only the bootloader and kernel are typically signed. Bundling everything into a signed PE binary closes that gap and is what modern measured boot with TPM2 PCR sealing actually depends on.
For mkinitcpio, UKI generation is driven by presets. Since mkinitcpio 38+, /etc/mkinitcpio.d/linux.preset can declare:
default_uki="/efi/EFI/Linux/arch-linux.efi"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"and mkinitcpio -P builds a signing-ready UKI directly. If systemd-ukify is installed, mkinitcpio offloads the assembly to ukify; otherwise it assembles the PE itself.
For Dracut, UKI generation is a flag on the command line:
dracut --force --uefi --kernel-cmdline "root=UUID=... rw quiet"produces a UKI in /boot/efi/EFI/Linux/. The --uefi-stub flag lets you pick a non-default stub (e.g., sd-stub from systemd-boot).
Neither tool signs the resulting .efi by default, which is the correct design. Key management is separate from image generation. You run sbctl sign -s /efi/EFI/Linux/arch-linux.efi afterward, or sbsign --key db.key --cert db.crt --output ... ..., ideally via a pacman or dnf hook that runs after the generator.
Microcode handling is the one detail people miss. UKIs embed CPU microcode (amd-ucode.img, intel-ucode.img) as a separate .ucode PE section, so you no longer need a separate initrd /amd-ucode.img line in your bootloader config. Both mkinitcpio 38+ and dracut-ng 060+ handle this correctly, but older configs that still list microcode as a separate initrd will either double-load it or quietly ignore it depending on the loader.
If you are setting up Secure Boot today, UKIs are the path of least resistance and both generators support them natively. This is no longer a reason to pick one tool over the other.
Migrating Between the Two Without Breaking Boot
People migrate in both directions. Arch users get curious about Dracut’s systemd integration after running Fedora on a work laptop, and ex-Fedora users on Arch sometimes want a more predictable hook model. The migration itself is straightforward but has one rule: never delete the old generator’s images until you have successfully booted into a new one.
Before you start, boot into the rescue or fallback image at least once, keep a live USB nearby, and remember how to arch-chroot (or chroot) into your root. Initramfs misconfiguration is the number one cause of “I broke my boot” forum posts, and the recovery always involves one of these three things.
For Arch moving to Dracut:
pacman -S dracut
cat > /etc/dracut.conf.d/10-arch.conf <<EOF
hostonly=yes
compress=zstd
EOF
dracut --force --regenerate-allThen edit /etc/mkinitcpio.d/linux.preset to disable image generation, or install the dracut-hook package that replaces the mkinitcpio pacman hook with a Dracut equivalent.
Going the other direction from Fedora or Ubuntu to mkinitcpio really only applies if you also switched to Arch. Do not fight the distro default if you are staying on Fedora. On Arch, install mkinitcpio (it is already in base), populate the HOOKS= line, run mkinitcpio -P, and remove any Dracut pacman hooks you installed.
A short translation table for the cmdline covers most real migrations:
| mkinitcpio | Dracut |
|---|---|
cryptdevice=UUID=X:root | rd.luks.uuid=X |
cryptkey=rootfs:/path/key | rd.luks.key=/path/key |
resume=UUID=Y | resume=UUID=Y (identical) |
root=UUID=Z | root=UUID=Z (identical) |
rootflags=subvol=@ | rootflags=subvol=@ (identical) |
Verify before you reboot. lsinitrd /boot/initramfs-$(uname -r).img | grep -E 'crypt|lvm' (Dracut) or lsinitcpio /boot/initramfs-linux.img | grep -E 'crypt|lvm' (mkinitcpio) confirms encryption tooling is present. dracut --print-cmdline shows what Dracut thinks the cmdline should look like based on your running system.
Update the bootloader last. Re-run grub-mkconfig -o /boot/grub/grub.cfg (GRUB), bootctl update (systemd-boot), or regenerate your UKI. The initramfs filename or location may have changed and the boot entry needs to match.
If you break it, boot the previous kernel from the bootloader menu, or boot a live USB, chroot into your root, and rebuild with the tool that worked last. That is precisely why you do not delete the old images on day one.
The Practical Recommendation
The pragmatic answer in 2026 is boring: use whatever your distro uses. Both tools are mature, both support UKIs, both handle LUKS with TPM2, and both have good documentation once you know where to look. Fighting the distro default buys you maintenance headaches on every kernel update and nothing else.
The more interesting question is what to pick for a new install on a distro-agnostic substrate like mkosi, or when you are writing your own custom image. There the answer tilts toward Dracut, because the systemd integration matches what the rest of the modern Linux stack already expects, and the rd.* cmdline namespace composes cleanly with other systemd generators. mkinitcpio remains the better choice on Arch because everything in the ecosystem assumes it. Every AUR package that touches boot, every wiki page, every support thread is written with mkinitcpio in mind, and swimming against that current is unrewarding work.
Pick the default, read the man page once, and spend the saved time on something more interesting than your initramfs.
Botmonster Tech