---
title: "For developers"
description: "The developer guide: database-free architecture, tests, the archive, customizing the Éclair CMS theme, Nginx configuration and contributing."
url: "https://eclaircms.org/en/documentation/developers"
lang: "en"
author: "Thierry Gustin"
published: "2026-10-30"
updated: "2026-10-30"
---

# For developers

> **Key takeaways** — Éclair is written in PHP 8.1+ with no framework and no Composer: a front controller that serves the static cache, flat-file storage in protected files, plain classes and vanilla JavaScript. You customize the Éclair CMS theme in app/theme; 299 automated checks and a build tool come with the code, under the MIT license.

Éclair is written in PHP 8.1 or later, with no framework and no Composer: plain classes in `app/lib/`, PHP views and vanilla JavaScript. This guide explains its architecture, how to run the tests and build an archive, how to customize the Éclair CMS theme without breaking security, and how to serve it with Nginx.

## How is Éclair built?

Three ideas make it light and fast:

1. **A front controller that serves the cache without loading the application.** `index.php` first looks for the requested page in `cache/pages/` and sends it directly, with its headers and ETag (a `304` response if nothing has changed). The application only loads for a page that isn’t cached yet, the admin or the installation.
2. **Flat-file storage, with no database.** Each piece of data is a `.php` file that starts with `<?php exit; ?>`, followed by JSON. Writes are atomic (temporary file, then rename), private (0600) and done under an exclusive lock for read-modify-write operations. `data/index.php` keeps a summary of all content for fast listing and routing.
3. **Blocks validated, then rendered.** Each block is validated and sanitized against an allowlist, then rendered as HTML, exported as Markdown for GEO and analyzed for SEO.

The result: a 402 KB archive, zero dependencies, and pages served in 0.7 ms in our local measurements.

## What’s in the eclair folder?

```text
eclair/                  ← upload this to your hosting
├── index.php            front controller (serves the cache without loading the application)
├── .htaccess            rewriting, protections, compression, browser caching
├── app/lib/             code (Eclair\… classes): Content, Blocks, Seo, Analyzer, Media, Auth…
├── app/admin/views/     admin screens
├── app/theme/           public site templates + theme.css (inlined in every page)
├── app/lang/            admin translations (6 languages, compressed JSON)
├── assets/admin/        admin CSS and JavaScript (no dependencies)
├── assets/site/site.js  the only public script (2.4 KB, 1.2 KB compressed)
├── data/                content, settings, accounts (created at installation, never public)
├── cache/               generated pages
└── media/               uploaded images
```

In the repository, `i18n/` holds the human-readable translation sources, `tests/` the tests and `tools/` the development router and the build tool.

## How do you run Éclair locally?

From the repository, PHP’s built-in server is all you need:

```bash
PHP_CLI_SERVER_WORKERS=4 php -S localhost:8000 -t eclair tools/router.php
```

`tools/router.php` reproduces the `.htaccess` rules. `PHP_CLI_SERVER_WORKERS` lets the site call itself to verify its address: with a single process, the check simply fails and redirects to the official address stay disabled. To try it without the command line, see [Try Éclair on your computer](https://eclaircms.org/en/installation/local).

## How do you run the tests?

```bash
php tests/run.php          # 299 unit and HTTP checks
php tests/run.php --unit   # unit tests only
```

The integration tests start a real PHP server and replay a large part of the attacks from the security review. `tests/fake-ai.php` simulates the AI providers (Claude, ChatGPT, images): the assistant is tested with no key and no spending.

## How do you build a distributable archive?

```bash
php tools/build.php
```

The tool recompiles the translations from `i18n/`, computes the SHA-256 fingerprint of each file in `app/manifest.php` (the reference for the integrity check), then creates `dist/eclair-cms-<version>.zip` with the LISEZ-MOI readme, the license and the third-party notices.

## How do you customize the Éclair CMS theme?

The public site is rendered by the templates in `app/theme/`:

| File | Role |
| --- | --- |
| `layout.php` | Main template: header, menu, footer |
| `single.php` | A page or a post |
| `list.php` | Blog, categories, author pages and search |
| `cards.php` | The grid of post cards |
| `404.php` | The page-not-found page |
| `theme.css` | The styles, minified then inlined in every page |

Appearance settings become CSS variables your theme can reuse: `--accent`, `--on-accent`, `--link`, `--link-dark`, `--font` and `--font-head`. Dark mode goes between the `/*dark*/` and `/*/dark*/` comments: Éclair removes this block when the “Always light” setting is chosen.

> **Respect the security policy** — The public site’s Content-Security-Policy forbids inline scripts: put your JavaScript in a file under `assets/`. For styles, only the theme’s `<style>` tag is allowed, thanks to its automatically computed SHA-256 hash; `style=""` attributes are blocked.

Keep a copy of your templates: the integrity check will flag them as modified, which is expected, and an Éclair update replaces them (see [Updating](https://eclaircms.org/en/documentation/updates)). The eclaircms.org site you’re reading is itself built with Éclair and a custom theme: sticky menu, documentation with a sidebar menu, previous and next pages.

## How do you serve Éclair with Nginx?

Éclair doesn’t need `.htaccess` on Nginx, but you have to reproduce these rules:

```nginx
location ~ ^/(app|data|cache)(/|$) { return 404; }
location ~ /\.(?!well-known/) { return 404; }
location ^~ /media/ {
    location ~* \.(php\d?|phtml|phar|s?html?|svgz?|xml|js)$ { return 404; }
    add_header X-Content-Type-Options nosniff;
    expires 1y;
}
location ~* \.(webp|avif|jpe?g|png|gif|ico|css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location / { try_files $uri /index.php$is_args$args; }
location = /index.php {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}
location ~ \.php$ { return 404; }
```

To have the AI assistant’s replies stream in as they’re written, add `fastcgi_buffering off;` to the PHP block.

## Which PHP versions and extensions do you need?

Éclair runs on **PHP 8.1 to 8.5**; 8.3 is recommended. The `mbstring`, `json`, `dom` and `session` extensions are required. `gd` (WebP images), `zip` (backups), `curl` (IndexNow and the AI assistant), `zlib` (translated admin) and `sodium` or `openssl` (assistant keys) are recommended. The setup wizard checks all of this.

## How do you contribute to Éclair?

The code is public on [GitHub](https://github.com/Jacckisback/eclair-cms): report a bug or suggest an idea in the issues, or send a pull request with tests. Éclair is released under the MIT license; some admin icons are derived from [Lucide](https://lucide.dev), under the ISC license. You can also support the project on the [Donate](https://eclaircms.org/en/donate) page.

## Developer questions

### Do I need Composer or Node.js to develop on Éclair?

No. Éclair has no dependencies: PHP 8.1 or later is enough to run the site, the tests and the build tool.

### Can I create my own Éclair CMS theme?

Yes: edit the templates in app/theme and the theme.css file. Respect the security policy (no inline scripts) and keep a copy of your files, which an update would replace.

### Where is the content stored?

In data/content, one file per piece of content, in JSON format preceded by the protection line. data/index.php keeps a summary of it for fast listing and routing.

### How do I add a translation of the admin?

The human-readable sources are in the repository’s i18n folder, with the French text as the key. tools/i18n.php compiles them into compressed files, and php tools/build.php does it automatically.
