Open-source project
thephpleague/commonmark avatar
thephpleague/commonmark

league/commonmark: A PHP Markdown Parser with Full CommonMark and GFM Spec Support

Highly-extensible PHP Markdown parser which fully supports the CommonMark and GFM specs.

2,979 stars218 forksPHPBSD-3-Clause

At a glance

What is it?
league/commonmark is a PHP library that parses Markdown into HTML with strict adherence to the CommonMark specification and optional GitHub-Flavored Markdown support. Created by Colin O'Dell and based on the CommonMark JS reference implementation, it targets PHP applications that need predictable, spec-compliant Markdown rendering with a configurable extension system.
Who is it for?
league/commonmark is the right choice for PHP projects that need predictable, spec-compliant Markdown rendering and may need to extend the parser with custom syntax. Teams that parse untrusted user input must set html_input and allow_unsafe_links explicitly.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What league/commonmark Solves and Who Uses It

league/commonmark exists because the original Markdown specification left many parsing edge cases undefined, producing inconsistent output across implementations. The CommonMark spec, developed by John MacFarlane and others, was created to resolve those ambiguities with a detailed, testable specification. league/commonmark implements that spec in PHP and is based on the CommonMark JS reference implementation (commonmark.js) by John MacFarlane.

The intended users are PHP developers who need Markdown parsing in web applications, CMS systems, documentation generators, or content platforms. The library is particularly suited to projects where the rendered HTML must be predictable and auditable, such as platforms that expose Markdown to end users and need consistent output regardless of input quirks. The README notes integrations with CakePHP 3, Drupal, Laravel, Sculpin, and Symfony, which gives a sense of the ecosystem it serves.

CommonMark Spec Compliance and GitHub-Flavored Markdown

The core parser implements the full CommonMark specification. This means standard elements including headings, paragraphs, block quotes, fenced code blocks, emphasis, strong emphasis, links, images, and HTML blocks all follow spec-defined behavior rather than a best-effort approximation.

The GithubFlavoredMarkdownConverter class extends this with the features defined in the GitHub-Flavored Markdown (GFM) spec: autolinks, disallowed raw HTML, strikethrough, tables, and task lists. GFM is a superset of CommonMark, and the README notes that individual GFM features can be included selectively through the extensions documentation rather than enabling all of them at once.

An important character encoding constraint: the README states that only UTF-8 and ASCII encodings are supported. Markdown that uses other encodings must be converted to UTF-8 before being passed to the library. This is a hard constraint, not a soft preference.

Installing league/commonmark and Running a First Conversion

The library requires PHP 7.4 or higher with the mbstring extension. Installation through Composer is the standard approach:

bash
composer require league/commonmark

The CommonMarkConverter class provides a direct path from Markdown string to HTML string. The README gives this example:

php
use League\CommonMark\CommonMarkConverter;

$converter = new CommonMarkConverter([
    'html_input' => 'strip',
    'allow_unsafe_links' => false,
]);

echo $converter->convert('# Hello World!');

// <h1>Hello World!</h1>

To use GitHub-Flavored Markdown instead, replace CommonMarkConverter with GithubFlavoredMarkdownConverter. The constructor signature and configuration keys are the same.

The html_input and allow_unsafe_links settings shown here are the security-relevant options. When processing input from untrusted users, the README's security documentation at commonmark.thephpleague.com/security/ should be consulted before choosing values for these options.

Security Considerations for Untrusted Input

The README includes an explicit security warning: when parsing untrusted user input, the html_input and allow_unsafe_links configuration options must be set deliberately. Setting html_input to 'strip' removes any raw HTML tags that a user might embed in Markdown, which prevents HTML injection. Setting allow_unsafe_links to false prevents the parser from rendering javascript: and data: URLs as clickable links.

For applications that must allow some raw HTML from users, the README recommends passing the output through an HTML sanitization library such as HTML Purifier as an additional layer. league/commonmark itself does not perform HTML sanitization beyond the html_input option; it is a parser, not a security filter.

This design choice is correct: parsing and sanitization are separate concerns, and coupling them would make the library harder to use in contexts where raw HTML output is intentional (for example, a trusted author writing documentation).

