Source stays untouched
The stock images live in their own folder and are never written to. Every panel that can undo something puts the partition back from there, byte for byte.
crb Android Kitchen unpacks a firmware package into files you can actually edit, rebuilds each partition in the filesystem you choose, and packs the result back into something a phone will accept. Every screen tells you what it is about to write, what the device can take, and what it will cost you if the two do not match.
Windows 10 and 11, x64 or ARM64, and 64-bit Linux. No WSL, no virtual machine.
Every ROM you open becomes a project, and the project keeps the firmware as it shipped separate from what you changed and from what you built. That separation is the whole safety model: what you are about to flash is never confused with what came out of the box.
The package is unpacked into per partition trees, with the stock images kept aside.
Files, apps, framework, boot images, mount table, device tree, verified boot flags.
Each partition is written back as ext4, f2fs or EROFS, then read back and checked.
Stock against built, path by path, down to the methods inside a jar.
Odin archive, OTA payload, sparse images, or straight to the phone over USB.
The stock images live in their own folder and are never written to. Every panel that can undo something puts the partition back from there, byte for byte.
Ownership, mode, capabilities and the SELinux label of every path are recorded on extraction and written back on build. They are visible per file, not hidden in a config nobody reads.
Extraction, building, patching and comparing all run locally. The only thing that talks to the network is the licence check and the update notice.
Android files carry more than their bytes. A file has an owner, a mode, capabilities and a security context, and getting any of them wrong is the difference between a phone that boots and one that does not. crb reads them out of the image on extraction, shows them per item, and writes them back on build.
Select a file and the inspector shows both sides of it: where it sits in the project, and the line that will end up in the image. Device path, mode, owner, capabilities, SELinux label. Symlinks are shown with their target and with whether that target actually resolves inside the tree.

crb walks two trees by path and marks every row: identical, added, removed, content differs, metadata differs, or the kind of the path changed. It compares filesystem images, and it compares the extracted folders of two projects, which is the same question asked before the build instead of after it. Each side is picked by project and folder, so the two do not have to belong to the same project: stock against built, one firmware release against the next, or the same partition from two different phones. Filesystems do not have to match either, so the stock ext4 image and the EROFS one you just built are directly comparable.
Every screenshot on this page is from a real project. Click one to see it full size.





Not "did the build succeed", but "is the image I am about to flash different from the stock one in exactly the ways I intended, and in no others". Text files get a line diff. Archives get their entry list. Jars and APKs get their methods. And the same tool pointed at two releases instead of at your own work is the fastest way to find what an OEM changed between two builds.
Any partition can be rebuilt in a filesystem it did not ship with. That is a genuinely useful thing to do, and it is also a good way to produce an image the phone cannot mount. crb makes the change one click, and then it tells you everything that has to follow from it.
Switch /system from ext4 to EROFS and the panel immediately says what is wrong: the table in the ramdisk offers ext4 and the build is set to write EROFS, so first stage mount would fail. One button adds the missing row, puts it on the correct side of read only, writes it into the mount table inside vendor_boot.img, and reminds you that the boot image itself now has to be rebuilt for the change to reach the device.

A build is not finished when the last byte is written. crb reopens the image it just produced, reads its superblock, walks its directories, and reports what it found: size, label, UUID, mode, feature flags, how much of the image is actually used, and how long the check took.
The log is not decoration. It records the compression saving, the file and directory counts against the source tree, the space used for data and metadata, and what the filesystem reports as mounted. If a build is wrong, the log is where it shows.

Dynamic partitions are laid back into a single super.img using the layout the firmware itself declares. The group total, what your images use and what is left are shown before you start, so an overflow is something you see rather than something the builder discovers at the end.

Opening a boot image turns it into a working area inside the project: the ramdisk as a directory, the kernel as a file, the device tree as JSON. Everything you do to it is a change to those files, and the image is written once at the end, with everything else that changed.




crb ships no list of packages that are safe to remove, because such a list is a statement about a generic phone and you are not holding one. Every app in the firmware is read: its manifest, the libraries it provides, the apps that need it, the overlays that dress it, the permissions other apps ask for, and the configuration files that name it. The verdict comes with the reasons that produced it.



