# Nesta: a file based CMS and static site generator that keeps content in plain text

> Nesta is a lightweight Ruby CMS built on Sinatra that stores posts and pages as Markdown or Textile files that you edit in your own text editor, with no database, and can publish either as a static site or as server-rendered HTML. It suits people who already write in an editor and want Git to be the deployment story.

**gma/nesta** — File Based CMS and Static Site Generator

- Repository: https://github.com/gma/nesta
- Website: http://nestacms.com
- Stars: 899 · Forks: 121
- Language: Ruby
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/gma-nesta

## Content as files, with no database in the picture

Nesta is a lightweight CMS for building content sites and blogs, written in Ruby using the Sinatra web framework. The description in the README is plain: a file based CMS and static site generator.

The design choice that defines it is that content lives in text files on your hard drive, and there is no database. You write posts and pages in Markdown or Textile, in your text editor, and you can drop into HTML or Haml if you need more control over a particular file. The publishing step is putting those files online, with Git recommended but not required.

That last point is the one that determines who this is for. A CMS with a database gives you an admin interface, a login form, a media library and a set of write permissions. A file based CMS gives you the editing power of your own editor, the diffing and history of a version control system, and the ability to script changes. What it gives up is the ability for a non-technical person to publish without a text editor.

The audience, then, is writers and developers who are comfortable in an editor, and small teams who want the site content to live in the same repository as the code. The project's own vocabulary is plugin oriented. The README asks that new features be discussed as an issue first, and mentions that a feature might be better implemented as a plugin to keep Nesta itself lean and simple. That is a strong signal about the shape of the project: the core stays small and the extension points do the work.

The topic list on the repository names the stack plainly, with sinatra, ruby, haml, sass, markdown and textile all present, and the file based CMS and static site generator labels alongside them.

## Two publishing paths from the same content directory

Nesta can be deployed in two ways, and this is the decision that shapes the rest of your setup.

The first is a static site. The README describes deploying behind a web server, or building a static version of the site, and the build is a single command:

```bash
    $ nesta build  # but see config.yml for build settings
```

The comment in that line matters. The build settings live in the site's configuration file, config/config.yml, and the README points you there for what the build actually does.

The second is server-side rendering, where HTML is rendered on the server rather than pre-generated. Because the same content directory feeds both, choosing one does not lock you out of the other later, but it does decide what you are deploying: a directory of static files, or a Rack application that Sinatra serves. The project supports both behind the same `nesta` command-line tool.

The other piece of the publishing story is the content itself. The README's advice is to publish changes by putting the files online, with Git recommended but not required. So a deployment is a commit and a push in the Git case, or a file copy in the other case. That makes the hosting question separate from the CMS question, and it means the site can go to any host that serves files or runs a Rack app, rather than to a platform with a proprietary content store.

This is where the project differs most from the database-backed alternative. There is no admin panel to deploy, secure and maintain, and no content API for a separate front end to consume. There is a directory of files and a decision about how to serve them.

## From gem install to a local server on port 8080

The installation path in the README is short enough to follow without further reading.

First, install Ruby, then the Nesta gem:

```bash
    $ gem install nesta
```

Then use the `nesta` command to generate a new site, with a git repo optional but recommended:

```bash
    $ nesta new mysite.com --git
```

The generated site is a directory named after your domain, with its own Gemfile. Install the dependencies with bundler:

```bash
    $ cd mysite.com
    $ bundle
```

Configuration lives in config/config.yml, and the README is explicit that the defaults will work but that you will want to tweak them before going very far. That file is the place where the build settings the `nesta build` command refers to are defined, so it is worth reading early rather than at deploy time.

For local work, the project uses the `mr-sparkle` dev server, launched through the config.ru file at the project root:

```bash
    $ bundle exec mr-sparkle config.ru
```

Point a browser at http://localhost:8080 and you are looking at the site. The README tells you to start editing the files in `content/pages`, and links to the documentation on creating content for the full instructions.

So the loop is: write a file in content/pages, reload the browser, and the development server picks it up. There is no publish button anywhere in that loop, and that is the point of the design.

## A plugins model, and a core that is meant to stay small

Nesta's approach to extending itself is visible in how the maintainer asks for contributions. The README says that if you want to add a new feature, consider creating an issue so there can be a conversation before coding starts, and that the maintainer might contribute ideas on how to approach it, or suggest that the feature be implemented as a plugin, explicitly to keep Nesta itself lean and simple.