The Extension System: Bundled and Community Extensions

league/commonmark includes an extension system that allows new block and inline elements to be added without modifying the core parser. Extensions are PHP classes that register new parsers, renderers, and delimiter processors.

The library ships with a set of bundled extensions documented at commonmark.thephpleague.com/extensions/overview. Community-maintained extensions on Packagist include an emoji extension, superscript and subscript support, a YouTube iframe embedder, a lazy image loader, a highlighted text extension using the HTML mark tag, a Pygments-based syntax highlighter, and a LaTeX renderer.

The README notes that classes and methods marked @internal are not stable API and may change in any release. Custom extensions that depend on @internal classes accept the risk of breakage on minor version updates. This is the main technical constraint to verify when building a deep integration: checking whether the extension points needed are part of the public API or marked @internal.

Versioning Policy and Maintenance Support

The library follows SemVer. The README draws a careful distinction: minor and patch releases should not introduce breaking changes to code, but they may change the resulting HTML output of parsed Markdown due to bug fixes or spec updates. Code that consumes the HTML output rather than the library's PHP API may therefore need to handle output changes on minor version updates.

When a new minor version is released, the previous minor version receives security and critical bug fixes for at least three months. When a new major version is released, the previous major version receives critical bug fixes for three months and security updates for six months. The README notes this policy may change.

Professional support, including notifications for new releases and security updates, is available through a Tidelift subscription. Security vulnerabilities should be reported through Tidelift's security contact rather than as public GitHub issues. The last push was September 27, 2026, and the most recent releases (2.10.3 and 2.10.2) were on September 21, 2026.

league/commonmark vs. Python-Markdown and Pandoc

Python-Markdown is the most widely used Markdown parser in the Python ecosystem and follows the original Markdown specification rather than CommonMark. It does not implement the CommonMark spec's disambiguation rules, which means edge cases in nested constructs and table-adjacent content can produce different output than league/commonmark. For PHP projects, this distinction is mainly relevant when the application must produce output consistent with a Python backend or another non-CommonMark parser.

Pandoc is a universal document converter that supports Markdown as one of many input formats and can produce output in dozens of formats, including PDF, EPUB, and LaTeX. Its Markdown dialect extends CommonMark with features such as definition lists, footnotes, and math notation. Pandoc is the right tool when the output format is not HTML or when the input needs features beyond what CommonMark and GFM define. For PHP web applications that need straightforward Markdown-to-HTML conversion with a spec-compliant parser, league/commonmark is a better fit than invoking Pandoc as an external process.

Editorial conclusion

league/commonmark is the right choice for PHP projects that need predictable, spec-compliant Markdown rendering and may need to extend the parser with custom syntax. Teams that parse untrusted user input must set html_input and allow_unsafe_links explicitly. The BSD-3-Clause license imposes no constraints beyond attribution, and the Tidelift subscription path is available for organizations that need a formal support SLA. The @internal API boundary is the main technical constraint to verify before building a deep custom extension.

Frequently asked questions

What is league/commonmark?

league/commonmark is a PHP Markdown parser created by Colin O'Dell that implements the full CommonMark specification and optionally supports GitHub-Flavored Markdown. It is available on Packagist and installs via Composer.

What is the difference between CommonMark and GFM?

CommonMark is the base specification that defines standard Markdown parsing rules with precise disambiguation. GFM (GitHub-Flavored Markdown) is a superset that adds features including tables, task lists, strikethrough, and autolinks. league/commonmark supports both through separate converter classes.

How does league/commonmark compare to Python-Markdown?

Python-Markdown follows the original informal Markdown specification rather than CommonMark, so edge cases in nested constructs can produce different HTML output. league/commonmark strictly follows the CommonMark spec. For interoperability between PHP and Python systems, the output may differ unless both sides use CommonMark-compliant parsers.

Official sources

  1. License: BSD-3-Clause
  2. Project website
  3. README
  4. Releases
  5. thephpleague/commonmark on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/thephpleague-commonmark.svg)](https://hysenlabs.com/projects/thephpleague-commonmark)