PHPackages                             iliaal/mdparser - 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. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. iliaal/mdparser

ActivePhp-ext[Parsing &amp; Serialization](/categories/parsing)

iliaal/mdparser
===============

Native C CommonMark + GitHub Flavored Markdown parser for PHP, targeting CommonMark 0.31 + GFM. ~10-20x faster than pure-PHP parsers, zero runtime dependencies.

0.4.1(1mo ago)19293BSD-3-ClauseCPHP &gt;=8.2CI passing

Since Apr 11Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/iliaal/mdparser)[ Packagist](https://packagist.org/packages/iliaal/mdparser)[ Docs](https://github.com/iliaal/mdparser)[ RSS](/packages/iliaal-mdparser/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (6)DependenciesVersions (7)Used By (0)

mdparser
========

[](#mdparser)

[![Tests](https://github.com/iliaal/mdparser/actions/workflows/tests.yml/badge.svg)](https://github.com/iliaal/mdparser/actions/workflows/tests.yml)[![Windows Build](https://github.com/iliaal/mdparser/actions/workflows/windows.yml/badge.svg)](https://github.com/iliaal/mdparser/actions/workflows/windows.yml)[![Version](https://camo.githubusercontent.com/ef0b4ea8e473b20ea4601de5f90665a85f506df28439b79a1e973d40c4fa26c6/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f696c6961616c2f6d64706172736572)](https://github.com/iliaal/mdparser/releases)[![License: BSD-3-Clause](https://camo.githubusercontent.com/5b18cec5d64abf4a1fb017b12bcf376f4f1aa4c91aa28a9669664f8b2666eb62/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4253442d2d332d2d436c617573652d677265656e2e737667)](https://opensource.org/licenses/BSD-3-Clause)[![Follow @iliaa](https://camo.githubusercontent.com/a54521c97521f05fbadec4bd9bcba96ff1eeaffe756a6d7338b47a628cdeb39b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466f6c6c6f772d40696c6961612d3030303030303f7374796c653d666c6174266c6f676f3d78266c6f676f436f6c6f723d7768697465)](https://x.com/intent/follow?screen_name=iliaa)

[![mdparser: ~10-20× faster than pure-PHP](images/mdparser-hero.jpg)](images/mdparser-hero.jpg)

Native C CommonMark + GitHub Flavored Markdown parser for PHP. ~10-20× faster than pure-PHP alternatives (Parsedown, cebe, michelf) on a clean optimized build, targeting CommonMark 0.31 (652/652 spec examples pass; see `docs/spec-coverage.md`). GFM extensions: tables, strikethrough, task lists, autolinks, tagfilter. Installable via [PIE](https://github.com/php/pie) (the PHP Foundation's PECL successor); ships as a single `.so`. PHP 8.2 minimum, OO API with `final` classes and `readonly` options.

📦 Install
---------

[](#-install)

```
# PIE (PHP Foundation's extension installer; uses the composer.json
# at the repo root with type: "php-ext")
pie install iliaal/mdparser
```

On a minimal PHP image (e.g. `php:8.x-cli` from Docker Hub), PIE needs a few build tools installed first:

```
# Debian/Ubuntu
sudo apt install -y git bison libtool-bin

# macOS
brew install bison libtool
```

### From source

[](#from-source)

```
git clone https://github.com/iliaal/mdparser.git
cd mdparser
phpize && ./configure --enable-mdparser
make -j
sudo make install
echo 'extension=mdparser.so' | sudo tee /etc/php/conf.d/mdparser.ini
```

### Windows binaries

[](#windows-binaries)

Pre-built DLLs for PHP 8.3, 8.4, and 8.5 (TS/NTS, x86/x64) are attached to each [GitHub release](https://github.com/iliaal/mdparser/releases).

🛠️ Usage
--------

[](#️-usage)

```
use MdParser\Parser;
use MdParser\Options;

// Default parser: safe mode on, GFM extensions on.
$parser = new Parser();
echo $parser->toHtml('# Hello');
// Hello

// Custom options via named arguments. All fields readonly.
$parser = new Parser(new Options(
    smart: true,          // --- -> em dash, -- -> en dash, "..." -> curly
    footnotes: true,      // enable [^ref] / [^ref]: syntax
    unsafe: false,        // raw HTML is escaped (default)
));
echo $parser->toHtml($markdown);

// Three output formats from one parser.
$html = $parser->toHtml($markdown);
$xml  = $parser->toXml($markdown);   // CommonMark XML, DOCTYPE-wrapped
$ast  = $parser->toAst($markdown);   // nested arrays, see below

// AST shape is documented in tests/006_ast.phpt. Brief example:
// [
//   'type' => 'document',
//   'children' => [
//     ['type' => 'heading', 'level' => 1, 'children' => [
//        ['type' => 'text', 'literal' => 'Hello'],
//     ]],
//   ],
// ]
```

📊 Performance
-------------

[](#-performance)

Against the major pure-PHP Markdown libraries, on PHP 8.4 (clean optimized build, each parser in its default configuration):

Corpusmdparser ops/secBest pure-PHP ops/secSpeedup200 B~530,000~26,000 (Parsedown)~20×1.8 KB~110,000~6,000 (cebe/GitHub)~19×200 KB~980~95 (cebe/GitHub)~10×~10-20× faster across the corpora (up to ~45× vs the slowest), from small messages to full 200 KB spec documents. [`bench/README.md`](bench/README.md) is the source of truth: methodology, all parsers, caveats, league/commonmark notes, and how to reproduce. (Always benchmark a clean optimized PHP build — a debug/ASan build inflates these numbers.)

✨ Feature matrix
----------------

[](#-feature-matrix)

Comparison with the major pure-PHP Markdown libraries. "via ext" means the feature exists but requires opting in to a non-default extension; "Extra" means the feature ships in the library's Markdown Extra dialect, not its base mode; "✗" means the feature is not supported at all.

FeaturemdparserParsedownleague/cm corecebe GFMmichelf ExtraCiconiaCommonMark core✓partial✓partialpartialpartialFenced code blocks✓✓✓✓✓✓GFM tables✓✓via ext✓via Extra✓Strikethrough✓✓via ext✓✗✓Task lists✓✗via ext✗✗✓Autolinks (bare URL)✓✓via ext✓✗✓`` tag filter✓ (tagfilter)✓ (escaped)via extpartial✗✗Smart punctuation✓ (`Options::smart`)✗via ext✗✗✗Footnotes✓ (`Options::footnotes`)Extravia ext✗✓ ExtrapluginHardbreaks/nobreaks✓✗✗✗✗✗Sourcepos✗✗✓✗✗✗Heading anchors✓ (`Options::headingAnchors`)✗via ext✗✗✗`rel="nofollow"`✓ (`Options::nofollowLinks`)✗via ext✗✗✗HTML output✓✓✓✓✓✓XML output✓✗✗✗✗✗AST output✓ (arrays)✗✓ (objects)✗✗✗Opt-in dialect extensions
-------------------------

[](#opt-in-dialect-extensions)

Beyond CommonMark + GFM, md4c ships several dialect extensions, each exposed as an opt-in `Options` flag (all default off, so the standard CommonMark + GFM parse is unaffected): `latexMath` (`$inline$`, `$$block$$`), `wikiLinks` (`[[target]]`), `spoilers` (`||text||`), `underline`, `highlight` (`==text==`), `superscript` (`^text^`), `subscript` (`~text~`), and `admonitions` (GitHub-style `> [!NOTE]` alert blocks). Plus parser-behavior toggles (`noIndentedCodeBlocks`, `permissiveAtxHeadings`, `collapseWhitespace`). See [`docs/options.md`](docs/options.md) for behavior and edge cases.

What we don't cover
-------------------

[](#what-we-dont-cover)

mdparser is deliberately scoped to CommonMark core plus the GFM extensions. It does **not** cover the "Markdown Extra" family of features that Parsedown Extra, michelf Markdown Extra, and league/commonmark's optional extensions offer. If you need any of the following, reach for league/commonmark, the most actively-maintained pure-PHP option for extended Markdown:

- Definition lists (`Term :: definition`)
- Abbreviations (`*[HTML]: ...`)
- Attribute syntax (`{.class #id key="val"}`)
- Permalink anchor markup (we emit heading `id` slugs; we don't inject the inner `` element GitHub uses for permalinks)
- Table of contents
- YAML front matter
- Mentions (`@user`)
- Emoji (`:smile:`)
- Fenced admonition containers (`::: warning`); GitHub-style `> [!NOTE]`alert blocks are supported via `Options::admonitions`

These are real features. They're just out of scope for a CommonMark+GFM core parser.

A note on `unsafe: true`
------------------------

[](#a-note-on-unsafe-true)

`Options::unsafe = true` tells the renderer to pass raw HTML through verbatim instead of escaping or stripping it. The contract for this mode is that you own the input: it is yours, or it comes from a pipeline you trust. `headingAnchors` and `nofollowLinks` are applied in-stream as md4c parses the source, so they touch only Markdown-derived nodes; raw HTML you write directly is emitted verbatim and is never rewritten:

- **Heading anchors apply to Markdown headings only.** A `# heading` gets an `id` slug. A raw `x` block written directly in the source (possible under `unsafe: true, tagfilter: false`) is raw HTML, not a parsed heading node, so it is emitted untouched and gets no id. A raw heading and a later Markdown heading with the same text do not collide.
- **`nofollowLinks` applies to Markdown links only.** Inline links, reference links, and autolinks get `rel="nofollow noopener noreferrer"`; in-document fragment anchors (`href="#..."`, including footnote references and backrefs) are skipped. A raw `` written directly in the source is passed through verbatim rather than rewritten — sanitize raw HTML yourself if you allow it.

### Structural outputs are unsanitized

[](#structural-outputs-are-unsanitized)

`Parser::toXml()` and `Parser::toAst()` return structural representations of the parsed document. Link / image `url` fields and `html_block` / `html_inline` literal text are preserved; XML output escapes those bytes as XML text, while AST output returns them byte-for-byte. The `unsafe`, `tagfilter`, and URL-scheme defenses do **not** make these structural outputs safe to transform back into HTML. If you build HTML out of XML or AST data yourself, you own the sanitization: apply a URL scheme allowlist before emitting `href`, and run HTML through a sanitizer before emitting raw `html_block` / `html_inline` literal text. See `docs/ast.md` for examples.

🔗 PHP Performance Toolkit
-------------------------

[](#-php-performance-toolkit)

Companion native PHP extensions for high-throughput PHP workloads:

- **[php\_excel](https://github.com/iliaal/php_excel)**: native Excel I/O. 7-10× faster than PhpSpreadsheet, full XLS/XLSX with formulas, formatting, and styling. Powered by LibXL.
- **[php\_clickhouse](https://github.com/iliaal/php_clickhouse)**: native ClickHouse client speaking the wire protocol directly. Picks up where SeasClick left off.
- **[fastchart](https://github.com/iliaal/fastchart)**: native chart-rendering extension. 26 chart types behind one fluent OO API, SVG-canonical with PNG/JPG/WebP output (no libgd dependency).

📚 Read more
-----------

[](#-read-more)

Full background, design rationale, and benchmark methodology in the launch post: [mdparser: A Native CommonMark + GFM Parser for PHP](https://ilia.ws/blog/mdparser-a-native-commonmark-gfm-parser-for-php).

License
-------

[](#license)

- Wrapper code (`mdparser*.c`, `php_mdparser.h`) under BSD 3-Clause.
- Embedded md4c sources under the MIT license. See `LICENSE` for aggregated notices.

---

[Follow @iliaa on X](https://x.com/iliaa) • [Blog](https://ilia.ws) • If this sped up your stack, ⭐ star it!

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance91

Actively maintained with recent releases

Popularity25

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.7% 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

Every ~17 days

Total

5

Last Release

37d ago

PHP version history (2 changes)0.1.1PHP &gt;=8.3

0.4.0PHP &gt;=8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2838354?v=4)[iliaa](/maintainers/iliaa)[@iliaa](https://github.com/iliaa)

---

Top Contributors

[![iliaal](https://avatars.githubusercontent.com/u/158724?v=4)](https://github.com/iliaal "iliaal (75 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

cmarkcommonmarkgfmmarkdownpeclphpphp-extensionpieparsermarkdowngfmcommonmarkphp-extensionpiecmark

### Embed Badge

![Health badge](/badges/iliaal-mdparser/health.svg)

```
[![Health](https://phpackages.com/badges/iliaal-mdparser/health.svg)](https://phpackages.com/packages/iliaal-mdparser)
```

###  Alternatives

[league/commonmark

Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)

3.0k437.5M1.1k](/packages/league-commonmark)[erusev/parsedown

Parser for Markdown.

15.1k156.8M875](/packages/erusev-parsedown)[cebe/markdown

A super fast, highly extensible markdown parser for PHP

1.0k34.1M150](/packages/cebe-markdown)[erusev/parsedown-extra

An extension of Parsedown that adds support for Markdown Extra.

84315.3M220](/packages/erusev-parsedown-extra)[cebe/markdown-latex

A super fast, highly extensible markdown parser for PHP, that converts markdown files into latex

50780.3k8](/packages/cebe-markdown-latex)[parsedown/parsedown

Parser for Markdown.

221.6M9](/packages/parsedown-parsedown)

PHPackages © 2026

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