The framework patcher, the deodexer and the Bluetooth library patcher all work the same way: a dry run that reports exactly what it found and would do, then an apply that keeps a copy of everything it replaced.
Every one of these tools will tell you what it would do and then stop. The report names each file it examined and the decision it reached for it, and the run ends on the line that matters: (dry-run: no files were modified). Nothing about the project has changed, and you know whether the operation is worth starting.
The apply keeps a copy of everything it replaces, and then checks its own work: dex checksums, signatures, and the methods it touched. Backups are listed in the same panel and restore from there, so undoing is one click and not a re-extraction.

Built images are one thing; a package a device will take is another. crb wraps them the way each ecosystem wants, and the log records the archive it produced and the checksum it computed.


LZ4 alone, LZ4 in a tar, or the verified form with the MD5 appended, which is what Odin and the phone expect.
A signed payload.bin built from the selected partition images, or the same payload wrapped in a flashable update zip with its metadata.
Raw and Android sparse conversion in place, transfer list sets as NEW.DAT or Brotli compressed, and Allwinner and Amlogic repacking from the project configuration.
Connect a device over USB and crb asks it what it is and what it can do, then holds the answers next to the images in your project. Writing is deliberate: you tick what goes, you see where each file lands, and the confirmation states the consequence rather than asking whether you are sure.
Each file in the list is matched to a partition on the device and given a status. An image that is larger than the partition it targets says so. An image that lives inside super on this phone says there is no partition of that name to write it to. A raw image going to a target that expects sparse says it will be converted first.


Writing to a phone is presented as experimental and meant for people who already know how to bring one back. crb never writes the partitions that hold a device's identity, it asks before any partition whose loss would cost you fastboot, and it says plainly that a wrong image or an interrupted write can still leave a device that does not start. Have the stock firmware for your exact model ready before you begin.
Firmware work goes wrong in quiet ways: a flag you did not know existed, a table that no longer matches the image, a partition that fits until it does not. crb is built so that the screen you are on already tells you the thing you would otherwise have to know.
Options that carry consequences do not get a tooltip, they get a paragraph. The verified boot panel spells out what each flag stops the phone from checking, and which choice a locked bootloader will still accept.
Restore a boot image from Source, re-extract a partition with its settings, restore a patched jar from its backup, put removed apps back. The undo is on the screen that did the change.
Every operation writes what it did with numbers: files scanned, bytes saved, rows changed, checksums computed, how long the verify took. Filter it by level, copy it whole, or turn on a debug trace when something needs reporting.
The framework patcher and the deodexer analyse first and report what they found. Auto Size measures the tree before it writes. Metadata coverage checks a partition without touching it.
Every image says whether it is stock, changed but not built, or built. Every partition says whether the build settings are the original ones or your overrides. You never have to remember what you did an hour ago.
Extraction, building and packing report progress and can be cancelled. Large images stream instead of being loaded whole, so a 7 GB partition does not need 7 GB of memory.

crb reads a file's header to decide what it is holding. An extension is a convention and firmware breaks it all the time: an .img that is really a vendor container, an archive with the wrong suffix, an image that is sparse when the name says otherwise.
This is not a compatibility list. The vendor layouts above are named because they arrange or hide their contents in a way that belongs to one manufacturer and would otherwise be unreadable. Everything else is simply read for what it is: a Xiaomi update carrying a payload.bin, a recovery zip, a folder of loose images meant for fastboot, a plain archive of sparse partitions. They all go through the same detection, whoever shipped the phone. Oppo, realme and OnePlus firmware is handled from the unpacked package rather than from the .ofp container, including the regional metadata variants and the pointer files that stand in for the real images.
Every filesystem crb reads and writes, every image it packs and every patch it applies is done by the application itself. There is nothing to enable, no distribution to install, no virtual machine to keep running, and no Linux command line hiding behind the interface. If you already have WSL for other reasons, crb neither uses it nor cares.
Not only the menus: the explanations, the warnings and the log labels are translated too, because on this kind of screen the explanation is the part that matters. Switch language from the title bar at any time.
crb Android Kitchen 4 runs on Windows 10 and 11 and on 64-bit Linux. Install it, create a project, point it at a firmware package, and you will be looking at the files inside it in a couple of minutes.