NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #2886 most downloaded on Packagist
A PHP port of Mozilla's Readability.js
Last release 2 months ago
30 Jul 2026
Release timing varies
gaps range from 2 weeks to 1.2 years
Nearly every release is documented
notes for 28 of 31 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
35 releases · first in 2016
Lazy Article properties + metadataOnly option (4.1.0) by @fivefilters in #52
Full Changelog: v4.0.0...v4.1.0
metadataOnly option (PHP-specific): extract only the title and metadata, skipping content extraction entirely. parse() then skips every stage that mutates the document (noscript image unwrapping, script removal, document prep, and the article grab itself), so a passed-in \Dom\HTMLDocument is guaranteed to be left unmodified. The returned Article has the content-derived properties set to null, as when no content is found (hasContent() returns false)Article's content-derived properties (content, textContent, length, images) are now computed lazily from contentElement on first access (via property hooks) and cached, so callers that only use contentElement, hasContent() or the metadata no longer pay for serializing the article HTML and text on every parse. Reads are unchanged (same names, same types, same values); hasContent() now checks contentElement. json_encode() and var_dump() output is preserved via jsonSerialize()/__debugInfo() (note that both trigger the full serialization). Two edges to note: the Article constructor no longer takes content/textContent/length/images (it derives them from contentElement), and the lazy properties, being virtual, no longer appear in get_object_vars() or (array) castsOne column per quarter.
Readability.php 4.0 is a ground-up rewrite: a fresh port of Mozilla's Readability.js v0.6.0 built on PHP 8.4's new DOM API and HTML parser . This is t
Readability.php 4.0 is a ground-up rewrite: a fresh port of Mozilla's Readability.js v0.6.0 built on PHP 8.4's new DOM API and HTML parser. This is the first stable release of the 4.0 series and includes everything from v4.0.0-beta.1.
Dom\HTMLDocument (the spec-compliant Lexbor parser bundled with PHP), replacing HTML5-PHP and the legacy libxml path. No more entity workarounds (substituteEntities, summonCthulhu and friends are gone).lang and publishedTime output, maxElemsToParse, classesToPreserve, allowedVideoRegex, linkDensityModifier and debug options, and Readerable::isProbablyReaderable().parse() returns a readonly Article value object (title, content, textContent, excerpt, byline, siteName, dir, lang, publishedTime, image, images, …). Options are passed as named constructor arguments: new Readability(fixRelativeURLs: true).Uri\WhatWg\Url when available, with rowbot/url as the fallback on PHP 8.4, matching the new URL() behavior Readability.js relies on.psr/log ^1.0 || ^2.0 || ^3.0 and rowbot/url ^3.1.7 || ^4.0 so the library co-installs cleanly alongside a wider range of applications, with CI now also testing the lowest allowed versions (#49).The API has changed — see UPGRADE.md for the full migration guide, and the CHANGELOG for the complete list of changes.
The only changes since beta.1 are the widened dependency constraints and lowest-deps CI coverage noted above — no code changes.
Full Changelog: v3.3.3...v4.0.0
First stable release of the 4.0 series — a ground-up rewrite. This release includes all changes from v4.0.0-beta.1 below (see UPGRADE.md for the 3.x → 4.0 migration guide), plus the following changes since beta.1:
psr/log now accepts ^1.0 || ^2.0 || ^3.0 (the library only consumes the interface, so every major works) and rowbot/url now accepts ^3.1.7 || ^4.0 (older majors avoid rowbot/url 4.x's hard requirements on psr/log ^3 and newer brick/math, both common sources of version conflicts). Note: rowbot/url 3.x emits PHP 8.4 implicit-nullable deprecation notices internally; it is only loaded on PHP 8.4 (PHP 8.5+ uses the native Uri\WhatWg\Url), and Composer still picks 4.x unless another dependency forces an older versioncomposer update --prefer-lowest) to keep the widened constraints honestv4.0: Rewrite on PHP 8.4's native DOM API, parity with Readability.js 0.6.0 by @fivefilters in #41
Full Changelog: v3.3.3...v4.0.0-beta.1
Ground-up port from the latest Readability.js (v0.6.0) using Claude's Fable model. Uses PHP 8.4's new DOM API and native parser. See UPGRADE.md for the full 3.x → 4.0 migration guide.
Dom\HTMLDocument (the WHATWG-spec Lexbor parser bundled with PHP), replacing HTML5-PHP and the legacy libxml pathparse() now returns a readonly Article value object (title, content, textContent, length, excerpt, byline, siteName, dir, lang, publishedTime, image, images, contentElement). When no article content is found (where Readability.js returns null), the Article still carries the extracted title and metadata with null content — check Article::hasContent(). ParseException is thrown only for empty input or documents over maxElemsToParseReadability constructor as named arguments, like the options object in Readability.js (new Readability(fixRelativeURLs: true)), and are all optional; a readonly Configuration object taking the same named arguments can be passed instead. maxTopCandidates renamed to nbTopCandidates (matching Readability.js)<div id="readability-page-1" class="page">, as in Readability.jsArticle::$byline; the articleByline option becomes keepInlineByline, which only controls whether an inline byline stays in the content (default removes it, as in Readability.js)getImage()/getImages() become $article->image / $article->imagesLoggerInterface as the logger option instead of setLogger()Uri\WhatWg\Url when available, rowbot/url on PHP 8.4 — matching the new URL() behavior Readability.js relies on; replaces league/urilang and publishedTime output; maxElemsToParse, classesToPreserve, allowedVideoRegex, linkDensityModifier and debug options; aria-modal dialog removal; ad/loading-indicator stripping; parsely/article:author/itemprop metadata sources; JSON-LD @graph, @context-object and array handling; Unicode comma scoring; updated regexes (mathjax, bilibili, en/em-dash title separators)Readerable::isProbablyReaderable(), a port of Readability-readerable.jsparse() accepts an already-parsed Dom\HTMLDocument as well as an HTML stringtest/tools/) that diffs this port's output against Readability.js over the whole corpuscomposer analyse), run in CI alongside the test suiteext-xml requirementparser, substituteEntities, normalizeEntities, summonCthulhusrc/Nodes/) and its workarounds (attribute-based state, shifting-aware iteration)docker-compose.yml, Makefile, docker/); tests and static analysis run directly on PHP 8.4/8.5, locally and in CIFix type error - extends type support to add DOMProcessingInstruction in more method signatures (reported in #39 by @reinierkors )
Fix type error - extends type support to add DOMProcessingInstruction in more method signatures (reported in
#39 by @reinierkors)
Full Changelog: v3.3.2...v3.3.3
Fix type error - extends type support to include DOMCdataSection and DOMProcessingInstruction in various method signatures (reported in #37 and #38 by
Fix type error - extends type support to include DOMCdataSection and DOMProcessingInstruction in various method signatures (reported in
#37 and #38 by @mikiescolarmrf and @Grotax)
Full Changelog: v3.3.1...v3.3.2
fix: allow DOMProcessingInstruction by @blizzz in #36 , and #33 #35
Full Changelog: v3.3.0...v3.3.1
Fixed PHP 8.4 deprecation warning #31 (reported by @pich )
keepClasses is disabledisWhitespaceInElementContent() for whitespace detectionfirstElementChild and previousElementSibling for DOM traversalFull Changelog: v3.2.0...v3.3.0
Update dependencies to newer versions (League/URI version 7) to improve compatibility with projects already relying on those versions
Full Changelog: v3.1.7...v3.2.0
Fixes PHP 8 deprecation notice when base URLs (used for rewriting relative URLs) don't have a path component - thanks to @blat and @Markus-GS
Full Changelog: v3.1.6...v3.1.7
Avoid re-parsing source HTML when making multiple attempts to identify content in parse()
Full Changelog: v3.1.5...v3.1.6
Allow psr/log version 2.x and 3.x - thanks to @piotrek-r and @ArondeParon
Fixes improper use of null coalescing operator - reported by @thedf
Fixes issue where exception was thrown when resolving an invalid relative URL (when setFixRelativeURLs(true)) - reported by @jeffbotw
Fixes issue "Warning: Undefined array key 2" reported by @castroCrea
Exclude tests folder when using composer
Minimum PHP version 7.4 (composer.json updated)
Implemented changes made to Readability.js up to 26 August 2021, with the exception of a piece of code which doesn't produce the same results in PHP f
Added NodeUtility::filterTextNodes and deprecated NodeTrait getChildren()
og:image and og:image:width)getSiteName() feature from JS version as of 21 Dec 2018Fixed small issue that prevented the main image from showing up in the results
[BREAKING CHANGE] Bumped the minimum supported version of PHP to 7.0
<aside> tags during prepArticle().Merged PR#49 (Missing object when calling ->getContent())
->getContent())<base> elements before converting URLs to absolute.<link> tags on prepArticle()Switched from assertEquals to assertSame on unit testing to avoid weak comparisons.
data-src as a image source path->getDOMDocument() getter to retrieve the fully parsed DOMDocumentAdded 'data-orig' as an URL source for images
data-readability tags that don't apply anymore to the new structureNode encapsulation is gone. Pre v1 all nodes where encapsulated in a Readability class, which created lots of trouble with dependencies, responsibilit
ParseException.Trim titles when detecting hierarchical separators to avoid false negatives on strings with spaces.
<title> tag before searching on the <meta> tagsMerged PR #24. Fixes notice when trying to extract og:image
og:imagebutton, textarea, select, etc.)&nsbp; was detected as a node with content)ltr or rtl)Next release after this one will be v1 and will be a major refactor around Readability and HTMLParser methods and responsibilities.
Added a safecheck for really nasty HTML
Added normalizeEntities flag to convert UTF-8 characters to its HTML Entity equivalent. Fixes bugs on htmls with mixed encoding.
normalizeEntities flag to convert UTF-8 characters to its HTML Entity equivalent. Fixes bugs on htmls with mixed encoding.dom and backupdom objects are linked and some changes on the dom object reach the bakcupdom object. The new approach consists in deleting the backupdom object and recreating from scratch the dom object. Of course this has a performance impact, but seems to be quite low.100% complete port of Readability.js!
100% complete port of Readability.js!
, that entity is replaced by libxml and there's no way to disable it.Nothing published for this version
Nothing published for this version
Nothing published for this version
We are getting closer to be a 100% complete port of Readability.js!
We are getting closer to be a 100% complete port of Readability.js!
Last version I'm using master as the main development branch. All unreleased changes and main development will happen in the develop branch.
- Initial release
Your coding agent can read these notes before it upgrades. Set up the MCP server →