That is a small project with a stated philosophy, and it has a practical consequence. A plugin-based CMS with a small core is easy to reason about and easy to upgrade, because there is less of it to break. It is also a smaller surface for third-party code, which matters when the extension points run inside your publishing process.

The repository layout supports the same picture. The tree has a lib/ directory for the library code, a config/ directory, a views/ directory for templates, a templates/ directory for the files that get copied into a new site, a bin/ directory for the command-line entry point, a test/ directory, a scripts/ directory, a Rakefile, a Gemfile and Gemfile.lock, a nesta.gemspec, a .rubocop.yml for style rules, a Guardfile for file watching, a config.ru at the root for Rack, a CHANGELOG.md, a RELEASING.md and a .gitmodules file.

The presence of a rubocop configuration and a Guardfile says something about the development workflow: style is enforced automatically, and the Guardfile indicates a watch-and-run loop for tests during development. The tests themselves are wired into CI, since the README carries a Tests badge pointing at a workflow named tests.yml.

The .gitmodules entry is worth a second look in a project whose own documentation recommends Git for publishing. It means at least part of the content or templates lives in a separate repository, which is a reasonable pattern for shared themes across several sites, and also a place to look if a site is missing content that the main repository does not contain.

## A single maintainer, no tagged releases, and a licence that stays simple

On maintenance, the repository is not archived and the last push was on 2026-06-23, on the main branch. The repository has no GitHub releases at all, so there are no version tags to point at, and the versioning happens through the gem.

That has a concrete consequence for you. The version you get is the one your Gemfile resolves, and because the project does not publish tagged releases on GitHub, the CHANGELOG.md at the repository root and the gem's own version history are where the release information lives. For a site that must keep working, pinning the version in the Gemfile and reading the changelog before upgrading is the responsible routine, and the presence of a RELEASING.md file in the repository root suggests the maintainer keeps a defined release process even though it does not produce GitHub tags.

The licence is MIT, held in a LICENSE file at the root of the tree. That is the permissive end, with no copyleft condition on sites you build and host, and no obligation to publish anything you derive from it. This review does not interpret licence terms, and no commercial terms are mentioned in the README.

The support story is correspondingly small. The README points to nestacms.com for documentation, suggests filing an issue on GitHub, and gives a Mastodon contact. The contributing section is written in the first person by the maintainer, Graham, and asks for an issue before code. For a project with one maintainer, that is a real constraint on how quickly issues get resolved, and it is worth knowing before you depend on it for something urgent.

For a blog or a small content site, none of that is a problem. For a site that is a dependency of a business process, it is the main thing to weigh.

## Conclusion

Nesta fits a writer or a small team who wants content in plain text files, versioned in Git, and a site that can be published either as static files or rendered on the server, and the three command install path makes a first site reachable in minutes. It is the wrong choice for a team that wants a database-backed admin interface, for non-technical editors who would rather not touch a text editor, or for anyone who needs a plugin ecosystem beyond what a handful of plugins can cover, since the project asks that new features be discussed as issues first and keeps the core lean. Before you adopt it, read the CHANGELOG.md in the repository root for the changes since the version you used, decide between the SSG and SSR deployment paths before writing content, and note that the repository has no tagged releases, so the version your Gemfile resolves is the version you have to pin.

## FAQ

### How do I install Nesta and create a new site?

Install Ruby, then run `gem install nesta`, use `nesta new mysite.com --git` to generate the site, `cd mysite.com` and `bundle` to install its dependencies. The README says a git repo is optional but recommended.

### How do I preview a Nesta site locally?

Run `bundle exec mr-sparkle config.ru` from the project root and open http://localhost:8080. You then edit files in `content/pages` and the development server picks up the changes.

### Does Nesta need a database?

No. The README states that files are stored in text files on your hard drive and that there is no database, with content written in Markdown or Textile and published by putting the files online.

### Can Nesta build a static site as well as render on the server?

Yes. The README describes deploying behind a web server or building a static version of the site, and the build is run with `nesta build`, with build settings taken from config/config.yml.

### How do I add a feature to Nesta?

The README asks that you create an issue first so there can be a discussion before coding, and notes that a feature might be better implemented as a plugin so that Nesta itself stays lean and simple.

## Sources

- [gma/nesta on GitHub](https://github.com/gma/nesta)
- [Issues](https://github.com/gma/nesta/issues)
- [License: MIT](https://github.com/gma/nesta/blob/main/LICENSE)
- [Project website](http://nestacms.com)
- [README](https://github.com/gma/nesta/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gma-nesta
