Technical Architecture & System Overview
DashMail is a native Windows email client built on WinUI 3. It uses a local-first architecture — all email is stored in a SQLite database on the Windows host. The SMB network share is used only as a handoff zone: Mutt deposits incoming messages and DashMail queues outgoing ones.
Current state of the DashMail prototype — built in React/JSX as a visual specification for the WinUI 3 native build.
Login screen — 50/50 split layout. Paper airplane logo + DashMail wordmark on dark left panel, mountain background photo on rounded right panel. Password-only authentication auto-matches account profile.
Main email client — three-pane layout: account/folder sidebar (left), email list with search (centre), reading pane with full email + attachments (right). Resizable panels, sign out button, connection status bar.
DashMail follows the local-first (Option B) architecture. The SMB share acts only as a message handoff point — not a working mailstore.
Each email on the SMB share is a folder containing these files. The parsing rules are deliberately simple:
| File | Role | Action |
|---|---|---|
_headers_ | RFC 2822 email headers | Parse: From, To, Subject, Date, Message-ID, Spam-Score |
textfile0 | Email body — plain text | Store as body_text in SQLite, render in reading pane |
| Everything else | Attachment | Copy to local attachments cache, register in DB |
| Header Field | Example Value | UI Usage |
|---|---|---|
From: | Charleen Roland <charroland@zoominternet.net> | Sender name + avatar initials |
Delivered-To: | sales@littlecreekdoor.com | Account routing |
Subject: | Charleen and Rich Roland | Email list + reading pane title |
Date: | Sat, 23 May 2026 10:33:48 -0400 | Timestamp display |
Message-ID: | <1076592763...@zoominternet.net> | Unique key / deduplication |
X-Spam-Status: | No, score=1.7 | Spam indicator in UI |
Thread-Topic: | Charleen and Rich Roland | Thread grouping |
\\mailserver\mail\.Mails\[account]\inbox\ containing _headers_, textfile0, and any attachments.FileSystemWatcher or 60-second timer._headers_ is parsed with MimeKit HeaderList — From, To, Subject, Date, Message-ID, Spam-Score extracted.textfile0 is read as the email body. All other files in the folder are copied to the local attachment cache at %LOCALAPPDATA%\DashMail\attachments\[guid]\.mail.db. FTS5 full-text search index is updated automatically.\\mailserver\mail\.Mails\[account]\out\[timestamp]-[guid]\_headers_: From, To, Subject, Date, Message-ID, X-Mailer: DashMail 1.0.textfile0: the plain text message body.out\, transmits via SMTP, removes the folder.| Folder | Managed by | DashMail action |
|---|---|---|
inbox\ | Mutt (writes incoming message folders) | Reads _headers_ + textfile0, checks Message-ID against SQLite, imports unseen — never deletes |
out\ | DashMail (writes outgoing message folders) | Writes new _headers_ + textfile0 folder; Mutt picks up and sends |
sent\ | Mutt (optional mirror) | Not modified by DashMail |
drafts\ | — | Not used on SMB; drafts live in local SQLite only |
archive\ | — | Not used on SMB; archive lives in local SQLite only |
trash\ | — | Not used on SMB; deleted emails are flagged locally only |
| Layer | Technology | Purpose |
|---|---|---|
| UI Framework | WinUI 3 / Windows App SDK 1.6+ | Native Windows controls, Fluent Design, Mica material |
| Language | C# 12 | All app logic, services, ViewModels |
| UI Pattern | MVVM (CommunityToolkit.Mvvm) | Data binding, commands, ObservableCollection |
| Header Parsing | MimeKit / MailKit | Parse RFC 2822 _headers_ files, write outgoing headers |
| Email Body | Plain text (textfile0) | Read as-is; write plain text for outgoing mail |
| Local Database | SQLite + FTS5 (Microsoft.Data.Sqlite) | All email storage + instant full-text search |
| SMB Access | Native Windows UNC paths | Read inbox\, write out\ — no extra library needed |
| File Watching | FileSystemWatcher (.NET) | Real-time detection of new message folders on SMB |
| Reading Pane | RichTextBlock / WebView2 | Render textfile0 body |
| Notifications | AppNotificationBuilder | Windows Action Center toasts for new mail |
| Packaging | MSIX | Installer, auto-update, Windows Store compatible |
| IDE | Visual Studio 2022 | Build, XAML designer, debugger |
_headers_ parser, textfile0 reader, attachment cache · 2 days_headers_ + textfile0 to SMB out\ · 2 days
DashMail stores all email, settings, and metadata in a local SQLite database
(mail.db). The SMB share is never modified during backup or restore.
Users can schedule automatic backups, choose between Smart / Always Full / Always Incremental modes,
configure multiple backup destinations, and restore from any point in the backup chain.
Each backup is a timestamped ZIP archive containing:
| Mode | Behaviour | Storage impact |
|---|---|---|
| Smart (recommended) | Daily incrementals; auto-resets to full every 30 days or 10 incrementals | Low — incremental ZIPs are typically < 2 MB |
| Always full | Every scheduled run produces a complete backup | High — each run copies entire database |
| Always incremental | Only changes since last backup are captured | Very low — requires a full backup to exist first |
The emails.modified_at column is updated automatically by a SQLite trigger on every
UPDATE (read/unread, starred, moved, label changes). At backup time, DashMail queries
SELECT * FROM emails WHERE modified_at > :last_backup_ts and serialises the results
as INSERT OR REPLACE statements into email_changes.sql.
base_id for all subsequent incrementals.base_id = <full GUID> in its manifest so restore knows the required base.mail.db replaces the live database via SQLite online backup API.email_changes.sql in the chain is executed in date order up to the selected restore point.