krz/orgo

Lightning fast org-mode static site generator.

clone: git clone https://gitbay.org/krz/orgo.git

v0.20.2: README.md · raw

  1# orgo
  2
  3Turn a folder of org files into a website.
  4
  5You write posts the way you already do — an `.org` file per page, in whatever directory
  6structure suits you — and orgo builds a complete site from them: pages, navigation, a blog
  7index, tags, an RSS feed, syntax-highlighted code. It is one binary with nothing to
  8install alongside it, and **you do not need Emacs to build your site**, only to write in a
  9format Emacs made.
 10
 11Org is the source language here, not something to convert away from first. Tools that
 12route org through markdown lose what markdown has no words for — property drawers, a
 13heading's TODO state and tags, `#+` keywords, ID links, captions on images. orgo keeps all
 14of it, and its output is checked page by page against what Emacs' own exporter produces
 15from the same file.
 16
 17**Documentation: <https://krazywarez.github.io/orgo/>** — that site is written in org and
 18built by orgo, so it doubles as the longest worked example available.
 19
 20## Install
 21
 22You need [Rust](https://rustup.rs) (1.88 or newer). Nothing else — syntax highlighting and
 23its themes are compiled in.
 24
 25```sh
 26cargo install orgo
 27```
 28
 29Or from a checkout, if you want to build the version you can read:
 30
 31```sh
 32git clone https://github.com/krazywarez/orgo
 33cd orgo
 34cargo install --path .
 35```
 36
 37Either way you get an `orgo` command on your `PATH`. Full notes, including how to run it
 38without installing anything: <https://krazywarez.github.io/orgo/install.html>
 39
 40## Your First Site
 41
 42```sh
 43orgo init my-site
 44orgo serve my-site -o _site
 45```
 46
 47Open <http://127.0.0.1:3000>. Edit `my-site/index.org`, save, and the page reloads on its
 48own — that is the loop you will spend your time in.
 49
 50`init` writes a starter post, a page layout you can edit, and a config file with every
 51setting explained in comments. It never overwrites a file you already have.
 52
 53## Org-Mode, Anywhere
 54
 55```sh
 56orgo build ~/notes -o _site
 57```
 58
 59No config file, no templates, no orgo-specific markup in your files. You get a real site:
 60every page, links between them resolved, navigation across the top, code highlighted. That
 61is a supported way to use it rather than a demo — configuration changes what you get, it
 62is never what makes it work.
 63
 64Nothing that should stay private is published: dot-directories like `.git`, your templates
 65and the output folder itself are all skipped.
 66
 67Want to know what orgo will make of your files before trusting it with them?
 68`orgo audit ~/notes` reports which org constructs you use and how each one lands, with
 69counts and line numbers — never the text of your writing, so the report is safe to share.
 70
 71## Additional Features
 72
 73Each of these is a few lines of config, and each has a page in the guide:
 74
 75| Add | Documented in |
 76|---|---|
 77| A blog index, newest first | [Collections](https://krazywarez.github.io/orgo/guide/03-collections.html) |
 78| Tag pages, and an index of tags | [Collections](https://krazywarez.github.io/orgo/guide/03-collections.html) |
 79| An RSS feed | [Collections](https://krazywarez.github.io/orgo/guide/03-collections.html) |
 80| Numbered pages when a list gets long | [Collections](https://krazywarez.github.io/orgo/guide/03-collections.html) |
 81| Your own design, in ordinary HTML templates | [Templates](https://krazywarez.github.io/orgo/guide/04-templates.html) |
 82| Drafts that stay unpublished until you say so | [Authoring](https://krazywarez.github.io/orgo/guide/06-authoring.html) |
 83| A table of contents on long posts | [Authoring](https://krazywarez.github.io/orgo/guide/06-authoring.html) |
 84| Clean URLs that survive a renamed file | [Authoring](https://krazywarez.github.io/orgo/guide/06-authoring.html) |
 85
 86Rebuilds only touch the pages that actually changed, so saving a post on a site with
 87hundreds of them stays instant.
 88
 89## Speed
 90
 91Publishing one real site ([cleberg.net](https://cleberg.net)) — 178 org files, ~180 pages — three ways. Median of three runs
 92each, measured back to back on one machine:
 93
 94| | Time | |
 95|---|---|---|
 96| weblorg (`emacs --script publish.el`) | 49.0s | |
 97| weblorg + [build.py](https://github.com/ccleberg/cleberg.net/blob/8ec9cdfeae71068a8924dd9f61b9cc28c947ec31/build.py) | 50.3s | |
 98| orgo, cold build | **0.22s** | 223× faster |
 99| orgo, nothing changed since last build | **0.13s** | 377× faster |
100
101That middle row is the interesting one. weblorg alone does not group a blog index by year,
102write a tags page, rewrite image URLs, minify CSS or emit a sitemap — so I
103wrote ~600 lines of Python to do those on top of it. orgo does four of the five natively —
104the sitemap included, since writing this table is what prompted it.
105
106Read the numbers with three things in mind. The weblorg figures include Emacs starting and
107loading its packages, which you pay on every publish and cannot avoid. orgo emits 13 pages
108weblorg does not, one per tag, so it is doing slightly more work. And the two do not
109produce byte-identical output — the differences are deliberate and listed under
110[Org support](https://krazywarez.github.io/orgo/guide/05-org-support.html).
111
112Apple M2 Pro, 12 cores, macOS 26.6, Emacs 30.2, orgo built with `--release`.
113
114## Docs
115
116<https://krazywarez.github.io/orgo/>
117
118| Page | What is in it |
119|---|---|
120| [Quick start](https://krazywarez.github.io/orgo/quickstart.html) | A working site in two commands, then your own writing, then your own design. |
121| [Install](https://krazywarez.github.io/orgo/install.html) | Getting the binary, and running it without installing anything. |
122| [Commands](https://krazywarez.github.io/orgo/guide/01-cli.html) | Every command and flag, and what each is for. |
123| [Configuration](https://krazywarez.github.io/orgo/guide/02-configuration.html) | Every setting in `orgo.toml`, what it changes, and what it costs. |
124| [Collections](https://krazywarez.github.io/orgo/guide/03-collections.html) | Blog indexes, tag pages, pagination and RSS feeds. |
125| [Templates](https://krazywarez.github.io/orgo/guide/04-templates.html) | Layouts, and every variable a template can use. |
126| [Org support](https://krazywarez.github.io/orgo/guide/05-org-support.html) | Which org syntax is handled, which is not, and how the rest degrades. |
127| [Authoring](https://krazywarez.github.io/orgo/guide/06-authoring.html) | URLs, drafts, excerpts, tables of contents. |
128| [Incremental builds](https://krazywarez.github.io/orgo/guide/07-incremental.html) | How it decides what to rebuild. |
129| [Watching and serving](https://krazywarez.github.io/orgo/guide/08-workflow.html) | The write-save-see loop. |
130| [Auditing](https://krazywarez.github.io/orgo/guide/09-auditing.html) | Reading a corpus before trusting a tool with it. |
131| [Deploying](https://krazywarez.github.io/orgo/guide/10-deploying.html) | Producing a production build, and putting it somewhere. |
132
133## Building
134
135```sh
136cargo test                              # includes a differential check against Emacs, when present
137cargo run -- serve docs -o docs/_site   # read the documentation locally
138```
139
140## Licence
141
142[0BSD](LICENSE). Do what you like with it.