Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chex

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.

Table of contents


Overview

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.

Features

  • 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.


Quick start

  1. Export a chat from Threema.
  2. Install chex.
  3. Decrypt the exported ZIP archive (per-conversation format only — the all-chats export is not encrypted).
  4. Run chex pointing 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.


Installation

Linux (x86_64)

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/chex

Using 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/chex

macOS (Apple Silicon)

curl -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/chex

If macOS blocks the unsigned executable:

xattr -d com.apple.quarantine /usr/local/bin/chex

macOS (Intel)

curl -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/chex

If macOS blocks the unsigned executable:

xattr -d com.apple.quarantine /usr/local/bin/chex

Windows (x86_64)

  1. Download chex-windows-x86_64.exe

  2. Rename it to chex.exe and move it to a folder of your choice, for example C:\Tools\chex.exe.

  3. 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
  4. Open a new PowerShell or Command Prompt window and verify:

chex --version

Verify (Linux and macOS)

chex --version

If ~/.local/bin is not in your PATH, add this to your shell configuration file (~/.bashrc, ~/.zshrc, etc.):

export PATH="$HOME/.local/bin:$PATH"

Exporting a chat

Threema iOS offers two ways to export conversations. Both produce a ZIP archive, but the format, scope, and encryption differ.

Per-conversation export

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

All-chats export (JSON)

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 Messages JSON file and a Media/ 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.


Locales

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.


Exit codes

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).

Limitations

Per-conversation format

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

All-chats JSON format

  • 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.

Both formats

  • Non-NFC Unicode text in filenames is preserved as-is.
  • Files not downloaded to the device at export time are noted as absent.

Contributing

Bug reports and feature requests: Codeberg issues.

Pull requests are welcome. A PR should pass dune test on all targeted platforms before submission.


About the format

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.

About

Convert a Threema iOS chat export into a self-contained HTML archive.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages