This page is the technical reference for BetterZip 6’s format definition. If you want to add support for a new archive format or expose extra options of an existing one, this is the schema. For a more gentle introduction see Custom Format Definitions.
BetterZip Format Definitions
BetterZip uses JSON files to describe archive formats and the interaction between external tools and BetterZip. Built-in formats ship inside the app; you can add your own through the Helpers tab in the Settings window. Each JSON file defines how BetterZip lists, extracts, compresses, and tests a particular archive type.
This document explains every field you can use in a format definition.
Minimal Example
A read-only format that can only be opened (not created):
{
"class": "xad",
"format": "sit",
"name": "StuffIt Archive",
"tag": 110,
"extensions": ["sit", "sitx"]
}
Full Example
A format that supports creating, extracting, testing, and splitting:
{
"class": "tar",
"format": "tzst",
"name": "TAR Format, Zstandard compressed (tzst)",
"tag": 9,
"builtIn": true,
"installPath": "$BUNDLE_HELPERS/zstd",
"canSave": true,
"canUpdate": false,
"magicBytes": [
{
"start": 0,
"hex": true,
"bytes": "28B52FFD"
}
],
"extensions": ["tzst", "zst"],
"extract": {
"weight": 14
},
"compress": {
"factors": [
{
"standardTitleTag": 1,
"position": 1,
"weight": 5,
"options": ["-1"]
},
{
"standardTitleTag": 2,
"position": 2,
"weight": 6,
"options": []
},
{
"standardTitleTag": 3,
"position": 4,
"weight": 75,
"options": ["-19"]
}
]
}
}
Top-Level Fields
Identity
| Field | Type | Required | Description |
|---|---|---|---|
class |
String | Yes | Determines which handler processes this format. See Handler Classes. |
format |
String | Yes | Internal format identifier passed to command-line tools (e.g. "zip", "7z", "tgz"). |
name |
String | Yes | Display name shown in menus and the save panel. |
tag |
Integer | Yes | Unique numeric identifier. Used internally to reference formats in presets and scripts. Pick a number not already in use. |
builtIn |
Boolean | No |
true for formats that ship with BetterZip. Leave out or set to false for your own definitions. |
comment |
String | No | Freeform note or URL for your own reference. Not shown in the UI. |
iconName |
String | No | Name of a custom icon (without extension) to display for this format. |
Capabilities
All of these default to false if omitted.
| Field | Type | Description |
|---|---|---|
canSave |
Boolean | Can BetterZip create archives in this format? |
canUpdate |
Boolean | Can files be added to or removed from an existing archive? |
canTest |
Boolean | Can archive integrity be verified? |
canSplit |
Boolean | Can archives be split into multiple volumes? |
canWriteComments |
Boolean | Can the archive store a text comment? |
canFilterRsrc |
Boolean | Can macOS resource fork files (._*, __MACOSX) be filtered out? Defaults to true unless explicitly set to false. |
canSaveWithForks |
Boolean | Can the format preserve macOS resource forks natively? |
canOnlyCompressFolders |
Boolean | Set to true if the format can only compress entire folders, not individual files (e.g. disk images). |
numberedParts |
Boolean | Enables the name.1.ext, name.2.ext, … multi-volume naming scheme for this format. Only set this if the format’s tools actually produce this pattern. Most formats use other split naming conventions (.001, .z01, .part001.rar) that are detected automatically. |
Format Behavior
These fields configure format-specific behavior. All are optional.
| Field | Type | Default | Description |
|---|---|---|---|
rsrcFolder |
String | null |
Name of the resource fork folder inside archives (e.g. "__MACOSX"). |
defaultExtension |
String | from format
|
Override for the default file extension when creating new archives. |
encryptionDetection |
Array | [] |
Patterns for detecting encryption from 7z listing output. See Encryption Detection. |
threadOption |
String | null |
Template for the tool’s thread-count flag, using the $THREADS placeholder (e.g. "-mmt=$THREADS", "--threads=$THREADS"). Applied during extraction and other non-compression operations. For compression, $THREADS is typically placed inside factor options arrays instead. |
Tool Paths
These tell BetterZip which command-line tool to invoke.
| Field | Type | Description |
|---|---|---|
installPath |
String | Path to the tool used for all operations. |
installPathList |
String | Override for listing only. Falls back to installPath. |
installPathExtract |
String | Override for extraction only. Falls back to installPath. |
installPathCompress |
String | Override for compression only. Falls back to installPath. |
Path variables you can use:
| Variable | Expands to |
|---|---|
$BUNDLE_HELPERS |
The Helpers folder inside the BetterZip app bundle |
$APP_SUPPORT |
~/Library/Application Support/com.macitbetter.betterzip |
If the tool is installed in a standard location you can use an absolute path like /usr/local/bin/lz4.
File Type Detection
BetterZip identifies archive types in two steps: first by checking magic bytes at specific offsets in the file, then by falling back to the filename extension.
magicBytes
An array of byte patterns to check. If any pattern matches, the file is recognized as this format.
"magicBytes": [
{
"start": 0,
"hex": true,
"bytes": "504B0304"
}
]
| Field | Type | Description |
|---|---|---|
start |
Integer | Byte offset in the file where the check begins. |
hex |
Boolean |
true if bytes is a hex string, false if it is plain ASCII. |
bytes |
String | The byte sequence to match. Hex example: "504B0304" (ZIP signature). ASCII example: "ustar" (TAR). |
extensions
An array of filename extensions (without the dot) that identify this format:
"extensions": ["zip", "jar", "war", "cbz"]
Operation Dictionaries
Format-specific settings for listing, extracting, compressing, and testing are grouped under four optional top-level keys: list, extract, compress, and test. Only include the ones you need.
extract
"extract": {
"weight": 17
}
| Field | Type | Description |
|---|---|---|
weight |
Number | Relative extraction speed. Higher values mean slower extraction. Used to estimate progress. If omitted, defaults to 28. |
compress
Contains compression levels, encryption options, and an optional label override.
"compress": {
"compressionTitle": "Compression:",
"factors": [ ... ],
"encryptionMethods": [ ... ]
}
| Field | Type | Description |
|---|---|---|
compressionTitle |
String | Label shown above the compression level popup in the save panel. Defaults to “Compression:” if omitted. Use a custom label when the choices are not traditional compression levels (e.g. “Image type/compression” for DMG). |
factors |
Array | Compression level presets. See Compression Factors. |
encryptionMethods |
Array | Encryption options. See Encryption Methods. |
list
test
These are reserved for user-defined formats (class "user") that need custom command-line options for testing. See User-Defined Formats.
Compression Factors
Each entry in the factors array represents one compression level shown in the save panel dropdown.
{
"standardTitleTag": 2,
"position": 3,
"weight": 12,
"options": ["-mx=5"]
}
| Field | Type | Description |
|---|---|---|
standardTitleTag |
Integer | References a built-in label. See the table below. Use this when a standard label fits. |
title |
String | Custom label text. Use instead of standardTitleTag when you need a non-standard name (e.g. "Read/write image"). |
tag |
Integer | Numeric identifier for this level. Required when using a custom title instead of standardTitleTag. |
position |
Integer | Display order in the popup. 1 = first, 2 = second, etc. |
weight |
Number | Relative compression speed. Higher = slower. Used for progress estimation. |
options |
Array | Command-line flags passed to the compression tool for this level. |
Standard Compression Tags
| Tag | Label |
|---|---|
| 0 | No compression |
| 1 | Fast, but larger archives |
| 2 | Normal |
| 3 | Best, but slower operation |
| 4 | High, but slower operation |
| 5 | Best (solid, slow extraction) |
These labels are automatically localized into all supported languages.
Encryption Methods
Each entry in the encryptionMethods array represents one encryption option in the save panel.
{
"standardTitleTag": 2,
"position": 2,
"options": ["-mem=AES256", "-p$PASSWORD"]
}
The fields are the same as for compression factors. Use $PASSWORD as a placeholder in options – BetterZip replaces it with the actual password at runtime.
Standard Encryption Tags
| Tag | Label |
|---|---|
| 0 | Not encrypted |
| 1 | Weak (PKZip2 compatible) |
| 2 | Strong (AES-256) |
| 3 | Strong (AES-256) with header encryption |
| 4 | macOS default (AES-128) |
Handler Classes
The class field determines which handler processes the format. Each handler has different capabilities.
| Class | Description | Mechanism |
|---|---|---|
tar |
TAR-based formats (tar, tgz, tbz, txz, tzst, tbr). Can pipe through an external compressor. | Shells out to gnutar + compressor |
zip |
ZIP archives. | Shells out to 7za
|
7Zip |
7-Zip format (7z). | Shells out to 7za
|
7ZipBase |
Other formats handled by 7za (CAB, NSIS, WIM, ARJ, CHM). | Shells out to 7za
|
split |
Split archive files (.001, .002, …). | Shells out to 7za
|
rar |
RAR archives (read-only unless RAR command-line tools are installed). | In-process via unrar library |
xar |
XAR, XIP, PKG archives. | In-process via xar library |
hdi |
Apple disk images (DMG, ISO). | Shells out to /usr/bin/hdiutil
|
xad |
Read-only formats handled by the XADMaster framework (SIT, PDF, HQX, many legacy formats). | In-process via XADMaster.framework |
mime |
TNEF / winmail.dat. | In-process via TNEF.framework |
user |
Fully user-configurable. All operations are defined through the JSON. | Shells out to specified tool |
The classes zip, 7Zip, 7ZipBase, and split all use the same unified handler internally. Behavioral differences (encryption, multi-part handling, etc.) are configured through the JSON fields.
7-Zip Base Defaults (7ZipBase.json)
All formats handled by the 7za tool (zip, 7Zip, 7ZipBase, split) automatically inherit shared defaults from 7ZipBase.json. This base config provides settings that are common to all 7za-based formats:
-
installPath– path to the7zabinary -
canTest– all 7za formats support integrity testing -
errors– standard error patterns for password prompts, broken archives, and permission errors
Individual format definitions override any field they specify – the base config only fills in missing values.
You can edit the base config through BetterZip > Settings > Helpers (it appears as “7-Zip Base Defaults”). Changes apply to all 7za-based formats that do not override the changed field. This is especially useful for adding custom error patterns that should apply across all 7za formats.
For most custom formats, use class "tar" (if your format is tar-based with a compressor) or "user" (for anything else).
User-Defined Formats
When using class "user", you have full control over the command-line options for every operation.
Operation Options
The list, extract, compress, and test dictionaries can each contain:
| Field | Type | Description |
|---|---|---|
options |
Array | Command-line arguments passed to the tool. Supports placeholder substitution (see below). |
installPath |
String | Override for this operation only. Falls back to installPath on top level. |
stdioPassword |
Boolean | If true, the password is piped to the tool via stdin instead of passed as a command-line argument. When set, $PASSWORD placeholders in options are not expanded. Can also be set at the top level as a default for all operations. |
Security and shell safety
options values are passed to the tool as command-line fragments. Use only real flags, values, and the documented placeholders ($THREADS, $FACTOR, $PASSWORD, …). Do not put shell metacharacters – ` $ ; | & < > ( ) " ' \ – into an option value.
The TAR-family handlers (tgz, txz, tzst, tbz, tbr, and tar with a custom compressor) build a shell pipeline. To prevent command injection, any flag/option value that still contains a shell metacharacter after placeholder expansion is rejected at runtime: the operation is aborted and the offending value is logged, rather than executed. Legitimate options (-c9, --threads=4, -mx=9) never trigger this.
Tool paths (installPath) and the file names inside the archive are quoted automatically, so they may safely contain spaces, quotes, and other special characters – you do not need to (and should not) quote them yourself.
Placeholders
Placeholders in option strings are substituted at runtime. Available placeholders depend on the operation.
Common Placeholders (all operations)
| Placeholder | Description |
|---|---|
$ARCHIVE |
Full path to the archive file. Must be a standalone option string (not embedded in other text). |
$PASSWORD |
The archive password. Can be embedded in an option string (e.g. "-p$PASSWORD"). Not expanded when stdioPassword is true. |
$THREADS |
Replaced with the user’s thread-count preference (from Settings > Advanced). Can be embedded in an option string (e.g. "-mmt=$THREADS", "--threads=$THREADS", "-p$THREADS"). When the preference is set to Auto (0), the entire option containing $THREADS is dropped – the tool uses its own default. |
Extract Placeholders
| Placeholder | Description |
|---|---|
$LISTFILE |
Path to a temporary file containing the list of items to extract (one per line). The placeholder is replaced inline within the option string (e.g. "@$LISTFILE"). |
$FILES |
Special repeating placeholder. The option string containing $FILES is split by spaces. The resulting group of arguments is repeated once per file to extract: in each repetition, the component containing $FILES is replaced with the file path, and other components are passed through unchanged. Example: "-g $FILES" with files a.txt and b.txt produces -g a.txt -g b.txt. |
Compress Placeholders
| Placeholder | Description |
|---|---|
$FACTOR |
Replaced with the options array of the selected compression factor (looked up by tag from factors). |
$ENCRYPTION |
Replaced with the options array of the selected encryption method (looked up by tag from encryptionMethods). Only expanded when a password is set. $PASSWORD inside encryption options is also expanded. |
$SPLIT |
Replaced with the splitOption string (see below), with $VOLUME_SIZE substituted with the calculated volume size in bytes. Only expanded when the user has configured a volume size. |
$LISTFILE |
Same as in extract. |
$FILES |
Same repeating behavior as in extract. When no specific files are given but a folder is being compressed, $FILES is replaced with ".". |
Compress-Specific Fields
| Field | Type | Description |
|---|---|---|
splitOption |
String | Template for volume splitting. Must contain $VOLUME_SIZE which is replaced with the volume size in bytes. Spaces split this into separate arguments. Example: "-s $VOLUME_SIZE" becomes ["-s", "1048576"]. |
compressionTitle |
String | Custom label shown above the compression level popup in the save panel. Defaults to “Compression:” if omitted. |
List-Specific Fields
| Field | Type | Description |
|---|---|---|
headerLines |
Integer | Number of lines to skip at the start of the tool’s output before parsing items. |
footerLines |
Integer | Number of lines to skip at the end of the tool’s output. |
parser |
Object | Defines how to parse the tool’s output into archive items. Contains regex and template. |
parser.regex |
String | Regular expression with capture groups applied to each output line. |
parser.template |
String | Tab-separated key=value template using $1, $2, etc. for capture group references. Supported keys: path, attr, unco (uncompressed size), comp (compressed size), time. |
Example:
"list": {
"headerLines": 2,
"footerLines": 0,
"options": ["-l", "$ARCHIVE"],
"parser": {
"regex": "(?:\\[[^\\]]*\\])+\\s*([-dlrwxsStT]{10})\\s+\\S+\\t\\S+\\t(\\d+)\\s+(\\S+)\\t([^\\t]+)\\t(.+)",
"template": "path=$5\tattr=$1\tunco=$2$3\tcomp=0\ttime=$4"
}
},
"extract": {
"weight": 18,
"options": ["-x", "$ARCHIVE", "-g $FILES"]
},
"compress": {
"splitOption": "-s $VOLUME_SIZE",
"options": ["-c", "$ARCHIVE", "$FACTOR", "$ENCRYPTION", "$SPLIT", "-g $FILES"],
"factors": [ ... ],
"encryptionMethods": [ ... ]
},
"test": {
"options": ["-t", "$ARCHIVE"]
}
Error Handling
User-defined formats can include an errors array to map tool output to meaningful error messages. The errors array can appear in two places:
- Top level – applies to all operations (list, extract, test, compress).
-
Inside an operation dictionary (
list,extract,test,compress) – applies only to that operation.
If both exist, the operation-specific errors array is used exclusively – the two arrays are not combined.
"errors": [
{
"recognize": ["Wrong password"],
"standardError": "password",
},
{
"recognize": ["Sub items Errors", "Headers Error", "ERRORS:"],
"standardError": "broken"
},
{
"recognize": "ERROR: Operation not permitted",
"standardError": "permission"
},
{
"recognize": "ERROR: Need more memory",
"userMessage": "The operation needs more memory to succeed.",
"continue": false
}
]
| Field | Type | Description |
|---|---|---|
recognize |
String or Array | One or more strings to look for in the tool’s output. If any string is found, this error rule matches. |
standardError |
String | Standard error conditions: "password", "broken", or "permission". |
userMessage |
String | When this is not a standard error condition, this message is shown to the user. |
continue |
Boolean | If true, the alert panel with the userMessage has a continue button and the operation can continue after displaying the message. |
Encryption Detection
The encryptionDetection array tells BetterZip how to detect encryption from 7z listing output. Each entry matches a pattern in the compression method string reported by 7za.
"encryptionDetection": [
{ "pattern": "ZipCrypto", "method": 1 },
{ "pattern": "AES", "method": 2 }
]
| Field | Type | Description |
|---|---|---|
pattern |
String | Substring to look for in the item’s method string. |
method |
Integer | Encryption method value: 1 = weak, 2 = strong. |
headerEncryptionMethod |
Integer | If present, this value is used instead of method when the archive listing itself is encrypted (header encryption). Typically 3. |
For 7z archives with optional header encryption:
"encryptionDetection": [
{ "pattern": "7zAES", "method": 2, "headerEncryptionMethod": 3 }
]
Multi-Volume Naming Schemes
BetterZip automatically detects multi-volume archives using these naming patterns:
| Scheme | Pattern | First Volume | Handler |
|---|---|---|---|
| Generic split |
name.ext.001, .002, … |
.001 |
Detected by numeric extension; scans .001–.999
|
| Numbered parts |
name.1.ext, name.2.ext, … |
name.1.ext |
Only for formats with "numberedParts": true
|
| New RAR |
name.part001.rar, .part002.rar, … |
.part001.rar |
Detected by part prefix in second-to-last extension |
| Old RAR |
name.rar, name.r01–.r99, .s00–.s99, .t00–.t99
|
.rar |
Detected by [r-t]## extension pattern |
| WinZip |
name.z01–.z99, name.zip
|
.z01 |
Detected by z## extension pattern; .zip is the final part |
When a user opens a later volume, BetterZip automatically redirects to the first volume and scans for all parts.
The numberedParts scheme requires an opt-in flag because name.1.ext patterns are common in non-archive files (e.g. report.1.pdf). Only enable it for formats whose tools actually produce this naming convention.
Tips
- Tag numbers: Pick a tag number that is not already used. Tag numbers below 1000 are reserved. Use numbers above for custom formats.
-
Testing your format: After adding a JSON file in BetterZip > Settings > Helpers, your format should be recognized when opening archives and it should appear in the save panel’s and save preset configuration’s format drop-down (if
canSaveistrue). -
Compression factors: You need at least one entry in
factorsif your format supports saving. If the format has only one compression level, include a single entry. - Magic bytes: If you do not know the magic bytes for your format, leave the array empty and rely on file extensions only.
- Tool path: Make sure the tool is installed and the path is correct. BetterZip will show the format as unavailable if it cannot find the tool.