Convert a Threema iOS chat export into a self-contained semantic HTML archive.
Supports two export formats produced by the Threema iOS app: the per-conversation encrypted ZIP export and the all-chats JSON export.
- Overview
- Features
- Quick start
- Installation
- Exporting a chat
- Locales
- Exit codes
- Limitations
- Contributing
- About the format
chex converts a decrypted Threema iOS chat export into a portable HTML archive.
The generated archive consists of:
index.html— complete conversation in chronological order, with all CSS inlined and no external dependencies.media/— copies of media files found in the export.
The output renders correctly in any modern web browser without requiring JavaScript, network access, or additional assets.
- renders text messages, quoted messages, locations, and polls
- renders images, video, audio and file attachments
- renders emoji reactions (JSON format only)
- renders poll vote attribution — who voted for what (JSON format only)
- explicitly reports files referenced by the export but missing from the directory instead of silently omitting them
Supported locales:
Bulgarian, Czech, German, English, Spanish, French, Swiss German, Italian, Japanese, Korean, Dutch, Polish, Brazilian Portuguese, Slovak, Turkish, Ukrainian, Simplified Chinese and Traditional Chinese.
Supported platforms:
- Linux
- macOS
- Windows
Native executable. No runtime or external dependencies required.
chex is not affiliated with or endorsed by Threema.
Threema is a registered trademark of Threema GmbH.
- Export a chat from Threema.
- Install
chex. - Decrypt the exported ZIP archive (per-conversation format only — the all-chats export is not encrypted).
- Run
chexpointing at the export directory. The format is detected automatically.
Per-conversation export:
chex Threema_Export_20260630
All-chats export — pass a single chat subdirectory:
chex "Threema_Export_ABC3CKP8_2026-07-08/Contact Name ID AB12CD34"
Unless --output is specified, chex creates the output directory next to the input:
~/Threema_Export_20260630
~/Threema_Export_20260630-chex-output
Finally, open index.html in any browser.
Using curl:
curl -fL --create-dirs -o ~/.local/bin/chex https://codeberg.org/duras/chex/releases/download/v0.2.0/chex-linux-x86_64
chmod +x ~/.local/bin/chexUsing wget:
mkdir -p ~/.local/bin
wget -O ~/.local/bin/chex https://codeberg.org/duras/chex/releases/download/v0.2.0/chex-linux-x86_64
chmod +x ~/.local/bin/chexcurl -fL --create-dirs -o /usr/local/bin/chex https://codeberg.org/duras/chex/releases/download/v0.2.0/chex-macos-arm64
chmod +x /usr/local/bin/chexIf macOS blocks the unsigned executable:
xattr -d com.apple.quarantine /usr/local/bin/chexcurl -L \
https://codeberg.org/duras/chex/releases/download/v0.2.0/chex-macos-x86_64 \
-o /usr/local/bin/chex &&
chmod +x /usr/local/bin/chexIf macOS blocks the unsigned executable:
xattr -d com.apple.quarantine /usr/local/bin/chex-
Download chex-windows-x86_64.exe
-
Rename it to
chex.exeand move it to a folder of your choice, for exampleC:\Tools\chex.exe. -
Add that folder to your PATH:
- Open Start, search for "environment variables", and open "Edit the system environment variables"
- Click Environment Variables
- Under User variables, select Path and click Edit
- Click New and enter
C:\Tools - Click OK on all dialogs
-
Open a new PowerShell or Command Prompt window and verify:
chex --versionchex --versionIf ~/.local/bin is not in your PATH, add this to your shell
configuration file (~/.bashrc, ~/.zshrc, etc.):
export PATH="$HOME/.local/bin:$PATH"Threema iOS offers two ways to export conversations. Both produce a ZIP archive, but the format, scope, and encryption differ.
Export a single conversation from within the chat: tap the contact or group name → Export Chat.
- Exports one chat at a time
- AES-encrypted ZIP — must be decrypted before running
chex - Contains
messages.txt(locale-dependent text format) and media files at the root
After decryption, pass the directory to chex:
chex Threema_Export_20260630
Export all conversations at once: Settings → Storage Management → Manage All Chats → Chat-Export.
- Exports all conversations in a single unencrypted ZIP
- No decryption required
- Contains one subdirectory per conversation, each with a
MessagesJSON file and aMedia/subdirectory
After unpacking, pass a single chat subdirectory to chex:
chex "Threema_Export_ABC3CKP8_2026-07-08/Contact Name ID AB12CD34"
The all-chats format contains richer data than the per-conversation format: emoji reactions, poll vote attribution, and machine-readable timestamps are all present. The format is detected automatically — no flag is needed.
For the per-conversation format, chex normally detects the export locale
automatically from the content of messages.txt.
If detection fails, it exits with code 3.
List supported locales:
chex --list-locales
Specify the locale explicitly:
chex --locale de ~/Exports/Threema_Chat
The all-chats JSON format does not require locale detection — it is
language-independent. --locale is accepted but optional for JSON exports.
See chex.1 for the complete command-line reference.
| Code | Meaning |
|---|---|
| 0 | Success. Prints chex: wrote {output_dir}/index.html. |
| 1 | Invalid or missing command-line arguments. |
| 2 | Invalid input (not a directory, missing export file, invalid UTF-8). |
| 3 | Locale detection failed. Rerun with --locale. |
| 4 | Output error (cannot create the output directory or write index.html). |
messages.txt is not a structured data format. It is localized human-readable
text whose exact syntax depends entirely on the iOS locale used during export.
The export also lacks important metadata:
- locale identifier, export format version, conversation name, participant list
- Threema IDs (only display names are present)
The export format does not contain:
- emoji reactions or GIF messages
- poll votes (questions and choices are preserved)
- message edit history or deleted-message markers
- The device owner's Threema ID appears as a raw ID in poll vote attribution.
- Duplicate poll entries (a known quirk of the format) are deduplicated heuristically and may not always collapse correctly.
- Non-NFC Unicode text in filenames is preserved as-is.
- Files not downloaded to the device at export time are noted as absent.
Bug reports and feature requests: Codeberg issues.
Pull requests are welcome. A PR should pass dune test on all targeted platforms before submission.
Threema has not published a specification for either the encrypted ZIP export format or the JSON all-chats format, and has confirmed they have no plans to publish any.
The formats implemented by chex have been reconstructed from observed
exports and from the published source code of the Threema App for iOS (AGPL v3).
A detailed format specification is available in the repository as
threema-ios-export-format.md.