PHPackages                             manychois/simdom - 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. manychois/simdom

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

manychois/simdom
================

A simple-to-use PHP library for processing DOM documents.

0.3.1(7mo ago)4341[5 PRs](https://github.com/manychois/simdom/pulls)MITPHPPHP ^8.4CI passing

Since Jan 30Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/manychois/simdom)[ Packagist](https://packagist.org/packages/manychois/simdom)[ RSS](/packages/manychois-simdom/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (4)Versions (13)Used By (0)

Simdom - A simplified and relaxed DOM structure library
=======================================================

[](#simdom---a-simplified-and-relaxed-dom-structure-library)

[![PHP Version](https://camo.githubusercontent.com/2ef1b311391a967fe24849a49dd4d8e1b8ee9cf1f15625fd7c7b11a7c78da800/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e342d3737376262332e737667)](https://www.php.net/releases/8.4/en.php)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

Simdom is a lightweight PHP library designed to make parsing and manipulating DOM documents as straightforward as possible. It requires no external dependencies or extensions.

Without using the built-in PHP DOM extension, Simdom can have its own opinionated appraoch on how HTML documents should be parsed and manipulated. It lets you to work with "non-compliant" HTML structure in a literal and intuitive way.

Before outputing the HTML string of the document, you can call the `$document->validate()` method to ensure that the document is valid according to the HTML5 specification.

Key differences from the standard HTML5 DOM specification / PHP DOM extension
-----------------------------------------------------------------------------

[](#key-differences-from-the-standard-html5-dom-specification--php-dom-extension)

### Simplified node types

[](#simplified-node-types)

Simdom provides 6 node types that form the DOM tree:

- `Document` - The root document node
- `Doctype` - Document type declarations
- `Element` - HTML elements with attributes and child nodes
- `Text` - Text content within elements
- `Comment` - HTML comments
- `Fragment` - Document fragments for grouping nodes

Attributes are not considered as a node type in Simdom, but rather as properties of `Element` nodes.

CDATA section or processing instructions are not supported, as they would not be valid in HTML5 documents.

Simplified and relaxed DOM structure
------------------------------------

[](#simplified-and-relaxed-dom-structure)

- There is no concept of an owner document, meaning nodes can be freely moved between documents.
- There is no concept of namespace.
- `Document`, `Element` and `Fragment` nodes can have child nodes of any type except `Document` and `Fragment`, in any order, i.e.:
    - `Document` can hold `Text` child.
    - `Document` does not restrict at most one `Doctype` child, and it does not have to be placed before any `Element` child.
    - `Document` does not restrict at most one `Element` child.
    - `Element` and `Fragment` can hold `Doctype` child.
- There is no concept of valid element structure, meaning elements can be nested in any way, even if it would not be valid HTML5, i.e. `` would be parsed as it is.
- Misaligned end tags are fixed by finding the last matching start tag, i.e. `abc` would be parsed as `abc`. If there is no matching start tag, the end tag is ignored.
- `` elements are treated as a Rawtext type element like `` or ``.
- Self-closing tag syntax is supported, for example `` is parsed as ``.
- All element names and attributes names are parsed as their ASCII-lowercase form.

Restrictions
------------

[](#restrictions)

However, there are still some lines you cannot cross in Simdom:

- `Document` and `Fragment` has no parent node, and cannot be a child of any other node. (Inserting `Fragment` as a child of any parent node is fine though, as it means inserting the `Fragment`'s child nodes.)
- `Element` name and attribute names must conform to the HTML5 specification.
- `Doctype` name, public identifier and system identifier must conform to the HTML5 specification.
- `Doctype` name must be present if either public or system identifier is present.
- No control characters are allowed anywhere, e.g. you cannot inject an delete character (U+007F) to a `Text` node.
- `Comment` cannot contain the character sequence `-->`.
- If a `Text` node is under a Rawtext type (e.g. ``) or Rcdata type (e.g. ``) element, it cannot contain the character sequence which may terminate the corresponding element start tag, e.g. `setAttr('class', 'container');
$div->id = 'main-content';
```

### Traversing and Manipulating the DOM Tree

[](#traversing-and-manipulating-the-dom-tree)

```
// Access document parts
$html = $doc->documentElement; // The  element
$head = $doc->head;           // The  element
$body = $doc->body;           // The  element

// Navigate the tree
$element = $body->firstElementChild;
$nextElement = $element->nextElementSibling;
$parent = $element->parent;

// Child node access
foreach ($body->childNodes as $node) {
    echo get_class($node) . "\n";
}

// Element-only access
foreach ($body->children as $element) {
    echo $element->name . "\n";
}
```

### Adding and Removing Nodes

[](#adding-and-removing-nodes)

```
// Append nodes
$body->append($div, $text);
$body->appendChild($comment);

// Prepend nodes
$body->prepend(Text::create('First text'));

// Insert before/after
$div->before(Comment::create('Before div'));
$div->after(Text::create('After div'));

// Replace nodes
$div->replaceWith(Element::create('section'));

// Remove nodes
$div->remove();
```

### Working with Attributes

[](#working-with-attributes)

```
$element = Element::create('input');
// Set attributes
$element->setAttr('type', 'text');
// Get attributes
$type = $element->getAttr('type'); // 'text'
$missing = $element->getAttr('missing'); // null
// Check existence
$hasType = $element->hasAttr('type'); // true
// Remove attributes
$element->removeAttr('name');
// Get all attributes
$attrs = $element->attrs(); // ['type' => 'text']
```

### Searching and Traversal

[](#searching-and-traversal)

```
// Depth-first search
$found = $doc->dfs(fn($node) => $node instanceof Element && $node->id === 'target');

// Breadth-first search
$found = $doc->bfs(fn($node) => $node instanceof Element && $node->name === 'button');

// Find the first form
$form = $doc->querySelector('form');

// Iterate through all descendants
foreach ($doc->descendants() as $node) {
    if ($node instanceof Text) {
        echo $node->data . "\n";
    }
}
```

### HTML Serialization

[](#html-serialization)

```
// Convert to string representation
$html = (string) $doc;
// or using the __toString() method
$html = $element->__toString();
```

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance72

Regular maintenance activity

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 56.9% 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 ~192 days

Recently: every ~239 days

Total

6

Last Release

238d ago

PHP version history (3 changes)0.1.0PHP &gt;=8.1

0.2.0PHP &gt;=7.4

0.3.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/e1ba7e0a3d6113e5704a03007e1d40c208af6ac5ec3a57e389ac426c661cbbb1?d=identicon)[manychois](/maintainers/manychois)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (29 commits)")[![manychois](https://avatars.githubusercontent.com/u/3290769?v=4)](https://github.com/manychois "manychois (22 commits)")

---

Tags

domhtmlhtml5parserphpHTML5dom

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/manychois-simdom/health.svg)

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

###  Alternatives

[masterminds/html5

An HTML5 parser and serializer.

1.8k242.8M229](/packages/masterminds-html5)[paquettg/php-html-parser

An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.

2.4k7.9M123](/packages/paquettg-php-html-parser)[sunra/php-simple-html-dom-parser

Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.

1.3k9.4M61](/packages/sunra-php-simple-html-dom-parser)[sabre/xml

sabre/xml is an XML library that you may not hate.

52832.2M131](/packages/sabre-xml)[voku/simple_html_dom

Simple HTML DOM package.

9188.3M63](/packages/voku-simple-html-dom)[veewee/xml

XML without worries

1835.9M29](/packages/veewee-xml)

PHPackages © 2026

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