Lektor: a static site generator with an admin UI and a content database
The lektor static file content management system
At a glance
- What is it?
- Lektor builds static HTML from files, but keeps a database and a browser admin panel in the workflow. This review covers what it does, how to install it, and where it stops being the right tool.
- Who is it for?
- Adopt Lektor if your site is mostly content pages with a small team editing them and you want the admin UI rather than a Git-only workflow. Do not adopt it if you need a large plugin ecosystem or a JavaScript component model.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 11 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap Lektor fills between flat files and a full CMS
Most static site generators assume the person editing content is comfortable with a text editor and Git. Most content management systems assume the person deploying is comfortable with a database server and a running application. Lektor sits in the middle: it generates static HTML, but ships a browser-based admin UI and a desktop app, and it stores content in a structured form rather than as loose Markdown files. The README describes it as a static website generator that builds an entire project from static files into individual HTML pages, with a built-in admin UI and minimal desktop app.
The intended user is a developer or a small team that wants to hand editing to someone who will not touch a terminal. That is the specific problem: keeping the deployment model of a static site while giving non-developers a form-based editing surface. It is not aimed at sites that need server-side rendering, per-request personalization, or a plugin marketplace.
How Lektor builds a site: models, templates and a content database
A Lektor project is a directory with a .lektorproject file at the root and a set of conventional subdirectories. The example project in the repository shows the layout: assets/, configs/, content/, flowblocks/, models/, templates/, and themes/. That structure is the architecture. Content lives under content/ as records rather than as pre-rendered pages. Models under models/ define the schema for each content type, so a page is a set of typed fields, not an arbitrary blob of text. Templates under templates/ are Jinja2, which is consistent with the Jinja2>=3.0 dependency listed in pyproject.toml.
The build step walks the content tree, applies the matching model to each record, and renders it through the template. flowblocks/ is the part that differs from a plain file-to-template mapping: it lets a single record contain an ordered sequence of typed blocks, so an editor can compose a page from parts in the admin UI rather than filling one fixed set of fields. The admin UI is a Flask application (Flask and Werkzeug>=2.1.0 are both dependencies) served locally by the lektor server command. The front-end assets for that UI live in lektor/admin/static and, per the README, are built as part of the Python distribution build process.
Installing Lektor and starting a project
The README does not give end-user installation steps. It points to the official documentation for Installation and Quickstart at getlektor.com. What the repository does tell you is the packaging: the project is named Lektor on PyPI, the console script entry point is lektor = "lektor.cli:main", and requires-python is >=3.10. So the supported interpreter range is Python 3.10 through 3.14 according to the classifiers.
The commands below are taken from the development section of the README, which assumes Python, npm and uv are installed. This is the contributor path, not the end-user path, and it is the only concrete set of commands the README provides.
git clone https://github.com/lektor/lektor
cd lektor
python -m venv _venv
. _venv/bin/activate
pip install -U "pip>=25.1"
pip install --group dev --editable .The comment in the README is explicit that pip>=25.1 is required for PEP 735 support, which is what the --group dev flag relies on. After the editable install, the lektor command is on the path. The README then shows how to run the server against a copy of the bundled example project.
export LEKTOR_DEV=1
cp -r example example-project
lektor --project example-project serverSetting LEKTOR_DEV=1 puts the server in development mode. The --project flag points at the copied example directory. Running server starts the local admin UI and preview, which is what the screenshot in the README shows. If npm is not available in your environment, the README documents an escape hatch for the front-end asset build.
HATCH_BUILD_NO_HOOKS=true pip install --group dev --editable .That variable disables the build hooks, which means the admin front-end resources in lektor/admin/static will not be regenerated. The README frames this as useful when npm is not available, but the obvious consequence is that you get a Python install without freshly built JavaScript and CSS for the admin panel.
Where Lektor is the wrong choice
The admin UI is a local Flask application, not a hosted service. The README describes a server command and a desktop app, and there is no mention of a multi-user authentication layer, roles, or a remote editing backend. If your requirement is several editors logging into a shared hosted CMS from different machines, Lektor does not provide that out of the box, and the repository does not document one.
The second constraint is the plugin surface. pyproject.toml lists a normal set of runtime dependencies (Babel, click, Flask, Jinja2, MarkupSafe, marshmallow, mistune, Pillow, python-slugify, requests, watchfiles, Werkzeug), and the repository has no plugins/ directory at the top level. The README points to the example folder as the showcase of features rather than to an extension index. If your selection criteria include a large catalogue of third-party plugins for search, image pipelines, or deployment targets, Lektor's ecosystem is smaller than what you would find around generators that have been adopted more widely. That is a real trade-off, not a defect.
Third, the build pipeline for the admin assets depends on npm. The Makefile has a build-js target that removes lektor/admin/static and runs npm run build inside frontend/, and the README notes the same build happens during the Python distribution build. Anyone packaging Lektor from source in an environment without Node has to either supply the assets or accept the HATCH_BUILD_NO_HOOKS path.
Lektor compared with Hugo and Pelican
The closest comparison in the Python world is Pelican, and the difference is the content model. Pelican reads reStructuredText or Markdown files with metadata headers and renders them. Lektor reads structured records governed by models, which is what makes the admin UI possible: the UI can render a form because the model declares fields. That extra layer is the cost as well. You define models and templates before you get output, whereas a Pelican site can start from a folder of Markdown.
Against Hugo, the difference is language and runtime. Hugo is a single Go binary with no interpreter requirement; Lektor is a Python package with requires-python >=3.10 and a dependency tree that includes Flask, Pillow and watchfiles. Hugo builds faster in most reported comparisons, but Lektor's selling point is not build speed. It is the editing surface. If nobody but you will ever edit the content, you are paying for a feature you will not use.
Maintenance, licensing and upgrade cost
The repository is not archived, and the last push was on 2026-09-19. Recent releases include v3.3.14 and v3.4.0b15, both dated 2026-08-07. The presence of a beta line alongside a stable line means you should decide deliberately which you track. v3.4.0b15 is a beta, so pinning to the 3.3 series is the conservative choice unless you need something specific from 3.4.
Upgrade cost is dominated by the Python version floor. requires-python is >=3.10 and the classifiers run through 3.14, so the project tracks current interpreters. The mistune pin is worth noting: mistune>=0.7.0,<3,!=2.0.* excludes the 2.0 series entirely. If you have another package in the same environment that requires mistune 2.0, you have a conflict to resolve before installing.
Lektor is licensed BSD-3-Clause, with the pyproject.toml declaring license = { file = "LICENSE" } and the classifier "License :: OSI Approved :: BSD License". That is a permissive licence, which generally means you can use and redistribute it with the copyright notice and disclaimer intact. I am not a lawyer and this is not legal advice; read the LICENSE file in the repository for the actual terms, particularly if you plan to redistribute a modified Lektor.
Editorial conclusion
Adopt Lektor if your site is mostly content pages with a small team editing them and you want the admin UI rather than a Git-only workflow. Do not adopt it if you need a large plugin ecosystem or a JavaScript component model. Before committing, verify the Python version your environment provides (requires-python is >=3.10) and check whether the admin front-end assets are present in your installed wheel, since the README notes they are built during the Python distribution build.
Frequently asked questions
What is Lektor?
Lektor is a static website generator written in Python. It builds an entire project from static files into individual HTML pages and includes a built-in admin UI and a minimal desktop app.
What Python version does Lektor require?
The pyproject.toml sets requires-python to >=3.10, and the classifiers list Python 3.10 through 3.14. The README's development instructions also assume Python >= 3.10.
How do I install Lektor?
The README does not give end-user installation steps; it points to the Installation and Quickstart pages at getlektor.com. The repository's own instructions are the contributor path: clone the repo, create a virtual environment, and run pip install --group dev --editable .
What licence does Lektor use?
Lektor is licensed under BSD-3-Clause. The pyproject.toml points the license field at the LICENSE file and carries the BSD classifier.
Does Lektor need Node.js?
The admin front-end resources in lektor/admin/static are built during the Python distribution build, and the README's development instructions require npm. The README documents setting HATCH_BUILD_NO_HOOKS to disable that build when npm is not available.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lektor-lektor)