I saw a strange link on a GitHub repo the other day that was prefixed with gemini://. I was confused and tried looking up “gemini protocol” online, but to no avail. I brushed it off as a weird startup alternative to HTTP and went on with my day.

That was, until my friend Waylon1 shot me a message a week or two later:

waylon — 02/09/2022
have you seen this https://gemini.circumlunar.space/

leo — 02/09/2022
I've heard about Gemini
Hmmmm haven't seen a lot
Lemme read
So better HTTP?

So better HTTP?

Ehhhh, no. With some closer investigation, it’s an alternative protocol for the web. It’s still focused on delivering content, but just in a more privacy-motivated, cozy way. You can write a server or client for it very simply in only a handful of lines in almost any language. You can write a fully-fleshed out client in maybe 100 or 200 SLOC2.

Here’s an inetd-compatible ““server”” in POSIX-compliant shell I wrote in a minute or two:

#!/bin/sh
chdir $1
shift

if [ $# -ne 1 ]; then
  echo -n "50 Ill-formatted request"
  exit 0
fi

uri=$(printf '%b\n' "$@" | sed -n 's/^gemini:\/\/.*\/\(.*\)$/\1/p')

if ! [ -r $uri ]; then
  echo -n "40 Page does not exist\r\n"
  exit 0
fi

MIME="$(file -b --mime-type $uri)"
if echo "$uri" | grep -q ".*\.gmi"; then
  MIME="text/gemini"
fi

echo -n "20 $MIME;\r\n"
cat $uri

To use this you would just add a line to your /etc/inetd.conf:

127.0.0.1:1965  stream  nowait  gemini  /path/to/gemini.sh gemini.sh /path/to/chdir

This would produce some request-response behavior like this (\r\n included for legibility):

<<<<<<<<<<REQUEST
/index.gmi\r\n

>>>>>>>>>>RESPONSE
20 text/gemini;\r\n
hi there

I say ““server”” though because it only really just serves the file at a given URI with pretty minimal URI validation. There’s no meaningful logging. Also, you would need a relay for TLS (so you’d probably want to remap your server port to something else). If you’re using inetd, though, you probably have one of those. It isn’t the prettiest solution on Earth, but it could get the job done.

For my purposes, I happened to be looking for a more personal way of blogging without making it HTTP-scrapable. Gemini provides its own integrated markdown-esque markup language for text content, so things clicked. There’s all kinds of different protocols for this stuff, though. IPFS is an alternative I considered. Adjacent to Gemini specifically, Gopher comes to mind.

Gemini + Gopher #

You don’t always need a dozen headers or a packed format with a binary BNF grammar to describe a text file to a requester. I think that’s kind of the point of these new alternative protocols – levering modern technologies to make “the web” more accessible and a little less centralized.

Gemini is, in my eyes, one of the most straightforward protocols around when it comes to this. It doesn’t bother trying to be anything it isn’t.

No JS means there’s no interactivity, really, but that’s not an issue if your content is static. No CSS means there’s no definitive style, but that’s also not an issue if your content is static – the user’s client can determine how it should look.

At a technical level, there’s already so much abstraction afforded in TCP sockets and TLS alone, so why bother with adding all of this extra stuff when the ultimate goal of the protocol is to serve largely text-based content?

How far out can we push this line of power-to-weight3, though? Things get weird when you start looking at Gopher.

Gopher was designed a sort of alternative to HTTP. They were both around in the same era, and both got a reasonable amount of publicity. I’m too young to ever know “The Gopher Protocol” was a serious contender for the web, but it was.

Its markup is stripped down compared to HTML, and it revolves around the notion of menu-based browsing. There’s this packed, but semi-legible construct that it uses in responses to describe menus (pulled from Wikipedia).

<<<<<<<<<<REQUEST
/Reference

>>>>>>>>>>RESPONSE
1CIA World Factbook     /Archives/mirrors/textfiles.com/politics/CIA    gopher.quux.org 70
0Jargon 4.2.0   /Reference/Jargon 4.2.0 gopher.quux.org 70      +
1Online Libraries       /Reference/Online Libraries     gopher.quux.org 70     +
1RFCs: Internet Standards       /Computers/Standards and Specs/RFC      gopher.quux.org 70
1U.S. Gazetteer /Reference/U.S. Gazetteer       gopher.quux.org 70      +
iThis file contains information on United States        fake    (NULL)  0
icities, counties, and geographical areas.  It has      fake    (NULL)  0
ilatitude/longitude, population, land and water area,   fake    (NULL)  0
iand ZIP codes. fake    (NULL)  0
i       fake    (NULL)  0
iTo search for a city, enter the city's name.  To search        fake    (NULL) 0
ifor a county, use the name plus County -- for instance,        fake    (NULL) 0
iDallas County. fake    (NULL)  0

Don’t look at it too long. It’s easy to understand why it lost out against HTTP.

The formatting of Gophertext is reminiscent of troff’s syntax. The user requests the Reference menu, in plaintext then the server replies with different resources (their types indicated by the prefixed number), menus, and submenus (i). To an untrained eye, there’s these strange keywords “fake” and “(NULL)” popping up all over, references to proxy servers. It’s just… strange.

There isn’t really much in the way of security for the protocol, and there are unofficial, somewhat-community-accepted extensions to it for things like media files and binaries. Overall, it feels like a somewhat reasonable protocol that lost its focus as new things needed to be incorporated into it.

Its markup is restrained, but wanted to compete with HTML. It wanted to incorporate new media types, but to do that, it had to incorporate new prefix codes. And once the protocol itself changes at a fundamental level like that, it’s pretty difficult to propagate that change across the web. Meanwhile in HTTP or Gemini, you simply change the MIME type field. Overall, it’s a cool idea, but with all of these dangling bits it may be a bit of an anachronism and a case study in protocol design.

These ideas of alternative protocols still catch my eye, though. They’re reminiscent of a web that didn’t have a notion of CSS, or JS, or really any moving parts.

It makes you wonder. How different would the Internet be if these protocols had won out? How would we handle the features that are ubiquitous in the WWW today like CSS for styling and JS for interactivity?

The Real Web3 #

After Waylon and I chatted for a bit about the Gemini specification, a fun thought experiment began.

What if we abandoned what we have today to completely redesign the web? No HTTP. No HTML. No CSS. No JavaScript. Completely from scratch, but with our lessons-learned from the present.

Well for one, we wouldn’t be throwing out IP. Maybe if we were ambitious we’d redesign it such that all computers use IPv6, but a flag day is impossible now.

More realistically, I think application-level protocols would be a lot more modular with a security-first design – kind of like QUIC. Hosts can stream data between each other on a lighter protocol that is designed to handle congestion control.

The deep point of discussion, though, is how websites could be rendered without HTML. The one that seemed to hold our attention best was:

waylon — 02/09/2022
what if you had something like this
(except not with HTML primitives)
and instead of serving HTML
web servers served this
and browsers executed it to build a website
I mean that's basically react

I guess what we're doing is just React but cutting out the
js part and pretending HTML doesn't exist 🤔

So basically what dioxus is doing: compile down your dynamically-rendered JSX-like statically-typed markup into some WebAssembly. Dodge the JS runtime bullet and roll your own from scratch.

This would open up a few interesting discussions about website performance as more ambitious devs try to roll their own WebAssembly, but I don’t think it’d be any different than devs who roll their own HTTP servers these days.

I encounter problems thinking about this in the same way that I encounter problems trying to think in more than 3 dimensions. HTML is all I know. React is all I know. For the current web, it’s the same deal. WebAssembly is a step in the right direction of speeding up and broadening the spectrum of dynamic content on the web, but it’s still served as a complement to JavaScript4.

I am skeptical that we’ll see a serious transition to a brand new protocol like QUIC or an exodus from the de jure languages of the web for a long time. To do so would be like switching the web to IPv6, which - like I said - I’m fairly certain won’t be happening anytime soon… Maybe ever.

These new protocols are around the block, and they won’t be replacing anything that’s already around, but it’s a lot of fun exploring that big “what if”.


I might update this article later on.

  1. Waylon is one of the smartest people I know. https://www.waylonpeng.com/. 

  2. https://gemini.circumlunar.space/ 

  3. The Gemini docs describe it as “a new internet protocol which … strives for maximum power to weight ratio” 

  4. MDN describes it as complementary to JavaScript. https://developer.mozilla.org/en-US/docs/WebAssembly