carfile-go is a pure-Go library and CLI for parsing and extracting Apple's compiled Asset Catalog (Assets.car) format. It uses only the Go standard library and does not call CoreUI, assetutil, cgo, or third-party codecs at runtime.
Build the command:
go build -o carfile ./cmd/carfileRunning it with only an input file recovers every logical resource into an <name>-extracted directory beside the input:
carfile Assets.carOptions:
Usage:
carfile [options] <Assets.car>
Options:
-o, --output DIR Output directory
-f, --format FORMAT resources (default), xcassets, raw, png, or json
-i, --include PATTERN Include asset/file glob; may be repeated
-q, --quiet Disable progress output
-v, --version Print version
-h, --help Show help
Examples:
carfile Assets.car
carfile -o output Assets.car
carfile -i AppIcon Assets.car
carfile -i 'myBannerImage_*' -i '*@2x.png' Assets.car
carfile --format xcassets --output restored Assets.car
carfile -f raw -o payloads Assets.car
carfile -f json -o metadata Assets.car| Format | Output |
|---|---|
resources |
All logical resources, grouped by asset name. Packed atlas entries are cropped into individual files. This is the default. |
xcassets |
A flat, compilable Assets.xcassets with generated Contents.json files. |
raw |
Physical CAR payloads with wrappers removed where possible. Compressed data stays compressed. |
png |
Every directly stored compressed bitmap as PNG, including packed atlas images. |
json |
Parsed CAR metadata in catalog.json. |
Every extraction directory includes a machine-readable manifest except the JSON format, whose output is already self-describing.
--include/-i accepts Go-style glob patterns and can be repeated. Patterns are ORed and are matched against the logical asset name, rendition filename, and asset/file path. Filtering happens before bitmap decompression and PNG encoding.
# Both @2x and @3x renditions from one logical asset
carfile -i myBannerImage_de Assets.car
# One exact rendition
carfile -i myBannerImage_de@2x.png Assets.car
# Several asset families
carfile -i 'HomePage_*' -i 'AppIcon' Assets.car
# Precise asset/file selection
carfile -i 'AppIcon/Icon-iPhone-60@3x.png' Assets.carThe same filter is available to library callers through ExtractOptions.Includes. Include filters apply to resources, xcassets, raw, and png; JSON output always describes the complete catalog.
For a logical image stored inside a packed atlas, use resources or xcassets; these formats resolve the internal link and crop the requested image. The png format intentionally operates on directly stored physical bitmap renditions, while raw operates on physical payloads.
The CLI displays the current percentage, item count, asset name, and rendition filename while extracting. Interactive terminals reuse one line; redirected output uses one event per line. Use --quiet/-q to disable progress.
Library callers can receive the same synchronous, serial progress events:
result, err := carfile.ExtractFile("Assets.car", carfile.ExtractOptions{
Format: carfile.FormatResources,
OutputDirectory: "output",
Progress: func(event carfile.Progress) {
log.Printf("%d/%d %s/%s", event.Current, event.Total, event.AssetName, event.FileName)
},
})The module root is a regular importable Go package; the CLI is isolated under cmd/carfile.
package main
import (
"log"
carfile "github.com/devcxm/carfile-go"
)
func main() {
result, err := carfile.ExtractFile("Assets.car", carfile.ExtractOptions{
Format: carfile.FormatXCAssets,
OutputDirectory: "restored",
Includes: []string{"AppIcon", "myBannerImage_*"},
})
if err != nil {
log.Fatal(err)
}
log.Printf("wrote %d files to %s", result.Written, result.OutputDirectory)
}For parsing without immediately exporting:
catalog, err := carfile.Open("Assets.car")
if err != nil {
return err
}
result, err := catalog.Export(carfile.ExtractOptions{
Format: carfile.FormatResources,
OutputDirectory: "output",
})Individual codecs are independently importable:
import (
"github.com/devcxm/carfile-go/codec/deepmap2"
"github.com/devcxm/carfile-go/codec/kcbc"
"github.com/devcxm/carfile-go/codec/lzfse"
"github.com/devcxm/carfile-go/codec/lzvn"
)The parser reads:
- BOMStore headers, block indices, variables, and linked B+ tree leaves;
CARHEADER,EXTENDED_METADATA, andKEYFORMAT;APPEARANCEKEYS,FACETKEYS, andRENDITIONS;- CSI headers, TLV metadata, internal links, and common
RAWD,CELM, andCOLRpayloads.
The decoder supports:
- LZFSE
bvx2, rawbvx-, and embedded LZVNbvxnstreams; - raw LZVN instruction streams;
- KCBC horizontal bitmap chunks and row-padding removal;
- Deepmap2 default, lossless, and palette encodings;
- ARGB/BGRA and GA8 pixels;
- packed-image links, including lower-left coordinate conversion and atlas cropping.
Original RAWD files such as SVG and JPEG are copied byte-for-byte. Compiled bitmaps are re-encoded as PNG; their original PNG compression, ancillary metadata, and source group hierarchy are not present in the CAR and cannot be reconstructed exactly.
This project benefited from the following public research and reference implementations:
- Timac — Reverse engineering the
.carfile format, the foundational walkthrough of BOM and compiled Asset Catalog structures. - DBG.RE — A Deep Dive into Apple's
.carFile Format, especially the CSI, internal-link, compression, and KCBC format analysis. - Apple — LZFSE reference implementation, used as the authoritative algorithm reference for the pure-Go LZFSE and LZVN decoders.
Many thanks to the authors and maintainers for publishing their research and source code. carfile-go is an independent pure-Go implementation and does not copy or invoke Apple's private CoreUI framework.