If you need to store some data on a resource-constrained embedded platform, the prospect of dragging in a dependency for something like FAT filesystem access to flash or other storage medium can seem rather daunting. Not only is your binary size now significantly larger, the overhead of these filesystems is also not insignificant as they were not really designed for this type of environment. Here [Drew Gaylo]’s UTFS format is an interesting alternative to just writing raw binary data to said storage medium.
As explained in the accompanying introduction article, the basic idea is similar in scope but very much slimmed down compared to the venerable Tape ARchive (TAR) format, hence the Micro (µ) Tar File System name. The provided UTFS implementation is quite small, spanning two source files in C99 with zero heap usage. Targeting a custom store medium requires implementing one read and one write function to match the underlying platform.
A couple of examples are also provided, covering using the built-in Flash of a SAMD20 MCU and the EEPROM of an ATmega328. Compared to raw binary data that’d have to be fully rewritten, UTFS allows for sections of the storage to be accessed as files and thus updated in-place.

I struggle to see where you would both want minimal FS and it wouldn’t make sense to just use a simple id + length style header for your file layout. This is only slightly more complex, but wastes space on magic headers, version, name, and CRC, that are all overkill for most embedded purposes. Anything that needs to allow dynamic writing would probably be better served with a more robust, existing system.
my thoughts exactly. there’s very little space between “too simple for FAT” and “too complicated for id+length”. mostly because reading FAT is so easy
I agree, “id+length” done in a class so it is transparent to my program is pretty much the way I go too – and if it is a lot of storage on a bigger processor you may as well go with an actual file system..
It doesn’t even have a CRC despite the 24byte header.
The minimal FS becomes useful when you write to removable media which you then plug into a PC. If your PC Operating System supports that minimal FS.
What i was thinking, just take an old school WAD file as first used in Doom and call it a day. The eight bytes from the header are negligible for the ease of use as you don’t have to write any tooling yourself, the Doom community got you covered.
I didn’t anticipate that there could be a fully functional filesystem for even a 512 byte storage device. While I’ll still use raw packed structs for anything between 0.5KB to 32KB and LittleFS for anything above, it’s still great to see a neat option.
I ran into an issue on ESP32 where all of the file systems hooked into the flash HAL and even reads would block the cpu. This was true for both FAT and SPIFFS. So i ended up making my own using the ESP32 memory mapper so interrupts and things would not be blocked when reading. https://github.com/FL0WL0W/ESP32C6-CAN-Expander/blob/main/components/MMROFS/MMROFS_FORMAT_SPEC.md
This fits exactly what I was looking for my bare metal macro and config storage for cross mcu protocol level stuff. I’m writing desktop app created macro/snippets to “Whatever mcu” is connected. I need a portable way to toss in some data (eeprom via i2c, flash, sd card?) where it doesn’t care if you’re too resource constrained. For my freertos and zephyr builds I have nvs built in. for some form of on the fly changeable storage on something like a ch552, this will fit the bill.
How does this compare against squashfs?
squashfs is even more complicated than FAT. it’s a full-featured (tho read-only) filesystem. symlinks and device nodes and everything. plus it’s compressed. it’s pretty simple for what it is, but it has a ton of features.