Attachments are one of the oldest sources of friction in email clients. The file is there; getting it somewhere useful requires navigating a download dialog, finding the file in your Downloads folder, and switching to whatever app you actually need it in. More capable clients add virus scanning, cloud storage integration, or inline preview — each with its own tradeoffs in speed, privacy, and complexity.
cji.email’s approach is simpler and more honest: fetch attachment data on demand, preview what can be previewed in the app, and handle the security properties correctly by default.
Fetch on Demand, Not on Sync
Most email clients download the entire message body when a message is synced. This means attachment bytes are transferred whether or not you ever open the attachment — every PDF in every newsletter, every image in every marketing email, whether you read it or not.
cji.email’s Rust backend takes a different approach. When a message arrives, it fetches only the BODYSTRUCTURE — a lightweight IMAP metadata packet that describes what’s in the message without transferring the actual content. From BODYSTRUCTURE, cji.email knows:
- What attachments exist
- Their filenames and MIME types
- Their sizes
- The IMAP part identifiers needed to fetch each one
The attachment bytes are fetched only when you click Download or Preview. For inboxes with high attachment volume — invoices, reports, contracts — this significantly reduces sync bandwidth.
Downloading Files
Clicking Download on an attachment triggers a direct IMAP fetch using the message UID and the specific part identifier from BODYSTRUCTURE. The Rust backend decodes the bytes (Base64 or binary, as declared in the message), writes them to disk with async I/O, and notifies the UI when complete.
A configurable default download folder is set in Preferences. If none is configured, files land in the system Downloads directory. After a successful download, a notification shows the file path.
If a download fails — network timeout, IMAP error, encoding mismatch — a Retry button appears on the attachment row immediately. You don’t need to reload the message.
PDF Preview In-App
For PDF attachments, cji.email adds a Preview button alongside Download. Clicking it opens a full in-app modal that renders the PDF directly — no external viewer, no file saved to disk first, no switching applications.
This is useful for quickly verifying a document is the right file before deciding whether to save it, open it elsewhere, or archive the message. For people who receive high volumes of invoices or contracts, this removes a context switch from the review step.
Non-PDF files show only the Download option. Unsupported preview types are not offered as options, rather than being offered and then failing — the interface is honest about what it can do.
Security Details
Several security properties are built into the attachment system by default:
Filename sanitization. Every attachment filename is sanitized before it touches the filesystem. Path traversal sequences (../), null bytes, and characters illegal on Windows, macOS, or Linux are stripped or replaced. A filename crafted to write a file outside your download directory cannot succeed.
Credential handling. IMAP credentials used to fetch attachment bytes come from the OS keychain, not from in-memory state or config files. This is the same credential path used for all other IMAP operations.
Stable attachment identifiers. Attachments are identified using a hash derived from Content-ID or the combination of filename and size. This prevents “attachment not found” errors when the IMAP server renumbers part identifiers across sessions — a real-world IMAP server behavior that breaks naive implementations.
How This Fits the Workflow
cji.email organizes email as a Kanban board: IMAP folders as columns, messages as cards. Attachments integrate naturally. A card in a “To Review” column might be a contract PDF; a card in “Done” might be a signed return. Being able to preview and download directly from the message view keeps the workflow inside one interface without the context switch to a file manager or external viewer.
For teams that use cji.email alongside project management tools, this reduces the friction of moving files from email into other systems — one less reason to break flow.
What It Looks Like
Each attachment appears below the email body as a row with a file-type icon, filename, size, and Download/Preview buttons. A loading spinner appears during active downloads. Retry appears on error. The interface is minimal because the operation is simple — get the file, show it, or tell you it failed.