What lazysite does
The capabilities, by what you are trying to achieve. Each links to how it works.
What lazysite does, grouped by what you are trying to achieve. Each capability links to its 'how it works' reference for the mechanics.
Write pages as plain text and let lazysite turn them into a site. Drop a .md file in the docroot and it is served as a fully rendered HTML page on first request, then cached. No build step, no pipeline. Pages can carry dynamic values - site config, page front matter, computed expressions, conditionals and loops - resolved at render time. Inline shared Markdown partials, code files or remote fragments into a page so common content lives in one place. Includes can fetch remote content and cache it for a set time, so external data appears inline without a fetch on every request. A .url file makes lazysite fetch Markdown from a remote URL (such as a GitHub raw file) and render it through the same pipeline - so docs can live with the code. Wrap content in :::named blocks that become styled containers - callouts, columns, hero sections - without leaving Markdown. Paste a video or social URL and lazysite expands it into the proper embed automatically. A ::: qr block turns a link, a payment URL or a wifi string into a QR code on the page - drawn client-side from a bundled library, with no external service involved. Generate indexes, galleries and menus by scanning a folder of pages and looping over them - with optional filtering by tag, date or path. A built-in search index and results page let visitors find content without an external service. Auto-maintained sitemap.xml and llms.txt registries so search engines and AI agents can discover every page. Read URL query parameters in a page to vary its output - simple dynamic pages with no application code. Serve a page as pure data with api mode, or as an unwrapped fragment with raw mode - the same content reused as an API. List old or alternate URLs in a page's front matter and lazysite redirects them - permanently or temporarily - to the canonical page, so links keep working when content moves. Author your own 404 (and other status) pages as ordinary Markdown. Structure, style and content stay in separate layers that never touch. A layout.tt owns the HTML chrome; a theme on top supplies colours, fonts and assets; content stays in .md files. Swap any layer independently - and if no layout is installed at all, an embedded fallback still renders a complete page. A theme declares its palette and type as tokens in theme.json, auto-emitted as CSS custom properties - re-skin a site by editing values, not stylesheets. Any single page can opt into a different layout from front matter - a landing page or print view without affecting the rest. Install layouts and themes from a catalogue, upload a zip, or pull them from a remote source - activation validates the candidate and snapshots the outgoing version, so a change is easy to reverse. Forms, accounts and payments are built in - no plugins to bolt on. Build a contact, signup or feedback form right in Markdown with the :::form syntax - it works out of the box, validates input, accepts file and image attachments, and delivers to email or a handler. Fully customisable, and no third-party service or code required. Split a longer form into wizard steps with Back/Next navigation and per-step validation - still a single submission, and it degrades gracefully when JavaScript is off. Protect pages or whole sections behind sign-in, with the right state revealed per visitor. Gate content or downloads behind a payment using the x402 protocol, built into the core. The site menu is a plain nav.conf file read by the layout - edit the menu without touching templates. A browser-based manager to edit content, themes, navigation, users, backups and statistics without the command line. Form submissions and requests awaiting a reply land in the manager's notices bell, and can also be delivered over XMPP - so a submission always reaches a human. Publish over WebDAV and a control API - the path an AI agent or script uses to manage a site with no GUI in the loop. Standard WebDAV clients work too, including Windows Explorer and macOS Finder. Power-user features for data-driven pages and feeds - no plugins, no build. Point json:/data/file.json at a local JSON file and it is decoded into a real data structure you can loop over in the page - FOREACH, nested loops, indexed access and .size. The comparison and feature tables on this very site are built this way. The full Template Toolkit is available in pages and layouts: string, list and hash methods (split, join, replace, sort, first, last, size, match and more), computed expressions, and FILTERs such as markdown - real data shaping with no plugin. Register feed.rss and feed.atom in a page's front matter and lazysite emits both, generated from a scan of your pages and kept in sync as content changes - readers and aggregators subscribe directly. Pull a live value from a remote URL with url: (a version badge, an API field), or inline remote Markdown and feeds with includes - external data rendered through the same pipeline and cached for a chosen time. Files on disk, fast by default, and trivial to back up or move. Files are the source of truth. Nothing to provision, dump or migrate - back up by copying the folder. One small CGI script plus a few Perl modules - no database, no application server, no build pipeline. The minimal infrastructure runs on almost anything and costs very little to host. The engine runs entirely on your own server - just Perl and a web server - with no embedded AI and no dependency on any third-party or cloud service to operate. Nothing phones home, and nothing breaks when an outside API changes its terms or disappears. AI publishing is optional and uses an assistant you choose and control, not a service baked in. Dynamic only on the first request; plain cached HTML is served after that, with fine-grained control over caching. For production speed, run the same processor as a per-site FastCGI pool - modules compile once, and a cached page measured at 62 ms as plain CGI serves in 0.4 ms. Plain CGI stays the default and behaves identically. Run in generation mode to produce a fully static site you can host anywhere - the same content, no server process. A built-in server renders any Markdown tree locally with live preview - no install needed to start. Scan the site for broken internal links, orphan pages, missing titles and stale cached copies before you publish. Site-wide settings live in a single lazysite.conf, with overrides where you need them. Everything is a file, so the whole site - content, layout and theme - lives in a git repository. Switch on the Content history plugin and every edit - by a person or an agent - becomes a version you can view, diff and restore from the manager, with optional sync to a private git remote you control. Take content or full-system backups from the manager and restore content in-app; a full-system restore can rewrite the domain, moving a whole site - content, config and accounts - to its final home in one command. Install lazysite over a live HTML site without losing anything - existing pages carry on being served, and each one migrates to Markdown when you are ready, page by page. Lazysite records its own traffic - anonymised at write, never storing the IP - so the statistics dashboard works out of the box, with no web-server log access and no third-party analytics service. A health checker probes permissions, configuration and secrets exactly as the web server sees them, fixes what it can, then re-checks and reports the result. Install from Debian packages with a lazysite CLI for provisioning and upgrades, one-command domain onboarding on HestiaCP, and a zero-configuration demo command that serves a scratch site locally. Each site declares the release maturity it accepts - edge, beta or stable - and whether upgrades apply automatically; fleet-wide upgrades respect every site's policy, with an override reserved for critical security fixes. Releases are built by a gated pipeline - full test suite, coverage floors, security lints and a software bill of materials - and the stable line carries a declared five-year support period. One install can serve many domains and many languages - each first-class, all under one set of accounts. Host multiple first-class domains on a single install, each with its own content root, navigation and settings - confined from one another, managed through one engine and one set of accounts. Delegate a domain to a group so its members manage that site's content and settings - with a preview that works before DNS even points at the server, and a panel that checks DNS, certificates and proxy wiring. Publish the same site in several languages as linked per-language content roots - lazysite supplies the language switcher data, hreflang tags, localised page chrome and a translation-coverage report. Decide exactly who can do what, lock content down, and keep a record of every change. Channel-by-action grants carried by groups control exactly what each user or token can do - edit content, manage themes or layouts, change config, create sub-users. An account's rights are the union of its groups, checked once, server-side, across every surface. Map any path to an owner with read and write lists (users or groups). Access only ever narrows, the owner is always allowed, and the same check binds the manager, WebDAV and the AI connector. Lock a file so no one else can alter it. One lock store is shared across the manager and WebDAV, so a save anywhere respects a live lock. Accounts and machine tokens can carry an expiry, after which access fails closed - useful for time-boxed contributors and partners. A partner can mint scoped sub-accounts; onward delegation requires holding the capability itself, so nobody can grant more authority than they have. See every live session - who, since when, from where, on what device - and sign out a single session, one user everywhere, or rotate the secret to sign out everyone at once. An append-only log records who changed what, to what, when, from where, and the outcome - material changes only, never browsing. Optional TOTP second factor with recovery codes, self-contained with no external dependency. Repeated probes for wp-login.php, .env and the like get the source IP blocked automatically - on by default, with blocked addresses listed and unblockable from the Stats page. An account that can reach the manager is refused on the API and MCP transports, so a leaked or misissued token on a manager account cannot drive the site remotely. Scripts, secrets and credential files can never be read or written through the content tools - a hard deny-list, enforced on reads as well as writes. Built for a human/AI partnership - agents publish through the same rules a person does. An agent or script edits content over WebDAV and a JSON control API - no GUI in the loop - bound by exactly the same capabilities and ACLs as any human author. An AI agent can read the site's own visitor analytics - aggregated and IP-anonymised, with real people separated from bots and crawlers - to see which content actually engages, then act on it: sharpen the copy, reorder or add pages, retune the layout or theme, and measure again. A continuous analyse-and-improve loop, run through the same publishing rules and permissions a person uses. A built-in connector speaks the Model Context Protocol, so assistants such as Claude and ChatGPT can manage a site through first-class tools. Agents validate a page before it goes live - with a warning when content looks private, such as phone numbers or wifi passwords - preview it exactly as a visitor will see it, and audit the whole site for problems. Web-based AI connectors authenticate via a minimal OAuth 2.1 server with PKCE - the person proves they may act as a partner, and no secret is ever typed into the third party. Every door - browser, API, WebDAV, MCP - translates to the same shared handlers, so a lock, an ACL or a capability holds identically whoever knocks.Authoring & content
Markdown, served instantly
Template Toolkit variables
Reusable content includes
Cached remote includes
Pull in remote pages
Rich layout blocks (fenced divs)
Embed media (oEmbed)
QR codes in content
List and scan pages
Site search
Sitemaps & registries
Dynamic pages from query parameters
JSON & API output
Page aliases & redirects
Custom error pages
Design: layouts & themes
Layouts and themes
Design tokens
Per-page layout override
Install & publish themes
Dynamic & interactive
Customisable forms, built in
Multi-step forms
Authentication & access control
Payments (x402)
Navigation from a config file
Web manager UI
Operator notifications
WebDAV & AI publishing
Advanced data & templating
JSON data files
Template Toolkit helpers
RSS & Atom feeds
Remote data & JSON
Operate & maintain
No database
Tiny footprint, low cost
Self-contained, no external services
Fast by default
Persistent worker pools
Static export
Local dev server
Link auditing
Configuration in one file
Version-control ready
Content version history
Backups & site migration
Overlay an existing site
First-party visitor analytics
Built-in site doctor
Packaged installs
Release channels & fleet updates
Audited releases, five-year support
Multi-site & multilingual
Many domains, one instance
Domain delegation
Multilingual sites
Access, permissions & governance
Fine-grained capabilities
Per-file access control
File locking
Account & token expiry
Sub-users & delegation
Session visibility & revocation
Audit trail
Two-factor authentication
Automatic scanner blocking
Manager access stays interactive
Protected internals
AI & automation
AI publishing over WebDAV & API
Analytics-driven improvement loops
MCP AI connector
Pre-publish safety checks
OAuth for AI partners
One enforced core
Beyond the capabilities above, see how lazysite is engineered - the testing, security and quality practices behind them.