Pico is a stupidly simple, blazing fast flat-file CMS written in PHP. There is no database, no complex setup — just Markdown files that become web pages. It is perfect for small websites, documentation, and personal projects where you want simplicity without sacrificing flexibility.
Why Pico CMS?
- No database: Content stored as Markdown files — easy to version control and back up
- Minimal footprint: The entire CMS is under 1MB
- Fast: No database queries means near-instant page loads
- Twig templates: Powerful, easy-to-learn templating engine
- Plugin system: Extend functionality without bloat
Installation
# Install via Composer
cd /var/www
composer create-project picocms/pico-composer my-pico-site
cd my-pico-site
# Directory structure
my-pico-site/
├── assets/ # CSS, JS, images
├── config/ # Configuration files
│ └── config.yml # Main config
├── content/ # Markdown content files
│ ├── index.md # Homepage
│ └── sub.md # /sub page
├── plugins/ # Pico plugins
├── themes/ # Twig templates
│ └── default/
│ └── index.twig
└── vendor/ # Composer dependencies
Configuration
# config/config.yml
site_title: My Website
base_url: https://yourdomain.com
theme: my-theme
timezone: America/New_York
date_format: "%B %e, %Y"
# Content settings
pages_order_by: date
pages_order: desc
# Rewrite URL (remove index.php)
rewrite_url: true
Creating Content
# content/index.md
---
Title: Welcome to My Website
Description: A fast, simple website powered by Pico CMS
Template: index
---
## Welcome
This is my website built with Pico CMS. It's fast, simple, and
powered entirely by Markdown files.
### Features
- No database required
- Lightning fast page loads
- Easy to maintain and update
# content/blog/my-first-post.md
---
Title: My First Blog Post
Date: 2026-03-15
Author: John Doe
Template: blog-post
Tags: tutorial, getting-started
---
This is my first blog post. Pico makes it incredibly easy to
create content — just write Markdown files and they become pages.
## Code Example
You can include code blocks:
```bash
echo "Hello from Pico CMS!"
```
Custom Themes with Twig
<!-- themes/my-theme/index.twig -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ page_title }} | {{ site_title }}</title>
<meta name="description" content="{{ meta.description }}">
<link rel="stylesheet" href="{{ theme_url }}/css/style.css">
</head>
<body>
<nav>
<a href="{{ "index"|link }}">{{ site_title }}</a>
<ul>
{% for page in pages if not page.hidden %}
<li><a href="{{ page.url }}"
class="{{ 'active' if page.id == current_page.id }}">
{{ page.title }}</a>
</li>
{% endfor %}
</ul>
</nav>
<main>
<h1>{{ meta.title }}</h1>
{{ content }}
</main>
<footer>
<p>© {{ "now"|date("Y") }} {{ site_title }}</p>
</footer>
</body>
</html>
Nginx Configuration
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
root /var/www/my-pico-site;
index index.php;
# Clean URLs — rewrite to index.php
location / {
try_files $uri $uri/ /index.php?$uri&$args;
}
# Block access to sensitive directories
location ~ /(content|config|vendor|plugins) {
deny all;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Cache static assets
location /assets/ {
expires 30d;
add_header Cache-Control "public";
}
location /themes/ {
expires 30d;
add_header Cache-Control "public";
}
}
Best Practices
- Use Git for content: Track your Markdown files in a repository for version history
- Block sensitive directories: Ensure /content, /config, and /vendor are not web-accessible
- Create custom Twig templates for different page types (blog post, landing page, docs)
- Use Pico plugins for features like pagination, search, and sitemaps
- Cache with Nginx: Pico is already fast, but Nginx caching makes it even faster