Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Norgolith logo

CInorgolith-plugin-sdknorgolith-mcpLicense: GPL v2


The monolithic Norg static site generator built with Rust. Leverage rust-norg syntax validation with Norg-to-HTML conversion to build static sites from Norg content.

🌟 Features

  • Norg-native content with validation via rust-norg
  • Tera v2 templates with shortcodes, optional chaining, and rich filters
  • C ABI plugin system with Landlock sandboxing (filesystem confinement, timeout, panic isolation)
  • Incremental builds via content-hash caching
  • Parallel builds powered by Rayon
  • SEO out of the box: sitemap.xml, robots.txt, OpenGraph, Twitter Cards
  • Built-in backlinks computed automatically from internal Norg links
  • Built-in search index (search_index.json + dev server endpoint)
  • Asset fingerprinting (blake3 + fingerprint Tera filter)
  • Schema validation for content metadata via lith check
  • Custom error pages (404.html, 500.html)
  • Live preview dev server with hot reload and config hot-reloading
  • Plugin sources: install from crates.io, Git repositories, or local paths
⚖️ Comparison with Hugo and Zola
DimensionHugoZolaNorgolith
LanguageGoRustRust
TemplatesGo templatesTera v2Tera v2
Content formatMarkdown + 5 othersMarkdown onlyNorg only
Plugin systemNoneNoneC ABI + Landlock sandbox
Content validationNoneLink checkingrust-norg parser + schemas (lith check)
Syntax highlightingBuilt-in (Chroma)Built-inVia plugin (tree-sitter)
Image processingYesYesPlanned
Asset bundlingYesNoPlanned
Asset fingerprintingYesNoYes (blake3)
ConfigurationTOML / YAML / JSONTOMLTOML
MultilingualYesYesNo
ShortcodesBuilt-inTera v2 componentsTera v2 component()
Custom outputJSON, RSS, etcRSS, AtomRSS, Atom
Theme systemYesYesYes
BacklinksNo (custom templates)NoYes (automatic)
Built-in searchNoYesYes
BuildParallel (pages)ParallelParallel + incremental

📝 Requirements

ComponentRequirement
BuildRust >= 1.85 (Rust 2024 edition)

⚡ Install

Run cargo install --release --path . to compile and install Norgolith in your ~/.cargo/bin directory.

🔨 AUR

Use Arch User Repository helper to install norgolith-git.

paru -S norgolith-git

📦 Nix Package

For latest release version: nix-shell -p norgolith.

For git version you can add Norgolith to NixOS configuration with flakes.

{inputs={nixpkgs.url="github:NixOS/nixpkgs/nixos-unstable";norgolith.url="github:norgolith/core";};outputs={nixpkgs,norgolith, ... }:
{nixosConfigurations.mysystem=nixpkgs.lib.nixosSystem{modules=[{environment.systemPackages=[norgolith.packages.x86_64-linux.default];}];};};}
📦 Plugin SDK

Install from crates.io into your plugin project:

cargo add norgolith-plugin-sdk

Or build from the flake:

nix build .#norgolith-plugin-sdk

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-plugin-sdk];

Scaffold a new plugin with lith plugin new my-plugin, which generates plugin.toml, Cargo.toml, and src/lib.rs.

Hooks: pre_build, post_convert, post_render, post_build. Sandboxing: Landlock filesystem confinement, configurable timeout per hook, panic isolation. Logging: plugin_log! macro bridges to Norgolith's tracing pipeline.

The canonical plugin is written in Rust using the SDK:

use norgolith_plugin_sdk::*;register_plugin!("my-plugin",
hooks:[post_render: my_hook]);fnmy_hook(json: serde_json::Value) -> Result<Option<String>,String>{let ctx:TransformContext = serde_json::from_value(json).map_err(|e| e.to_string())?;Ok(Some(ctx.html))}

Plugins use Norgolith's C ABI, so any language that exports C functions can participate. A C plugin looks like:

#include<stdint.h>#include<string.h>#defineHOOK_POST_RENDER 4
typedefchar* (*plugin_fn)(constchar*);
typedefstruct {
uint32_tabi_version;
constchar*name;
constchar*version;
void (*log_fn)(uint32_t, constchar*);
} plugin_info;
char*post_render(constchar*input) {
/* parse input JSON, return modified HTML or NULL */returnNULL;
}
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
info->abi_version=1;
info->name="my-c-plugin";
info->version="0.1.0";
*mask=HOOK_POST_RENDER;
hooks[2] =post_render;
}

