PHPackages                             cosmira/outlook-msg - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. cosmira/outlook-msg

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

cosmira/outlook-msg
===================

Read and write Microsoft Outlook MSG files in modern PHP

0.0.1(1mo ago)1381↑29.6%MITPHPPHP ^8.2CI passing

Since Apr 16Pushed 1mo agoCompare

[ Source](https://github.com/cosmira/php-msg)[ Packagist](https://packagist.org/packages/cosmira/outlook-msg)[ RSS](/packages/cosmira-outlook-msg/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)Dependencies (11)Versions (2)Used By (0)

Outlook MSG for PHP
===================

[](#outlook-msg-for-php)

Read and write Microsoft Outlook `.msg` files with a clean, fluent PHP API.

[![Tests](https://github.com/cosmira/php-msg/actions/workflows/phpunit.yml/badge.svg)](https://github.com/cosmira/php-msg/actions/workflows/phpunit.yml)[![Coding Guidelines](https://github.com/cosmira/php-msg/actions/workflows/code-style.yml/badge.svg)](https://github.com/cosmira/php-msg/actions/workflows/code-style.yml)[![Quality Assurance](https://github.com/cosmira/php-msg/actions/workflows/quality.yml/badge.svg)](https://github.com/cosmira/php-msg/actions/workflows/quality.yml)[![Code Coverage](https://github.com/cosmira/php-msg/actions/workflows/coverage.yml/badge.svg)](https://github.com/cosmira/php-msg/actions/workflows/coverage.yml)

It gives you a clean API for subjects, bodies, recipients, attachments, embedded messages, and raw MAPI properties, while still leaving the low-level pieces available when you need them.

Installation
------------

[](#installation)

```
composer require cosmira/outlook-msg
```

Why You'll Like It
------------------

[](#why-youll-like-it)

- Read Outlook `.msg` files into a friendly `Message` object
- Work with recipients and attachments through fluent collections
- Access subject, sender, headers, plain text, HTML, and RTF through expressive methods
- Create new `.msg` files with a clean builder API
- Attach regular files, inline files, and embedded `.msg` messages
- Preserve unmapped MAPI properties for round-trip scenarios
- Drop down to low-level compound file and RTF helpers when needed

Quick Start
-----------

[](#quick-start)

### Read a message

[](#read-a-message)

```
use Cosmira\OutlookMessage\Attachment;
use Cosmira\OutlookMessage\Message;

$message = Message::from(file_get_contents('example.msg'));

echo $message->subject();
echo $message->senderName();
echo $message->preferredBody();

$message
    ->attachments()
    ->filter(static fn (Attachment $attachment): bool => $attachment->isInline())
    ->each(static fn (Attachment $attachment): void => print $attachment->contentId());
```

### Create a message

[](#create-a-message)

```
use Cosmira\OutlookMessage\Message;

Message::make()
    ->from('Jane Doe', 'jane@example.com')
    ->to('Abigail', 'abigail@example.com')
    ->subject('Ship it')
    ->text('The plain text body')
    ->save('message.msg');
```

Reading Messages
----------------

[](#reading-messages)

```
use Cosmira\OutlookMessage\Message;

$message = Message::from(
    file_get_contents('example.msg')
);

echo $message->subject();
echo $message->senderName();
echo $message->senderEmail();
echo $message->preferredBody();
```

`Message::from()` and `Message::parse()` are equivalent. If you prefer, the original public properties are still available too.

Working With Recipients
-----------------------

[](#working-with-recipients)

```
use Cosmira\OutlookMessage\Recipient;

$message
    ->to()
    ->each(function (Recipient $recipient) {
        printf("%s \n", $recipient->name() ?? '', $recipient->email() ?? '');
    });

// Additional recipient groups:
$message->cc()
    ->each(static fn (Recipient $recipient): void => print $recipient->email());

// Formatted header lines from the original message:
echo $message->displayTo();
echo $message->displayCc();
echo $message->displayBcc();
```

Working With Attachments
------------------------

[](#working-with-attachments)

```
use Cosmira\OutlookMessage\Attachment;

$message
    ->attachments()
    ->each(static function (Attachment $attachment, int $index): void {
        $name = $attachment->fileName()
            ?? $attachment->displayName()
            ?? "attachment_{$index}";

        file_put_contents(__DIR__."/out/{$name}", $attachment->content() ?? '');
    });
```

### Inline attachments

[](#inline-attachments)

```
use Cosmira\OutlookMessage\Attachment;

$message
    ->attachments()
    ->filter(fn (Attachment $attachment) => $attachment->isInline())
    ->each(fn (Attachment $attachment) => print $attachment->contentId());
```

### Embedded `.msg` attachments

[](#embedded-msg-attachments)

```
use Cosmira\OutlookMessage\Attachment;

$message
    ->attachments()
    ->filter(fn (Attachment $attachment) => $attachment->embedded() !== null)
    ->each(fn (Attachment $attachment) => print $attachment->embedded()?->subject());
```

Bodies: HTML, Plain Text, and RTF
---------------------------------

[](#bodies-html-plain-text-and-rtf)

If you just want the best available body, use:

```
$body = $message->preferredBody();
```

If you want explicit access:

- `$message->body()` for plain text
- `$message->bodyHtml()` for HTML
- `$message->bodyRtf()` for decompressed RTF text

To work with raw compressed RTF payloads directly:

```
use Cosmira\OutlookMessage\Rtf\RtfDecompressor;

$rtf = RtfDecompressor::decompress($rawRtfBinary);
```

Creating Messages
-----------------

[](#creating-messages)

The smoothest writing experience is the fluent builder API:

```
use DateTimeImmutable;
use DateTimeZone;
use Cosmira\OutlookMessage\Message;

$draft = Message::make()
    ->from('Jane Doe', 'jane@example.com')
    ->subject('Ship it')
    ->text('The plain text body')
    ->html('The HTML body')
    ->withHeaders("X-App: outlook-msg\r\n")
    ->sentAt(new DateTimeImmutable('2024-01-01 10:00:00', new DateTimeZone('UTC')))
    ->to('Abigail', 'abigail@example.com')
    ->cc('Jess', 'jess@example.com')
    ->bcc('Ops', 'ops@example.com')
    ->attach('notes.txt', 'Remember the meeting at 11:40')
    ->attachInline('logo.png', $logoBinary, 'cid:logo');

$draft->save('message.msg');
```

You can still use `MessageBuilder::make()` and `MessageWriter::make()` directly if you prefer the lower-level writer entry points.

Named Payload Constructors
--------------------------

[](#named-payload-constructors)

If you want more control, you can build payload objects directly:

```
use Cosmira\OutlookMessage\Writer\AttachmentPayload;
use Cosmira\OutlookMessage\Writer\RecipientPayload;

$to = RecipientPayload::to('Abigail', 'abigail@example.com');
$cc = RecipientPayload::cc('Jess', 'jess@example.com');
$bcc = RecipientPayload::bcc('Ops', 'ops@example.com');

$file = AttachmentPayload::file('report.pdf', $pdfBinary);
$inline = AttachmentPayload::inline('logo.png', $logoBinary, 'cid:logo');
```

Embedded Message Attachments
----------------------------

[](#embedded-message-attachments)

You can attach one `.msg` inside another:

```
use Cosmira\OutlookMessage\Writer\MessageBuilder;

$nested = MessageBuilder::make()
    ->from('Nested Sender', 'nested@example.com')
    ->subject('Nested message')
    ->text('Hello from inside');

$draft = MessageBuilder::make()
    ->from('Parent Sender', 'parent@example.com')
    ->subject('Parent message')
    ->attachEmbedded($nested, 'forwarded.msg');
```

Raw MAPI Properties
-------------------

[](#raw-mapi-properties)

Known message fields are mapped onto friendly methods. Everything else can still be preserved and inspected through raw properties:

```
$raw = $message->rawProperties();
```

This is useful when:

- you need round-trip fidelity
- you care about Outlook-specific metadata not mapped by the library
- you want to inspect or write custom MAPI values

Low-Level APIs
--------------

[](#low-level-apis)

The package also includes lower-level APIs for advanced scenarios:

- `Cosmira\OutlookMessage\CompoundFile\CompoundFile` for CFBF/OLE storage access
- `Cosmira\OutlookMessage\Support\BinaryBuffer` for binary reads
- `Cosmira\OutlookMessage\Rtf\RtfDecompressor` for compressed RTF payloads

Testing
-------

[](#testing)

```
php vendor/bin/phpunit
php vendor/bin/rector process
php vendor/bin/phpstan analyse --no-progress
```

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance89

Actively maintained with recent releases

Popularity20

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

54d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3c47797b11041f37c2eec74b09bc6619c8997467d690797ebad0e6ab7cb232b7?d=identicon)[tabuna](/maintainers/tabuna)

---

Top Contributors

[![tabuna](https://avatars.githubusercontent.com/u/5102591?v=4)](https://github.com/tabuna "tabuna (56 commits)")

---

Tags

phplaravelemailwriterreaderoutlookmsg

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cosmira-outlook-msg/health.svg)

```
[![Health](https://phpackages.com/badges/cosmira-outlook-msg/health.svg)](https://phpackages.com/packages/cosmira-outlook-msg)
```

###  Alternatives

[illuminate/database

The Illuminate Database package.

2.8k54.1M11.0k](/packages/illuminate-database)[propaganistas/laravel-disposable-email

Disposable email validator

6012.9M7](/packages/propaganistas-laravel-disposable-email)[erag/laravel-disposable-email

A Laravel package to detect and block disposable email addresses.

249143.0k](/packages/erag-laravel-disposable-email)[php-flasher/flasher-laravel

Seamlessly integrate flash notifications into your Laravel applications with PHPFlasher. Enhance user feedback and engagement with minimal setup.

452.9M45](/packages/php-flasher-flasher-laravel)[kolay/xlsx-stream

Streaming XLSX reader and writer for PHP and Laravel. Constant memory regardless of file size, direct S3 multipart streaming, optional born-indexed random access.

436.0k](/packages/kolay-xlsx-stream)[hafael/azure-mailer-driver

Supercharge your Laravel or Symfony app with Microsoft Azure Communication Services (ACS)! Effortlessly add email, chat, voice, video, and telephony-over-IP for next-level communication. 🚀

15122.2k](/packages/hafael-azure-mailer-driver)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
