MCPcopy
hub / github.com/xyproto/algernon

github.com/xyproto/algernon @v1.17.9 sqlite

repository ↗ · DeepWiki ↗ · release v1.17.9 ↗
3,728 symbols 13,055 edges 146 files 488 documented · 13%
README

Algernon

Build GoDoc License Go Report Card FOSSA Status Stand With Ukraine

Web server with built-in support for HTTP/2, HTTP/3 (QUIC), Lua, Teal, Markdown, Pongo2, HyperApp, Amber, Sass(SCSS), GCSS, JSX, TypeScript, Ollama (LLMs), BoltDB (built-in, stores the database in a file, like SQLite), Redis, Valkey, PostgreSQL, SQLite, MariaDB, MySQL, MSSQL, IPv6, rate limiting, graceful shutdown, plugins, users and permissions.

All in one small self-contained executable.

Distro Packages

Packaging status

Quick installation

Requires Go 1.26 or later.

go install github.com/xyproto/algernon@latest

Or manually (development version):

git clone https://github.com/xyproto/algernon
cd algernon
go build -mod=vendor
./welcome.sh

Releases and pre-built images

See the release page for releases for a variety of platforms and architectures.

Getting Started

See TUTORIAL.md.

Docker

The Docker image is less than 12MB and can be tried out (on x86_64) with:

mkdir localhost
echo 'hi!' > localhost/index.md
docker run -it -p4000:4000 -v .:/srv/algernon xyproto/algernon

And then visiting http://localhost:4000 in a browser.

Technologies

Written in Go. Uses Bolt (built-in), MySQL, PostgreSQL, SQLite or Valkey/Redis (recommended) for the database backend, permissions2 for handling users and permissions, gopher-lua for interpreting and running Lua, optional Teal for type-safe Lua scripting, http2 for serving HTTP/2, quic-go for serving QUIC, gomarkdown/markdown for Markdown rendering, amber for Amber templates, Pongo2 for Pongo2 templates, Sass(SCSS) and GCSS for CSS preprocessing. logrus is used for logging, goja-babel for converting from JSX to JavaScript, tollbooth for rate limiting, pie for plugins and graceful for graceful shutdowns.

Design decisions

  • HTTP/2 over SSL/TLS (https) is used by default, if a certificate and key is given.
  • If not, regular HTTP is used.
  • HTTP/3 (QUIC) can be enabled with a flag.
  • /data and /repos have user permissions, /admin has admin permissions and / is public, by default. This is configurable.
  • The following filenames are special, in prioritized order:
    • index.lua is Lua code that is interpreted as a handler function for the current directory.
    • index.html is HTML that is outputted with the correct Content-Type.
    • index.md is Markdown code that is rendered as HTML.
    • index.txt is plain text that is outputted with the correct Content-Type.
    • index.pongo2, index.po2 or index.tmpl is Pongo2 code that is rendered as HTML.
    • index.amber is Amber code that is rendered as HTML.
    • index.hyper.js, index.hyper.jsx or index.happ is JSX+HyperApp code that is rendered as HTML.
    • index.jsx is a React JSX/JavaScript file that is rendered as HTML with bundled JavaScript.
    • index.tsx is a React TSX/TypeScript file that is rendered as HTML with bundled JavaScript.
    • index.tl is Teal code that is interpreted as a handler function for the current directory.
    • index.prompt is a content-type, an Ollama model, a blank line and a prompt, for generating content with LLMs.
    • data.lua is Lua code, where the functions and variables are made available for Pongo2, Amber and Markdown pages in the same directory.
    • If a single Lua script is given as a command line argument, it will be used as a standalone server. It can be used for setting up handlers or serving files and directories for specific URL prefixes.
    • style.gcss is GCSS code that is used as the style for all Pongo2, Amber and Markdown pages in the same directory.
  • The following filename extensions are handled by Algernon:
    • Markdown: .md (rendered as HTML)
    • Pongo2: .po2, .pongo2 or .tpl (rendered as any text, typically HTML)
    • Amber: .amber (rendered as HTML)
    • Sass: .scss (rendered as CSS)
    • GCSS: .gcss (rendered as CSS)
    • JSX: .jsx (rendered as JavaScript/ECMAScript)
    • TypeScript: .ts, .tsx (rendered as JavaScript/ECMAScript)
    • Lua: .lua (a script that provides its own output and content type)
    • Teal: .tl (same as .lua but with type safety)
    • HyperApp: .hyper.js or .hyper.jsx (rendered as HTML)
  • Other files are given a mimetype based on the extension.
  • Directories without an index file are shown as a directory listing, where the design is hard coded.
  • UTF-8 is used whenever possible.
  • The server can be configured by command line flags or with a lua script, but no configuration should be needed for getting started.