For Lua, write a small C shim that embeds Lua and dispatches hook calls to a .lua script:

// c-shim.c — compiles to a .so that Norgolith loads#include<lua5.4/lua.h>#include<lua5.4/lauxlib.h>staticlua_State*L;
voidnorgolith_plugin_init(plugin_info*info, uint32_t*mask, plugin_fnhooks[4]) {
L=luaL_newstate();
luaL_dofile(L, "my-plugin.lua");
*mask=HOOK_POST_RENDER;
hooks[2] =&bridge;
}
char*bridge(constchar*input) {
/* push input, call my-plugin.lua's post_render, return result */
}

See sdk/README.md and norgolith.dev/docs/plugins for full documentation.

🤖 MCP Server

Install from crates.io:

cargo install norgolith-mcp

Or build from source:

cargo build --release --manifest-path norgolith-mcp/Cargo.toml

Or build from the flake:

nix build .#norgolith-mcp

Add it to your NixOS configuration:

environment.systemPackages=[norgolith.packages.x86_64-linux.norgolith-mcp];

Configure in your MCP client:

{
"mcp": {
"norgolith": {
"type": "local",
"command": "norgolith-mcp",
"enable": true
}
}
}

Capabilities: resources (norgolith://docs/*), tools (search_docs, read_source). See norgolith-mcp/README.md for details.

🚀 Quick Start

lith init my-site
cd my-site
lith new -k post hello-world
lith dev --open
lith build

📖 Usage

The produced binary is called lith for short.

$ lith --help
The monolithic Norg static site generator
Usage: lith [OPTIONS] <COMMAND>
Commands:
init Initialize a new Norgolith site
theme Theme management
dev Run a site in development mode
new Create a new asset in the site and optionally open it using your preferred system editor. e.g. 'new -k norg post1.norg' -> 'content/post1.norg'
build Build a site for production
plugin Plugin management
check Validate content files against the configured content schema
preview Preview from build result
help Print this message or the help of the given subcommand(s)
Options:
-v, --version Print version
-d, --dir <PROJECT_DIR> Operate on the project in the given directory
-h, --help Print help
🔌 Plugin Development

Norgolith ships a C ABI plugin system. Plugins are shared libraries (.so, .dylib, .dll) loaded at runtime and sandboxed with Landlock.

Hook pipeline:

Content --> pre_build --> post_convert --> Tera render --> post_render --> post_write --> post_build

Plugin install:

lith plugin install ./my-plugin # from local path
lith plugin install norgolith-tree-sitter # from crates.io
lith plugin install --git https://github.com/norgolith/norgolith-tree-sitter.git

Sandboxing: each plugin gets filesystem confinement (configurable: none / read / write / read-write), a per-hook timeout (default 10s), and panic isolation.

See sdk/README.md for the full plugin guide.

❄️ Developing with Nix

The repository includes a Nix flake for development and testing.

nix build .# build, output in result/
nix run .# build and run
nix develop .# dev shell with all dependencies

For Nix-direnv integration, entering the directory activates the dev shell automatically.

📚 Documentation

The documentation site source lives in the docs/ directory. To work on it:

# From repo root, enter dev shell (includes tailwindcss, mprocs).
nix develop
# Build lith
cargo build --release
# Start docs dev servercd docs
mprocs

See docs/README.md for details.

🚀 Community

Join the Neorg community and get help or discuss about the project:

💌 Supporting Norgolith

Developing and maintaining open-source projects takes time and effort. If you find Norgolith valuable and would like to support its continued development, here are some ways you can help:

  • Star this repository on GitHub: this helps raise awareness and shows the project is actively maintained.
  • Contribute code or documentation: we welcome contributions from the community.
  • Spread the word: let others know about Norgolith if you think they might benefit from it.
  • Financial Support (Optional): if you'd like to offer financial support, you can consider using my Ko-fi page (linked in the repository). Any amount is greatly appreciated and helps me invest further time in Norgolith's development.

💜 Sponsors

Huge thanks to the project sponsors for supporting my work!

Ladas552

📖 License

This project is licensed under the GNU General Public License v2 (GPLv2). You can find the license details in the LICENSE file.

About

The monolithic Norg static site generator built with Rust

Topics

Resources

Code of conduct

Contributing

Stars

65 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages