Everything in Unix is a file, except for the filesystem itself.
Until now.

Filesystems as plain text.

A c4m file describes an entire directory tree — permissions, timestamps, sizes, names, and a permanent identity for every file. Human-readable, diff-able, and small enough to email.

It's a filesystem in a text file.

# You can cd into it.
$ cd project.c4m
# You can list directories.
project:/ $ ls
.blenderrc assets/ renders/ scenes/ scripts/
# You can move and remove things.
project:/ $ mv renders/ final/
project:/ $ rm .blenderrc
project:/ $ ls -la
drwxr-xr-x 135 Mar 26 11:23 assets/ drwxr-xr-x 0 Mar 26 11:23 final/ drwxr-xr-x 789663 Mar 26 11:24 scenes/ drwxr-xr-x 0 Mar 26 11:23 scripts/
project:/ $ cd ..
# That was all inside a text file. Let's look at it.
$ cat project.c4m
drwxr-xr-x 2026-03-26T11:23:51Z 135 assets/ c42vDWM3UiMPrUH37d51tdsRvj8eAGqPQT9PZHnKo2qRVGMZsSLU1MgxoqnKQ5K5oYqzCts6FCbjLAgyVDVyxQKGox drwxr-xr-x 2026-03-26T11:23:51Z 0 textures/ c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT drwxr-xr-x 2026-03-26T11:23:51Z 0 final/ c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT drwxr-xr-x 2026-03-26T11:24:01Z 789663 scenes/ c45ppJrosXHjfdg3x2htEaXix51JwNrt1newAcJX7nKmLPaFCfNQqd8nnDyaaisksGA8Hp8qd3sJJwfpfVCWSkr6MS -rw-r--r-- 2026-03-26T11:24:01Z 789514 final.blend c45WbQYYBaRmToPRQrjnjcvFYAxqrHm4iLQbT7t2U58yPT5ScptCCRcPW9v7Ss2MCwagodLbqPrzPSJ7Y7PHnh7LXK drwxr-xr-x 2026-03-26T11:23:51Z 0 scripts/ c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT

cd, ls, mv, rm — they all work. The file is the filesystem.

Copy the file. Copy the filesystem.

# We have a backup from yesterday.
$ ls -l *.c4m
-rw-r--r-- 482 Mar 26 11:25 project.c4m -rw-r--r-- 530 Mar 25 17:00 project-backup.c4m
# The backup still has the original files.
$ cd project-backup.c4m
project-backup:/ $ ls
.blenderrc assets/ renders/ scenes/ scripts/
project-backup:/ $ ls scenes/
skeleton-arm.blend
project-backup:/ $ cd
# Two text files. Two complete snapshots. No duplicate storage.

Whole filesystems as simple text file copies. cp, scp, email, git — they all just work.

240 frames. One line.

# A Nuke comp with 240 EXR plates.
$ ls comp/plates/ | wc -l
240
# c4m supports range expressions — 240 frames become a single entry.
$ c4 -S comp/ > comp.c4m
$ cat comp.c4m
-rw-r--r-- 2026-03-26T13:02:28Z 284 shot_010.nk c41rYbrum5LihdP3MrVyXUZ3cJM2TyUtkoNfU4qF4YFkr96XtwyAgp4JJpcvHpvD8fYhyrATHqXQgJFbPbhFycMt2X drwxr-xr-x 2026-03-26T13:02:21Z 12322560 plates/ c43N332ZosgtAj14LYQgrhAodS62oNx4qcYpPEGESLvZra9GWH6SstLE47BGYxUwm1TUy7baXeB4UsWLyjVktJv7FH -rw-r--r-- 2026-03-26T13:02:21Z 12288000 plate.[1001-1240].exr c45mxwEGonWBUYArtWXrRcxyQQ7rL2AuATp9bDvWAUJadsthNCfLyZZorYgws4WbNoZo2zamSnarEXKNET3YLzDCf7

Range expressions let you treat frame sequences as single units. 240 plates + a Nuke script = 3 lines. Email it.

Every file gets a permanent identity.

