PHPackages                             commonform/trawl - 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. [Search &amp; Filtering](/categories/search)
4. /
5. commonform/trawl

ActiveLibrary[Search &amp; Filtering](/categories/search)

commonform/trawl
================

PHP-native build-time full-text search indexer with a dependency-free JS query runtime

v1.0.0(yesterday)00MPL-2.0PHP ^8.3

Since Jul 19Compare

[ Source](https://github.com/commonformhq/trawl)[ Packagist](https://packagist.org/packages/commonform/trawl)[ Docs](https://github.com/commonformhq/trawl)[ RSS](/packages/commonform-trawl/feed)WikiDiscussions Synced today

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

Trawl
=====

[](#trawl)

PHP-native build-time full-text search indexer with a dependency-free JavaScript query runtime. No Node, no server-side query API, no Elasticsearch — index at build time, query in the browser.

Quickstart
----------

[](#quickstart)

```
composer require --dev commonform/trawl
trawl init
trawl build --source=dist/ --output=dist/trawl/
```

Then in your HTML:

```

import { Trawl } from '/trawl.js';

const trawl = await Trawl.init({ baseUrl: '/trawl/' });
const results = await trawl.search('reverse proxy');
// [{ url, title, score, excerpt: '...reverse proxy...' }]

```

Copy `runtime/trawl.js` from the package into your public directory, or use it directly from `vendor/commonform/trawl/runtime/trawl.js`.

CLI Commands
------------

[](#cli-commands)

```
trawl build   Build the search index
trawl verify  Validate manifest + shard + doc consistency
trawl watch   Watch for file changes and rebuild incrementally
trawl init    Scaffold a trawl.json configuration file

```

### Build

[](#build)

```
trawl build --source=dist/ --output=dist/trawl/
trawl build --adapter=markdown --source=content/ --output=dist/trawl/
trawl build --incremental                          # skip unchanged docs
trawl build --config=trawl.json                    # use config file
```

### Verify

[](#verify)

```
trawl verify --index=dist/trawl/
```

Configuration (trawl.json)
--------------------------

[](#configuration-trawljson)

```
{
    "source": "dist/",
    "output": "dist/trawl/",
    "adapter": "filesystem",
    "include": ["**/*.html"],
    "exclude": ["**/404.html", "drafts/**"],
    "selectors": {
        "title": "title",
        "heading": "h1, h2, h3",
        "body": "main",
        "ignore": "[data-trawl-ignore], nav, footer"
    },
    "field_weights": { "title": 10, "heading": 5, "body": 1 },
    "facets": ["tags", "category"],
    "language": "en",
    "stemmer": "porter2",
    "stopwords": "default",
    "incremental": true,
    "cache_file": ".trawl-cache.json"
}
```

Adapters
--------

[](#adapters)

AdapterInputDescription`filesystem``.html` filesWalks a directory of rendered HTML, extracts content via CSS selectors`markdown``.md` / `.mdx` filesParses YAML frontmatter + Markdown body via league/commonmark`array``iterable`Programmatic input from CMS integrationsJS Runtime API
--------------

[](#js-runtime-api)

```
import { Trawl } from './trawl.js';

const trawl = await Trawl.init({ baseUrl: '/trawl/' });

const results = await trawl.search('query', {
    limit: 10,
    filters: { tags: 'docs' },
    mode: 'and'               // 'and' (default) or 'or'
});

// results: [{ url, title, score, excerpt, meta }]
```

Requirements
------------

[](#requirements)

- **Indexer**: PHP 8.3+, Composer
- **Runtime**: Any browser with native `fetch`, ES modules, and `URL`

License
-------

[](#license)

MPL-2.0

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

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

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a444e6ec6729bf445a0645a4431d61e595e67a2911f684f6edf0d90207eb6316?d=identicon)[hisoka-root](/maintainers/hisoka-root)

---

Tags

searchindexerstatic-sitebm25full text searchinverted-indexclient-side-search

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/commonform-trawl/health.svg)

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

###  Alternatives

[chameleon-system/chameleon-base

The Chameleon System core.

1028.7k5](/packages/chameleon-system-chameleon-base)[craftcms/cms

Craft CMS

3.6k3.6M3.2k](/packages/craftcms-cms)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

103519.9k57](/packages/friendsoftypo3-content-blocks)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.8M509](/packages/pimcore-pimcore)[blackfire/player

A powerful web crawler and web scraper with Blackfire support

49617.1k](/packages/blackfire-player)

PHPackages © 2026

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