# Technical Documentation: getgrav/grav

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/getgrav/grav)

### Overview (`README.md`)

#  Grav

[](https://github.com/phpstan/phpstan)
[](https://chat.getgrav.org)
 [](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [](#backers) [](#supporters) [](#sponsors)

Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform.  There is **Zero** installation required.  Just extract the ZIP archive, and you are already up and running.  It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.

The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:

* [Twig Templating](https://twig.symfony.com/): for powerful control of the user interface
* [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation
* [YAML](https://yaml.org): for simple configuration
* [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support
* [Symfony Cache](https://symfony.com/doc/current/components/cache.html): backend layer for performance
* [Pimple Dependency Injection Container](https://github.com/silexphp/Pimple): for extensibility and maintainability
* [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation

# Requirements

- PHP 8.3 or higher. Check the [required modules list](https://learn.getgrav.org/basics/requirements#php-requirements)
- Check the [Apache](https://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](https://learn.getgrav.org/basics/requirements#iis-requirements) requirements

# Documentation

The full documentation can be found from [learn.getgrav.org](https://learn.getgrav.org).

# QuickStart

These are the options to get Grav:

### Downloading a Grav Package

You can download a **ready-built** package from the [Downloads page on https://getgrav.org](https://getgrav.org/downloads)

### With Composer

You can create a new project with the latest **stable** Grav release with the following command:

```bash
composer create-project getgrav/grav ~/webroot/grav
```

### From GitHub

1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:
   ```bash
   cd ~/webroot
   git clone https://github.com/getgrav/grav.git
   ```

2. Install the **plugin** and **theme dependencies** by using the [Grav CLI application](https://learn.getgrav.org/advanced/grav-cli) `bin/grav`:
   ```bash
   cd ~/webroot/grav
   bin/grav install
   ```

Check out the [install procedures](https://learn.getgrav.org/basics/installation) for more information.

# Adding Functionality

You can download [plugins](https://getgrav.org/downloads/plugins) or [themes](https://getgrav.org/downloads/themes) manually from the appropriate tab on the [Downloads page on https://getgrav.org](https://getgrav.org/downloads), but the preferred solution is to use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`:

```bash
bin/gpm index
```

This will display all the available plugins and then you can install one or more with:

```bash
bin/gpm install <plugin/theme>
```

# Updating

To update Grav you should use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`:

```bash
bin/gpm selfupgrade
```

To update plugins and themes:

```bash
bin/gpm update
```

## Upgrading from older version

> **Migrating from Grav 1.x to Grav 2.0?** Grav 2.0 is a major release with a PHP 8.3+ baseline and a modernized core, and upgrading requires a dedicated migration — `bin/gpm selfupgrade` alone will not take you across the 1.x → 2.x boundary. Follow the step-by-step guide at **[getgrav.org/migrate-to-2](https://getgrav.org/migrate-to-2)** before running any upgrade command.

Within a major version, `bin/gpm selfupgrade` handles point upgrades. The following guides cover in-place upgrades between minor releases of Grav 1.x:

* [Upgrading to Grav 1.8](https://learn.getgrav.org/16/advanced/grav-development/grav-18-upgrade-guide)
* [Upgrading to Grav 1.7](https://learn.getgrav.org/16/advanced/grav-development/grav-17-upgrade-guide)
* [Upgrading to Grav 1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-16-upgrade-guide)
* [Upgrading from Grav before 1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-15-upgrade-guide)

# Contributing
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement! Please refer to the [Contributing guide](CONTRIBUTING.md) for more guidance on this topic.

## Security issues
If you discover a possible security issue related to Grav or one of its plugins, please email the core team at contact@getgrav.org and we'll address it as soon as possible.

# Getting Started

* [What is Grav?](https://learn.getgrav.org/basics/what-is-grav)
* [Install](https://learn.getgrav.org/basics/installation) Grav in few seconds
* Understand the [Configuration](https://learn.getgrav.org/basics/grav-configuration)
* Take a peek at our available free [Skeletons](https://getgrav.org/downloads/skeletons)
* If you have questions, jump on our [Discord Chat Server](https://chat.getgrav.org)!
* Have fun!

# Exploring More

* Have a look at our [Basic Tutorial](https://learn.getgrav.org/basics/basic-tutorial)
* Dive into more [advanced](https://learn.getgrav.org/advanced) functions
* Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli)
* Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook)
* More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav)

# Backers
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav/contribute)]

<img src="https://opencollective.com/grav/tiers/backers.svg?avatarHeight=36&width=600" />


# Supporters
Support Grav with a monthly donation to help us continue development. [[Become a supporter](https://opencollective.com/grav/contribute)]

<img src="https://opencollective.com/grav/tiers/supporters.svg?avatarHeight=36&width=600" />


# Sponsors
Support Grav with a yearly donation to help us continue development. [[Become a sponsor](https://opencollective.com/grav/contribute)]

<img src="https://opencollective.com/grav/tiers/sponsors.svg?avatarHeight=36&width=600" />

# License

See [LICENSE](LICENSE.txt)


[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
[gitflow-extensions]: https://github.com/nvie/gitflow

# Running Tests

First install the dev dependencies by running `composer install` from the Grav root.

Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
Windows users should use the `composer test-windows` command.
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`

To run phpstan tests, you should run:

* `composer phpstan` for global tests
* `composer phpstan-framework` for more strict tests
* `composer phpstan-plugins` to test all installed plugins

---

### Overview (`tests/conformance/README.md`)

# Markdown conformance harness

Measures Grav's vendored Parsedown engine against the **CommonMark** and **GitHub
Flavored Markdown (GFM)** specifications, so the markdown feature gap is visible and
tracked rather than guessed.

## Run

```bash
php tests/conformance/run.php                 # both suites, per-section matrix
php tests/conformance/run.php gfm             # GFM only
php tests/conformance/run.php commonmark --section="Fenced code" --show-fails=5
php tests/conformance/run.php both --save     # also (re)write fixtures/baseline.json
```

Regenerate the GFM JSON from the upstream spec text:

```bash
php tests/conformance/extract_gfm.php
```

## Fixtures
- `fixtures/commonmark.json` — official CommonMark 0.31.2 spec tests (652 examples).
- `fixtures/gfm-spec.txt` — GitHub `cmark-gfm` spec source.
- `fixtures/gfm.json` — examples extracted from the GFM spec (672 examples, incl. the 5 GFM extension sections).
- `fixtures/baseline.json` — recorded pass counts per section (regression reference).

## How to read the numbers

The harness reports two columns:
- **strict** — exact string match (after outer trim).
- **loose** — a light, `<pre>`/`<code>`-protected normalization (collapses insignificant
  inter-tag whitespace, normalizes void-tag spacing).

It tests the **raw vendored `\Parsedown`** (the engine), not Grav's wrapper subclass —
the wrapper additionally entity-escapes `<` `>` `"`, which changes many outputs and is
out of scope for an engine baseline.

**Absolute percentages are honest, not flattering.** Parsedown is a fast line-based
parser, not a CommonMark AST parser. Many core failures are genuine, well-known
divergences — e.g. it drops the trailing newline inside fenced `<code>`, keeps the
padding spaces in `` `code` `` spans that CommonMark strips, and does not implement
CommonMark emphasis flanking rules. So the light-normalized core rate (~46%) is real;
chasing a heavier normalizer would only inflate it. This is exactly why the plan targets
**GFM feature-completeness + a measured gap**, not literal 100% spec conformance.

## Baseline (PHP 8.5, pre-change)

GFM extension sections — the ones the feature work targets:

| GFM extension section | examples | loose pass |
|---|---|---|
| Strikethrough | 2 | **100%** ✅ already supported |
| Tables | 8 | 25% partial |
| Autolinks (www/email) | 11 | **0%** ❌ missing |
| Task list items | 2 | **0%** ❌ missing |
| Disallowed Raw HTML (tagfilter) | 1 | **0%** ❌ missing |

Overall: CommonMark 652 ex ≈ 46% loose; GFM 672 ex ≈ 46% loose. Use the per-section
matrix and the GFM-extension rows — not the headline number — to track progress. Every
engine change must keep core sections from regressing and push the GFM-extension rows
toward 100%.

## Regression gate for engine (perf) changes

Performance patches to the engine must be **output-identical**, not merely "spec pass-rate
unchanged." Verify by running the full corpus through the old and new engine and asserting
byte-identical output for every example (see the perf task / benchmark script).

---

--- METRICS ---
- Files Extracted: 2
- Estimated Token Budget: ~2686 tokens
- Canonical Reference: https://codewiki.google/github.com/getgrav/grav
