Grav
A fast, simple, and flexible flat-file CMS. No database required.
Introduction
Grav is a modern, open-source flat-file CMS that has redefined what a “database-free” website can do. Voted “Best Open Source CMS” multiple times, it was built by the team at RocketTheme to solve the bloat and complexity issues of traditional database-driven systems like Joomla and WordPress.
In Grav, “Content is Code.” Your entire website -pages, configuration, plugins, and themes -exists as simple text files (Markdown, YAML, Twig). This makes the system incredibly portable, easy to version control, and blazing fast. There is no MySQL database to install, secure, or backup. To move a Grav site, you literally just copy the folder.
Architecture and Technology
Grav is built on a sophisticated, modern PHP stack. It is not just a script; it is a framework leveraging best-in-class libraries (Symfony, Pimple, Doctrine).
Core Components
- Start-up Process: Grav uses Symfony components (Event Dispatcher, Console, Yaml) for its core logic.
- Template Engine: Twig is the templating language. It provides a powerful, secure way to output content without writing raw PHP.
- Content Processor: Parsedown (extended) is used to convert Markdown into HTML. It is extremely fast.
- Dependency Injection: Pimple handles dependency injection, making the codebase testable and modular.
- Caching: This is Grav’s secret weapon. Since reading thousands of text files
couldbe slow, Grav basically “compiles” your content into a high-performance map using Doctrine Cache. Subsequent requests are served instantly from the cache.
The Life of a Page Request
When a user visits yoursite.com/blog/my-post:
- Grav Initializes: Config files are loaded.
- Routing: Grav checks
user/pages/01.blog/my-post/item.md. The folder structure is the URL structure. - Processing: If not cached, the Markdown is parsed, Twig templates are processed, and plugins (like SEO or Form handling) fire events.
- Rendering: The final HTML is output and stored in the cache.
- Response: The user sees the page in milliseconds.
Content Management & Structure
One of Grav’s biggest distinguishing features is how it manages content. There is no “ID” column in a database.
The user/pages Directory
Content lives strictly in the user/pages/ folder. The relationships are defined by folder hierarchy:
- Ordering: Folders usually start with a number (e.g.,
01.home,02.blog) to define sort order in the menu. - Modularity: A page can be built from “Modular” sub-pages (e.g.,
_hero,_features,_contact) stored in subfolders, allowing for complex one-page layouts. - Media: Images and downloads live directly alongside the content file (
item.md), making portability effortless.
Modern PHP Foundation
Developers appreciate that Grav respects modern standards:
- Composer: It uses Composer for package management.
- PSR Compliance: It follows PHP Standards Recommendations.
- Symfony Components: It doesn’t reinvent the wheel; it uses rock-solid Symfony libraries.
Developer Experience (DX)
Grav is a joy for developers who love the command line and text editors.
Configuration as Code
Everything is YAML.
- Site Config:
user/config/site.yamlcontains global settings (Title, Author). - Page Headers: Every Markdown file starts with YAML Frontmatter:
--- title: My Post taxonomy: tag: [news, release] slug: my-custom-slug ---
This means you can edit your entire site in VS Code.
Twig Templating
Twig is expressive. A loop to show related pages might look like:
<ul>
{% for p in page.collection({'items':{'@taxonomy.tag': 'news'}, 'limit': 5}) %}
<li><a href="{{ p.url }}">{{ p.title }}</a></li>
{% endfor %}
</ul>
CLI Tools (GPM)
Grav comes with a CLI called GPM (Grav Package Manager).
bin/gpm index- List available plugins.bin/gpm install admin- Install the Admin panel plugin.bin/gpm selfupgrade- Update Grav itself.
Deployment and Performance
Hosting
Grav runs anywhere PHP runs. Shared hosting, VPS, or even Docker.
- Requirements: PHP 7.4+ (8.1+ recommended), modest RAM.
- No DB: This saves money. You don’t need an RDS instance or a managed SQL server.
Performance at Scale
Can a flat-file CMS scale? Yes, but with caveats.
- Small/Medium Sites (< 1000 pages): Grav is faster than almost anything else.
- Large Sites (10,000+ pages): The initial cache build can be slow. Grav 1.7 introduced “Flex Objects,” a new data type designed to handle large datasets (like user directories or product catalogs) more efficiently, bridging the gap between flat-file and database performance.
Caching Strategy
Grav has a multi-layer cache:
- File Cache: Compiled configuration.
- Object Cache: Parsed pages.
- Twig Cache: Compiled templates.
You can configure the backend driver (File, APCu, Memcached, Redis) in
system.yaml. For production, enabling Gzip and CSS/JS minification (built-in) is a checkbox away.
SEO, Performance, and Content Governance
SEO
Grav is SEO-friendly by default because it outputs clean, semantic HTML.
- Metadata: Titles, descriptions, and OpenGraph tags can be managed via the Admin plugin or directly in YAML frontmatter.
- Routing: URLs are human-readable and map directly to the file system.
- Plugins: Robust SEO plugins (like the official “SEO” plugin) add sitemaps, canonical tags, and meta robots control.
Content Governance
- Version Control: Since content is text, you can use Git for version history, blame, and rollbacks. This offers a level of governance and auditability that database CMSs struggle to match.
- Multi-User: The Admin plugin supports ACL (Access Control Lists), so you can define groups like “Editors” and “Admins” with different permissions.
Typical Use Cases
1. Documentation Sites
Grav is the engine behind many tech docs. The Markdown-native format makes it perfect for documenting code. The “Learn2” theme is an industry standard for docs.
2. Marketing Microsites
Agencies love Grav for landing pages. You can spin up a site, customize the YAML config, copy a theme, and deploy in hours.
3. Personal Portfolios / Blogs
For developers who want a blog but don’t want to maintain a MySQL database. It offers the “Hacker” feel of a Static Site Generator (SSG) but with the dynamic features (Search, Forms, Comments) of a CMS.
4. Knowledge Bases
Internal Wikis or Help Desks benefit from the speed and searchability of Grav.
Tips and Best Practices
- Install the Admin Plugin: Even if you love the CLI, the Admin plugin helps clients manage content visually.
- Use Blueprints: Blueprints define the form fields in the Admin panel. Use them to create strict content models for your editors.
- Version Control the
user/Folder: Keep yourgrav-admincore separate. Only commit theuser/directory to Git to keep your repo clean. - Leverage Skeletons: Start with a “Skeleton” package (Theme + Content + Plugins) rather than a blank install to save hours of setup time.
- Keep Plugins Updated: Security in Grav is often about keeping the plugin ecosystem up to date.
Who Should (and Should Not) Choose Grav
Best Fit For
- Developers: Who want a simple, fast CMS that feels like writing code.
- Ops-Light Teams: Who don’t want to manage database backups or SQL servers.
- Git-Centric Workflows: Teams that want to deploy content via
git push. - Content-Heavy Sites: Blogs, Docs, and Portfolios.
Not Ideal For
- Massive Scale: Sites with 100,000+ pages might struggle with file I/O limits.
- Complex Relations: If you need heavy Relational Data (Many-to-Many joins across millions of rows), use a database.
- Non-Technical Teams: Without the Admin plugin, the learning curve is steep.
Strengths
- Portability: Zip the folder, unzip it on a new server. Done. Migration is instant.
- Security: No database means no SQL injection. The attack surface is minimal.
- Flexibility: Custom fields are just YAML in your markdown frontmatter. No “Database Schema” to migrate.
- Ecosystem: A rich library of open-source plugins and themes.
Limitations and Trade-offs
- Write Heavy Workloads: If your site has 100 comments per minute or constant user data updates, writing to files concurrently can hit I/O locks. Use a database CMS for that.
- Search: Built-in search scans files. For massive sites, this gets slow. You’d need to integrate Algolia or similar.
- Learning Curve: Understanding the YAML/Twig relationship takes a day or two for non-devs.
Verdict
Grav is the king of the flat-file world. It strikes a perfect balance: simple enough for a personal blog, but architected well enough for complex corporate sites. If you don’t need a database, you probably shouldn’t have one -and Grav is the best way to prove that.