Igir Collection Manager
Igir is a zero-setup ROM collection manager that sorts, filters, extracts, archives, patches, and reports on collections of any size. While not a companion app per se, it's useful for cleaning up a library before importing into RomM, so scans have a better-named, better-organised starting point.
This is not an official app. Igir is a separate community project, but we document integration here because it's a common workflow and produces a compatible layout directly.
When you'd use Igir
- You have a messy collection with inconsistent naming, mixed formats, dumps from multiple sources.
- You want to match against No-Intro/Redump DAT files to verify authenticity and standardise names.
- You want to filter only retail releases, or strip out hacks, or keep only one region, etc.
- You want to move/rename files to the expected platform folder layout.
Directory setup
Igir works on a copy of your ROMs (never in place) to let you iterate on its config without risking the originals.
.
├── dats/ # DAT files (No-Intro, Redump)
├── roms/ # Your original ROM collection (untouched)
├── roms-unverified/ # Working copy Igir will process
└── igir-romm-cleanup.sh # the script below
- Make a working copy
- Download DAT files
DAT files are hash-referenced catalogues Igir matches against.
- Cartridge systems: No-Intro daily, full DAT compilation
- Optical systems (PS1, Saturn, etc.): Redump, per-platform DAT files
Drop the DAT files into dats/. You can use a subset if you only care about specific platforms.
The cleanup script
Save as igir-romm-cleanup.sh:
#!/usr/bin/env bash
set -ou pipefail
cd "$(dirname "${0}")"
INPUT_DIR=roms-unverified
OUTPUT_DIR=roms-verified
# https://igir.io/
# DAT files: https://datomatic.no-intro.org/index.php?page=download&op=daily
time npx -y igir@latest \
move \
extract \
playlist \
report \
test \
-d dats/ \
-i "${INPUT_DIR}/" \
-o "${OUTPUT_DIR}/{romm}/" \
--input-checksum-quick false \
--input-checksum-min CRC32 \
--input-checksum-max SHA256 \
--only-retail \
--merge-discs
Make it executable:
Run
Manually migrate leftovers
Some ROMs won't be identified (homebrew, hacks with --only-retail, truly unknown dumps). Move them manually preserving the folder shape:
This keeps the original subfolder structure but normalises extensions.
Multi-disc games
Redump and No-Intro catalogue each disc of a multi-disc game as a separate game, so by default Igir writes them out as sibling folders — which confuses multi-file game detection. Two parts of the script above handle this, no manual reorganisation needed:
--merge-discsgroups the discs of a game back into a single folder.- The
playlistcommand writes an.m3ualongside them.
Before:
Final Fantasy VII (USA) (Disc 1)/
Final Fantasy VII (USA) (Disc 2)/
Final Fantasy VII (USA) (Disc 3)/
After:
Final Fantasy VII (USA)/
Final Fantasy VII (USA) (Disc 1)/
Final Fantasy VII (USA) (Disc 2)/
Final Fantasy VII (USA) (Disc 3)/
Final Fantasy VII (USA).m3u
The .m3u is a playlist RomM respects for launching multi-disc games. It holds a relative path to each disc's playable file, in disc order:
Final Fantasy VII (USA) (Disc 1)/Final Fantasy VII (USA) (Disc 1).cue
Final Fantasy VII (USA) (Disc 2)/Final Fantasy VII (USA) (Disc 2).cue
Final Fantasy VII (USA) (Disc 3)/Final Fantasy VII (USA) (Disc 3).cue
A few things worth knowing:
- A playlist points at each disc's playable file, so discs can't be sitting inside zip archives — that's why the script uses
extractrather thanzipfor these platforms. The extensions Igir will reference default to.ccd,.cdi,.chd,.cue,.gdi,.iso,.mdf, and.toc, adjustable with--playlist-extensions. - CHDs need no special handling to appear in a playlist, though the script as written will unpack them — see Keeping CHDs as CHDs.
- Playlists are only written for multi-disc games. If you want one for every game, add
--playlist-mode always. --merge-discsdoesn't require DAT files, but is far more reliable with them — the script already passes-d dats/.- Some TOSEC-catalogued discs won't merge, because the ring/box codes used to distinguish separate pressings can't be told apart from other metadata programmatically. See Igir's merging limitations.
Keeping CHDs as CHDs
Igir reads inside a CHD to identify its tracks, but extract will unpack it into those tracks — .cue/.bin, or .gdi — rather than leaving the CHD intact. This applies to single-disc games as much as multi-disc ones.
extract applies to the whole run, so dropping it to protect your CHDs would also stop cartridge ROMs being unzipped. Split the run in two instead, excluding CHDs from the pass that extracts and handling them in a second pass that copies them through untouched:
# Everything except CHDs, extracted
npx -y igir@latest \
move extract playlist report test \
-d dats/ \
-i "${INPUT_DIR}/" \
-I "${INPUT_DIR}/**/*.chd" \
-o "${OUTPUT_DIR}/{romm}/" \
--only-retail \
--merge-discs
# CHDs, left as they are
npx -y igir@latest \
move playlist report test \
-d dats/ \
-i "${INPUT_DIR}/**/*.chd" \
-o "${OUTPUT_DIR}/{romm}/" \
--only-retail \
--merge-discs
Each game's discs are either all CHDs or all not, so disc grouping and playlists still come out right despite the split.
Matching CHDs against DATs is slower on the first run, since a CHD carries only a SHA1 rather than per-file CRC32. Igir caches the results, so subsequent runs are much faster.
Importing
Once roms-verified/ looks right, mount it as the library:
Read-only is safer: if you need Igir to re-clean, work in a parallel folder and re-promote it to roms-verified/. Once you run a scan from RomM, and everything should match cleanly against providers!