# Pipe any content into c4. It gets a permanent ID.
$ cat .blenderrc | c4
c438TPsEXWD76kqwE7k3tfkyBF55kPLS4NWfQvraUFUfTuaW3dD9B76NdCV48i7v6chTVtLzNr21Lvn59toBmqoJwt
# That ID is now in the store. Same bytes will always produce the same ID.
# Scan a directory — every file and folder gets one.
$ c4 -e workspace/
-rw-r--r-- Mar 26 11:23 2026       114 .blenderrc                          c438TPsEXWD76kqwE7k3tfkyBF55kPLS4NWfQvraUFUfTuaW3dD9B76NdCV48i7v6chTVtLzNr21Lvn59toBmqoJwt drwxr-xr-x Mar 26 11:23 2026       135 assets/                             c42vDWM3UiMPrUH37d51tdsRvj8eAGqPQT9PZHnKo2qRVGMZsSLU1MgxoqnKQ5K5oYqzCts6FCbjLAgyVDVyxQKGox   drwxr-xr-x Mar 26 11:23 2026         0 textures/                         c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT drwxr-xr-x Mar 26 11:23 2026         0 renders/                            c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT drwxr-xr-x Mar 26 11:24 2026   789,663 scenes/                             c45ppJrosXHjfdg3x2htEaXix51JwNrt1newAcJX7nKmLPaFCfNQqd8nnDyaaisksGA8Hp8qd3sJJwfpfVCWSkr6MS   -rw-r--r-- Mar 26 11:24 2026   789,514 skeleton-arm.blend                c45WbQYYBaRmToPRQrjnjcvFYAxqrHm4iLQbT7t2U58yPT5ScptCCRcPW9v7Ss2MCwagodLbqPrzPSJ7Y7PHnh7LXK drwxr-xr-x Mar 26 11:23 2026         0 scripts/                            c459dsjfscH38cYeXXYogktxf4Cd9ibshE3BHUo6a58hBXmRQdZrAkZzsWcbWtDg5oQstpDuni4Hirj75GEmTc1sFT
# The .blenderrc ID matches — same content, same identity.
# Content is in the store. Retrieve it anytime by ID.
$ c4 cat c438TPsEXWD76kqwE7k3tfkyBF55kPLS4NWfQvraUFUfTuaW3dD9B76NdCV48i7v6chTVtLzNr21Lvn59toBmqoJwt | head -2
# Default render settings render_engine = CYCLES

c4 stores content automatically. The ID is a permanent pointer to exactly those bytes.

What changed? See it instantly.

$ c4 explain diff yesterday.c4m project.c4m
Comparing yesterday.c4m (2 files) against project.c4m (3 files): 1 modified scenes/skeleton-arm.blend 789,514 → 812,032 bytes 1 added renders/frame_001.png 2,148,576 bytes 1 file unchanged.

No need to have both versions on disk. The c4m file remembers what was there.

Lost files, found instantly.

# Mystery files on a render node. No project name, no version.
$ c4 /farm/scratch/ > mystery.c4m
# Find them by content identity, not filename.
$ c4 intersect id mystery.c4m projects/feature.c4m | c4 paths
shots/sh010/scenes/scene.blend shots/sh010/renders/frame_001.png
# Two mystery files traced to shot 010. Different paths, same content.

Identity follows the content, not the path. Rename it, move it, archive it — the link holds.

The description is a view

A c4m file is a window into a project. Have many views — snapshots, versions, organizations. Switch between them instantly because views are tiny.

Pull from any source

Identities come from the content, not a system. A local drive, NAS, cloud bucket, or colleague's machine — any source with the right content works.

Indelible metadata

Link anything to a file by its identity. The file can move, be renamed, archived. The link holds — it links to what the file is, not what it's named.

Plain text is the superpower

grep, diff, awk, email, git — they all work on c4m files. When compressed, the text format is within 2% of an optimal binary format. It's not a compromise.

Open source Zero dependencies SMPTE ST 2114 standardized Cross-language verified

Install

Homebrew macOS / Linux — includes c4 + c4sh
brew install mrjoshuak/tap/c4
Go
go install github.com/Avalanche-io/c4/cmd/c4@latest
Python pip
pip install c4py
JavaScript npm
npm install @avalanche-io/c4

See c4toolkit for binary downloads and the full version matrix.

The toolkit

c4

Go

The CLI. Describe directories, diff c4m files, reconcile filesystems.

Shell integration. cd project.c4m and ls just works.

c4py

Python

Scan, diff, verify in Python. Zero dependencies.

Git for large files. No repo bloat, no server.

c4ts

TypeScript

Browser + Node.js. WebCrypto. Zero dependencies.

Native Swift for Apple platforms.

Embed file identification in any application.