The small web toolkit for Go
Go to file
tjpcc 09c482d501
continuous-integration/drone/push Build is failing Details
nit style fix
2023-09-23 13:18:49 -06:00
contrib improve shared host path handling 2023-09-23 13:18:30 -06:00
examples all the gopher CGI handlers to support gophernicus behaviors 2023-09-07 12:36:17 -06:00
finger Revert "text fixes" 2023-08-12 10:49:44 -06:00
gemini simplify internal gemini template-handling functions 2023-09-01 12:37:08 -06:00
gopher recognize .gph as gophermap 2023-09-23 13:18:41 -06:00
internal nit style fix 2023-09-23 13:18:49 -06:00
logging make debug log text more visible 2023-09-14 09:40:39 -06:00
spartan multi-protocol client 2023-08-12 10:47:51 -06:00
tools sw-convert format switch cleanup 2023-09-09 08:42:46 -06:00
.drone.yml testing and linting and linter fixes 2023-01-24 19:59:47 -07:00
.gitignore WIP improve test coverage 2023-01-11 11:41:07 -07:00
LICENSE.txt add unlicense 2023-01-09 22:21:57 -07:00
README.gmi sw-convert and sw-fetch tools 2023-09-03 08:01:38 -06:00 sw-convert and sw-fetch tools 2023-09-03 08:01:38 -06:00
client.go support tls client configs in HTTP client 2023-08-25 11:17:11 -06:00
go.mod name change gus -> sliderule 2023-05-01 07:56:25 -06:00
go.sum Completed gemtext package. 2023-01-14 09:58:32 -07:00
handler.go move common types to an internal package 2023-08-12 09:40:39 -06:00
handler_test.go name change gus -> sliderule 2023-05-01 07:56:25 -06:00
request.go move common types to an internal package 2023-08-12 09:40:39 -06:00
request_test.go name change gus -> sliderule 2023-05-01 07:56:25 -06:00
response.go move common types to an internal package 2023-08-12 09:40:39 -06:00
router.go allow mounted sub-routers to own the root path without a trailing slash 2023-09-17 19:57:50 -06:00
router_test.go fix tests and examples to match the router.Handler() change 2023-05-02 08:56:10 -06:00
server.go move common types to an internal package 2023-08-12 09:40:39 -06:00

sliderule: The small web toolkit for Go

sliderule is the toolkit for working with the small web in Go.

|  |"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|"!"|  |
|  0   1   2   3   4   5   6   7   8   9  10  11  12  13   4  |
    |   |891"!"|""2""|"3n|4|5"6|7891"!"|"|2""!"3"|"4|5"67891"!|   |
    |                      |     I     |                          |
|   9!1"1"2"3"4"5"67892"|"||""3n"|""4""|"5"!"6""7""8"9"1"1    |===

You still have to write your server, but you can focus on the logic you want to implement knowing the protocol is already dealt with. It's been said of gemini that you can write your server in a day. Now you can write it in well under an hour.

The slide rule

sliderule is named after the iconic instrument used to perform approximate mathematical calculations before the advent of handheld electronic calculators. It was the predominant tool that identified an engineer during project Gemini, a sort of developer's tool of it's time.

The "sliderule" package

sliderule is carefully structured as composable building blocks. The top-level package defines the framework in which servers and clients can be built.

  • a request type
  • a response type
  • a "Server" interface type
  • a "Handler" abstraction
  • a "Middleware" abstraction
  • a "Client" implementation which wraps multiple protocol-specific clients and can handle URLs with a variety of schemes
  • some useful Handler wrappers: a router, request filtering, falling through a list of handlers


The packages sliderule/gemini, sliderule/gopher, sliderule/finger, and sliderule/spartan provide concrete implementations specific to those protocols.

  • I/O (parsing, formatting) request and responses
  • constructors for the various kinds of protocol responses
  • helpers for building a protocol-suitable TLS config
  • Client implementations
  • Servers which can run your Handlers.

The primary text formats for those protocols have higher-level support provided in sub-packages:

  • sliderule/gemini/gemtext supports parsing gemtext and getting direct programmatic access to its AST.
  • sliderule/gopher/gophermap similarly parses the gophermap format and provides access to its AST.

Sub-packages in the text formats provide conversion functions to HTML, markdown, and Atom XML, using overridable templates.


sliderule borrows the logging interface from go-kit.

=> The logger interface from go-kit/log.

The sliderule/logging package provides everything you need to get a good basic start to producing helpful logs.

  • A request-logging middleware with common diagnostics (time, duration, url, status codes, response body lengths)
  • A simple constructor of useful default loggers at various levels. They output colorful logfmt lines to stdout.


The router in the sliderule package supports slash-delimited path pattern strings. In the segments of these patterns:

  • A "/:wildcard/" segment matches anything in that position, and captures the value as a route parameter. Or if the paramter name is omitted like "/:/", it matches anything in a single segment without capturing a paramter.
  • A "/remainder" segment is only allowed at the end and matches the rest of the path, capturing it into the paramter name. Or again, omitting a parameter name like "/" simple matches any path suffix.
  • Any other segment in the pattern must match the corresponding segment of a request exactly.

Router also supports maintaining a list of middlewares at the router level, mounting sub-routers under a pattern, looking up the matching handler for any request, and of course acting as a Handler itself.


This is where useful building blocks themselves start to come in. Sub-packages of contrib include Handler and Middleware implementations which accomplish the things your servers actually need to do.

The sub-packages include:

  • fs has handlers that make file servers possible: serve files, build directory listings, etc
  • cgi includes handlers which can execute CGI programs
  • sharedhost which provides means of handling /~username URLs
  • tlsauth contains middlewares and bool functions for authenticating against TLS client certificates
  • ...with more to come


The tools directory contains main packages that implement useful cli tools for working with the small web. You can install them all at once with:

go install

They all have useful output when given the -h/--help flag.

Get it

Using sliderule in your project

To add it to your own go project:

$ go get

Straight to the code please

=> The code is hosted here on tildegit.

=> The generated documentation is on the go package index.

Verify releases

Releases are signed with minisign. The signature file is included in the release downloads page, and the public key is RWSzQywJwHgjSMD0y0RXwXAGpapcMJplwbCVYQqabhAJ+NAnKAeh98Vb - this is also referenced on tjp's gemini home page.

=> tjp's home page, which also mentions the public key used for signing sliderule releases.


This project used to be called "gus", and the original project's old issues can be found at:



There's lots still to do, and contributions are very welcome!

=> submit an issue or pull request on the tildegit repository,

=> send me an email directly,

or poke me on IRC: I'm @tjp on where you'll find me in #gemini