Features and limitations

  • Supports HTTP/2, with or without HTTPS (browsers may require HTTPS when using HTTP/2).
  • Also supports HTTP/3 (QUIC) and regular HTTP.
  • Can use Lua scripts as handlers for HTTP requests.
  • The Algernon executable is compiled to native and is reasonably fast.
  • Works on Linux, macOS and 64-bit Windows.
  • The Lua interpreter is compiled into the executable.
  • The Teal typechecker is loaded into the Lua VM.
  • Live editing/preview when using the auto-refresh feature.
  • The use of Lua allows for short development cycles, where code is interpreted when the page is refreshed (or when the Lua file is modified, if using auto-refresh).
  • Self-contained Algernon applications can be zipped into an archive (ending with .zip or .alg) and be loaded at start.
  • Built-in support for Markdown, Pongo2, Amber, Sass(SCSS), GCSS and JSX.
  • Redis is used for the database backend, by default.
  • Algernon will fall back to the built-in Bolt database if no Redis server is available.
  • The HTML title for a rendered Markdown page can be provided by the first line specifying the title, like this: title: Title goes here. This is a subset of MultiMarkdown.
  • No file converters needs to run in the background (like for SASS). Files are converted on the fly.
  • If -autorefresh is enabled, the browser will automatically refresh pages when the source files are changed. Works for Markdown, Lua error pages and Amber (including Sass, GCSS and data.lua). This only works on Linux and macOS, for now. If listening for changes on too many files, the OS limit for the number of open files may be reached.
  • Includes an interactive REPL.
  • If only given a Markdown filename as the first argument, it will be served on port 3000, without using any database, as regular HTTP. This can be handy for viewing README.md files locally. Use -m to display it in a browser and only serve it once.
  • Full multi-threading. All available CPUs will be used.
  • Supports rate limiting, by using tollbooth.
  • The help command is available at the Lua REPL, for a quick overview of the available Lua functions.
  • Can load plugins written in any language. Plugins must offer the Lua.Code and Lua.Help functions and talk JSON-RPC over stderr+stdin. See pie for more information. Sample plugins for Go and Python are in the plugins directory.
  • Thread-safe file caching is built-in, with several available cache modes (for only caching images, for example).
  • Can read from and save to JSON documents. Supports simple JSON path expressions (like a simple version of XPath, but for JSON).
  • If cache compression is enabled, files that are stored in the cache can be sent directly from the cache to the client, without decompressing.
  • Files that are sent to the client are compressed with gzip, unless they are under 4096 bytes.
  • When using PostgreSQL, the HSTORE key/value type is used (available in PostgreSQL version 9.1 or later).
  • No external dependencies, only pure Go.
  • Requires Go >= 1.26 or a version of GCC/gccgo that supports Go 1.26.
  • The Lua implementation used in Algernon (gopherlua) does not support package.loadlib.
  • Full support for IPv6.

React, JSX and TypeScript

When a directory contains an index.jsx or index.tsx file, Algernon serves it as a complete React application. The JSX/TSX is bundled with esbuild, wrapped in an HTML page with the React runtime loaded, and served with the correct content type.

  • If style.css or style.gcss is present in the same directory, it is used. Otherwise, a built-in default stylesheet is applied.
  • The React version defaults to 19. A different major version (if it is available and built-in to Algernon) can be selected by placing a // React: <N> comment at the top of index.jsx or index.tsx:

    // React: 19
    
  • Lua scripts in the same directory (e.g. login.lua, data.lua) can serve as API endpoints, making it possible to build full-stack applications with JSX for the frontend and Lua for the backend.

Injected JavaScript functions

