Lightweight VSCode extension that previews email message files (.eml and .msg) directly inside the editor as a rendered email view, with inline images embedded.
Supported features
- EML rendering (
.eml): parses RFC 822 messages, renders the HTML (or plain-text fallback) body in a webview-based custom editor - MSG rendering (
.msg): parses Outlook.msgfiles using the maintained@kenjiuno/msgreader, with RTF body fallback (@kenjiuno/decompressrtf+rtf-stream-parser) and charset-aware HTML decoding viaiconv-lite - Default editor: registered as the default editor for
.emland.msg, so a single click opens the rendered view - Inline image embedding:
cid:references in HTML emails are resolved against the message's MIME parts and embedded asdata:URLs so logos and signature images render correctly - Attachment grid with Save / Save All: every attachment (including inline images) is listed between the headers and body with a thumbnail (or extension badge), MIME type, and size; each row has a
Save…button that opens the VS Code save dialog, and aSave All…button writes the entire set into a chosen folder (with automatic name deduplication) - Header pane: From / To / Cc / Bcc / Date / Subject rendered in a compact, themed header table
- Sandboxed body: the email body is rendered inside a sandboxed iframe via
srcdocso the email's own<html>/<head>/charset/styles cannot poison the surrounding shell layout; an outer height-fitter keeps the iframe sized to its content - Theme aware: header, attachment block, separators, body links, and blockquote borders use VSCode CSS variables, so it follows the active light/dark theme
Current scope intentionally focuses on read-only preview. Reply/forward/edit are out of scope.
Architecture
src/extension.ts: VSCodeCustomReadonlyEditorProviderregistration, header/body/attachments rendering,cid:→data:inliningsrc/parse.ts: dispatch between EML and MSG loaders based on file extensionsrc/loadEml.ts: EML parsing viamailparsersrc/loadMsg.ts: MSG parsing viamsgreadersrc/EmailFileSystemProvider.ts: virtual filesystem foreml:/msg:URIs so attachments are browsable
Install dependencies
npm install
Build
npm run compile
Run in VSCode (manual review)
- Open this repository in VSCode.
- Run
npm run compile. - Press
F5to launch an Extension Development Host. - In the new window, open an
.emlor.msgfile (samples are underdemo/). - Verify:
- The file opens in a rendered email view (not as raw text).
- From / To / Subject appear at the top.
- Inline images in HTML emails render in place.
- Non-inline attachments appear in the Attachments block.
Package and install in local VSCode
- Install VSCE:
npm install -D @vscode/vsce - Create VSIX:
npx vsce package - Install VSIX:
code --install-extension email-reader-0.1.1.vsix
Release Notes
0.1.1
- Attachment grid with Save / Save All: every attachment — including inline images — is now listed in a card grid between the headers and the body. Each card shows a thumbnail (or extension badge for non-images), MIME type, size, and an
inlinetag where applicable, with a per-attachmentSave…button. When there is more than one attachment, aSave All…button writes the whole set into a chosen folder, deduplicating filenames automatically (name (1).png,name (2).png, …). - Save dialogs default to the email file's own directory.
- Wired via webview
postMessage/onDidReceiveMessage; writes go throughvscode.workspace.fs.writeFile, so no network calls are involved.
0.1.0
- Initial release under the
Email Readername (forked fromEmail Viewer). - Default editor: registers
.emland.msgas default custom editors viaCustomReadonlyEditorProvider, fixing the previous breakage where opening an email file did nothing on current VSCode. - Inline images:
cid:references in HTML email bodies are resolved against the message's MIME parts and inlined asdata:URLs, so logos and signature images render correctly. - Theme-aware layout: header table, attachment block, separators, links, and blockquotes use VSCode CSS variables for proper light/dark theme integration; image and table widths are constrained to the viewport.
- Attachment list: non-inline attachments render in a dedicated block with size and clickable links; inline parts that already appeared in the body are no longer listed twice.