Under the surface

Here is how Gansey works.

A content system built like a tool

One binary. One database. The whole site.

Gansey is a compiled CMS. Each site is a single executable with Postgres underneath and pages rendered on the server. Clients edit the real page in front of them, and modules are plain code you can read in one sitting.

Ahoy! Every Gansey site is one binary.

1binary per site
3platforms: Linux x86_64, Linux ARM64, macOS on Apple silicon
Postgresand nothing else to run
0requests to other hosts from a public site
Why Gansey

Small on purpose, so a brochure site never carries a shop.

One binary per site

Copy it to a server, point it at Postgres, done. The admin lives inside the same executable.

Edit the page you can see

Sections, columns and widgets on the live rendered page, with every save kept as a revision.

Modules you can read

Models, routes, admin screens, widgets and jobs in Gansey's own small language, with permissions declared up front.

Theme kits

Colours, type, buttons and layout as one package. Clients can change any of it and see the result straight away.

Media handled for you

Sizes generated on upload, with WebP and AVIF when you want them. Everything is served by the site itself.

Roles that fit the client

Custom roles with sensible presets. Password, two-factor and emailed sign-in links.

Modules

Plain code, installed with one command.

Every module is a folder with a manifest, an entry file and templates. Braces, fn and let, with Result and ? so errors are handled rather than hoped away. Save the file and the module re-runs.

The registry lists every official module and theme kit, with what each one may touch before you install it.

// modules/blog/main.gansey
fn init(ctx) -> Result<(), Error> {
  ctx.db.migrate("posts", 1, |t| { t.text("title"); t.bool("published"); })?;
  ctx.routes.get("/blog", archive)?;
  ctx.widgets.register("blog-feed", { label: "Blog feed" }, feed)?;
  Ok(())
}

fn archive(req) -> Result<Html, Error> {
  let posts = ctx.db.find("posts", { where: { published: true } })?;
  match posts.len() {
    0 => Ok("<p>Posts coming soon.</p>"),
    _ => ctx.render("archive.html", { posts: posts }),
  }
}
Docs

Every part of Gansey, written down.

Setting up a site, building it in the page builder and the theme, running it with updates and backups, and writing modules in Gansey Script. One thing to a page, with the commands and settings it needs.

  • Install and configure a site
  • Pages, the builder and the theme
  • Updates, backups and the command line
  • Modules and Gansey Script
Updates and licences

Hosted or self-hosted, the site keeps running.

Self-hosted

Paid core updates

Run Gansey on your own server. Core updates are paid for.

  • Core updates are a paid subscription
  • Pricing to be confirmed
  • Modules: details to be confirmed

Already a Gansey client?

Check which updates your site is covered for with the licence key from its Updates screen.