When serving index.jsx or index.tsx, the following helper functions are available in the browser:

  • postForm(url, fields) — POST form data to a Lua/Teal endpoint and return the parsed JSON response as a promise. The fields argument is an object whose keys and values are URL-encoded and sent as application/x-www-form-urlencoded.
  • bufferToBase64URL(buffer) — convert an ArrayBuffer to a base64url-encoded string. Useful for WebAuthn credential responses.
  • base64URLToBuffer(str) — convert a base64url-encoded string to an ArrayBuffer. Useful for WebAuthn challenge and credential ID fields.

Example usage in JSX:

postForm("login.lua", { username, password }).then((data) => {
  if (data.ok) {
    console.log("Logged in");
  } else {
    console.log(data.error);
  }
});

Lua functions for JSON endpoints

  • formjson() — Read a JSON request body and return a Lua table with the decoded fields. Useful when the client sends application/json instead of form data.
  • formdata() — Read form-encoded or URL query data and return a Lua table.
  • json(table) — Convert a Lua table to a JSON string.

Example Lua endpoint:

content("application/json")
local fields = formdata()
local username = sanhtml(fields["username"] or "")
if username == "" then
  print(json({error = "Missing username"}))
  return
end
print(json({ok = true}))

WebAuthn (passwordless authentication)

Algernon has built-in support for WebAuthn/FIDO2 passwordless authentication. Credentials are stored in the database alongside regular user data. Four Lua/Teal functions are available:

  • WebAuthnBeginRegister(username) — Begin a registration ceremony. Writes JSON options to the response. Returns true if successful.
  • WebAuthnFinishRegister(username) — Finish registration. Reads the attestation response from the request body and stores the credential. Returns true if successful.
  • WebAuthnBeginLogin(username) — Begin a login ceremony. Writes JSON options to the response. Returns true if successful.
  • WebAuthnFinishLogin(username) — Finish login. Reads the assertion response from the request body. On success, also logs the user in via the standard session mechanism. Returns true if successful.

The relying party ID and origin are automatically derived from the request. Example Teal endpoints:

```lua -- webauthn_regist

Extension points exported contracts — how you extend this code

Renderer (Interface)
Renderer handles a small file extension by reading it through the cache and writing a response. Extensions that need mor [7 …
engine/renderer.go
Comment (Interface)
(no doc)
samples/react_tsx/index.tsx

Core symbols most depended-on inside this repo

push
called by 1286
engine/assets/mathjax/tex-svg.js
r
called by 1254
engine/assets/mathjax/tex-svg.js
create
called by 534
engine/assets/mathjax/tex-svg.js
get
called by 477
engine/assets/mathjax/tex-svg.js
apply
called by 463
engine/assets/mathjax/tex-svg.js
n
called by 424
engine/assets/mathjax/tex-svg.js
error
called by 414
engine/assets/mathjax/tex-svg.js
i
called by 395
engine/assets/mathjax/tex-svg.js

Shape

Function 2,362
Method 1,231
Class 90
Struct 39
Interface 3
TypeAlias 3

Languages

TypeScript84%
Go15%
Python1%

Modules by API surface

engine/assets/mathjax/tex-svg.js761 symbols
engine/assets/react19/react-dom.development.js753 symbols
engine/assets/react19/react-dom.production.min.js468 symbols
samples/htmx/htmx.min.js195 symbols
samples/react_simple/js/marked.min.js102 symbols
samples/react_jsonfile/js/marked.min.js102 symbols
samples/react_db/js/marked.min.js102 symbols
samples/react_simple/js/jquery.min.js80 symbols
samples/react_jsonfile/js/jquery.min.js80 symbols
samples/react_db/js/jquery.min.js80 symbols
samples/react_simple/js/marked.umd.js74 symbols
samples/react_jsonfile/js/marked.umd.js74 symbols

Dependencies from manifests, versioned

filippo.io/edwards25519v1.2.0 · 1×
github.com/DataDog/gostackparsev0.7.0 · 1×
github.com/alecthomas/chroma/v2v2.26.1 · 1×
github.com/allegro/bigcache/v3v3.1.1-0.20240229143 · 1×
github.com/aymerick/douceurv0.2.0 · 1×
github.com/caddyserver/zerosslv0.1.5 · 1×
github.com/chzyer/readlinev1.5.1 · 1×
github.com/coreos/go-semverv0.3.1 · 1×
github.com/davecgh/go-spewv1.1.2-0.20180830191 · 1×
github.com/ddliu/go-httpclientv0.7.1 · 1×

For agents

$ claude mcp add algernon \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact