The Gemini Protocol in 2026
52 points by chai
52 points by chai
Obligatory disclaimer: I was the second person, after Solderpunk, to be involved with the Gemini protocol. I implemented the first Gemini server (even before Solderpunk) and I influenced quite a bit of the protocol. Now, with that out of the way ...
TLS. The original idea for Gemini was "a more modern gopher, with TLS" since at that time (2019) people were experimenting with server gopher over TLS [1]. This was also the time of the "Encrypt All The Things!" that Google was pretty much forcing on everyone [2] that Solderpunk decided TLS was mandatory. During the mailing list age [3] there were two distinct groups complaining about TLS: the first group wanted it optional, and a second group wanting to replace TLS with something else, usually a bespoke encryption system the proposer just saw that promised to be simpler/more secure/faster. Of course, only one person in the second group even bothered with implementing their idea, and they later recanted, saying it was probably a bad idea.
Markdown: One could very well use Markdown for Gemini. People seem not to realize that Markdown not only has a MIME type (RFC-7763) but is documented as well (RCC-7764). Since Gemini supports MIME, this is trivial. No client, no my knowledge, handles this.
ANSI escape codes: a bad idea in my opinion. Way too easy to hide text and possibly (at least on MS-DOS/maybe Windows?) to reprogram the keyboard to do bad things. My own simple text client strips any ANSI escape sequences to remove this possibility, but most don't.
Client certificate use: my fault, even if I still think it's a good idea. I'm sad that the use of client certificates never really took off on the web, but key management has always been the hardest part of cryptography. Yes, one can "simply remember a password" but who does these days? Most people use a password manager, which requires storage, much like a client certificate.
Size of Gemini: it's actually larger than gopher.
Another aspect that I think is glossed over is that Solderpunk wanted Gemini to be easy to implement (both the protocol and the document format). In hindsight, I think "ease of implementation" over everything else was a bad idea (and Lagrange, perhaps the most popular Gemini client, itself isn't small, nor easy to implement), but that wasn't apparent at the time. I didn't particularly mind using TLS, but I was using libretls, the library that people should be using for TLS over raw openssl use. As I found out, stuff I found trivial to use (like client certificates) weren't that easy with openssl, but again, that's hindsight.
[1] I'm not a fan of the approach used to support TLS on gopher and it's difficult to support properly.
[2] By marking non-TLS sites with scary warnings.
[3] 2019-2021. The mailing list imploded due to a server crash and it was never restored nor restarted. <editorializing>This was probably for the best, as the community became very toxic towards the very people doing the development.</editorializing>
Markdown not only has a MIME type (RFC-7763) but is documented as well (RCC-7764)
This is misleading. You know why they’re in two RFCs? It’s the same reason why Markdown is unsuitable.
RFC 7763 is basically an admission that Markdown’s not going away, and that we should really have at least some sort of MIME type for it—which should have been done ten or twenty years ago, but the lack of governance around Markdown prevented it. It also includes a couple of other small things in sections 3 and 4. This is the rigid stuff.
RFC 7764 does document Markdown, but not to specify it. It might as well have been called “The Sad Story of Markdown”, for it tells the history and why it’s such a mess and what (with some wishful thinking) you can try to do about it. Followed then by registering a handful of variants.
“Markdown” is a loose family of similar writing formats. It’s unsuitable for direct publication. You need to be specific about what variant you’re using. Though even that probably won’t be enough: you might want something like “CommonMark but without HTML tags” or “CommonMark but with limitations on which HTML tags and attributes are supported, and such-and-such behaviour in case of unpermitted elements”. The whole thing truly is a mess.
For whatever it is worth, I have always thought the use of client certificates was one of the most compelling parts of Gemini. I saw them used in a clever ways at least once, and have long felt they are underutilized.
Markdown: One could very well use Markdown for Gemini. People seem not to realize that Markdown not only has a MIME type (RFC-7763) but is documented as well (RCC-7764). Since Gemini supports MIME, this is trivial. No client, no my knowledge, handles this.
One could also trivially just do HTML over Gemini. I did it myself with a few tweaks to elinks, just to prove I could.
i still feel guilty for abandonding the Kristall browser, because
Since Gemini supports MIME, this is trivial. No client, no my knowledge, handles this.
Size of Gemini: it's actually larger than gopher.
If we're measuring active Gemini sites, I agree there are almost certainly more of them.
If we're measuring absolute resources available, I think this is arguable due to the archival content many of the active Gophers maintain. I see very few of this sort of thing on Gemini.
Not that it really matters much :) but we should be specific on the stats.
There are only around 300 or so known gopher servers running, whereas Gemini has I think low-4 figures. But yes, there are some very large gopher servers in that 300.
In hindsight, I think "ease of implementation" over everything else was a bad idea
I would really love to hear more of your thoughts on this.
Not GP, but here are my thoughts on the matter from 2021:
https://gerikson.com/blog/comm/Gemini-misaligned-incentives.html#dev
It comes down to, no matter how easy it is to implement, not many people want to bother with coding. There's only a few clients that everyone uses, and only a bit more diversity with servers.
Also, because easy of implementation was key, a lot of ideas for small improvements were rejected. For example, you have three levels of headers, but only one level for lists. I suspect that Solderpunk restricted list to one level (and yes, he restricted lists to just a single level) because supporting more than one (like, say, three, to match headers) would have been more involved with formatting.
Another aspect (that I wish I had pushed harder for) are the status codes. I pushed for three digit status codes, just like nearly all other Internet based protocols, but Solderpunk wanted only single digit codes (and I don't recall if he even defined all 10 codes). I finally convinced him that single digit codes were not the right choice when he ran past 10 and started using other characters. He finally caved on two digits, structured similar to (but switched the meanings of 4xx and 5xx) three digit codes that have been in use since 1972. Gemini now has 18 status codes. For comparison, gopher only has one error code, and even that isn't supported very well.
And there's no way to upload information via Gemini, except through the query portion of a URL. You need to use a separate protocol to add pages to a Gemini site, whereas with HTTP, you have POST or PUT. But Gemini sure is easy to implement.
Hi, Sean!
Just chiming in; I was another early adopter, and implemented what was probably the third Gemini server. Also helped with the mailing list, wrote a guide, wrote a gopher-to-gemini gateway.
I initially proposed, in one of the earliest discussions on the mailing list, that we use Markdown as the standard document format for Gemini. I felt like it occupied the same middle ground between plain text (gopher) and HTML (www) that the protocol itself did. Solderpunk pushed hard for easier implementation, though. Gophermaps can be parsed line-by line, and he wanted that simplicity for gemtext. That ended up to be mostly but not completely the case: you also have to keep track of whether you are in a preformatted section.
Like Sean points out, there's nothing stopping you from serving Markdown over Gemini, since it supports arbitrary mime types. I don't think any clients currently support it, but I bet they would if it caught on. We've had a few years now to play with all kinds of possible Gemini clients and figure out the actual pain points (committing to maintenance actually seems to be the biggest one). Maybe its time has come.
I also think client certificates have worked great, even with inconsistent client support. The main thing is that the sites that use them need to have a backup auth flow.
I haven't been super active in Geminispace for a while, but I do read my curated feed of blogs every day, everything that interests me posted to Antenna, and then dip into Gopher if I'm still bored. I initially read this article on Gemini, in fact.
One thing I haven't seen mentioned: Gemtext's stripped-down markup isn't just an inconvenience. For some languages it's closer to a fundamental barrier.
Japanese ruby annotations (<ruby> in HTML) exist precisely because there's no other reasonable way to gloss kanji with furigana in running text. This isn't a presentational nicety; it's how you make a text legible to readers who might not know a given character. Traditional Mongolian script runs top-to-bottom, with columns progressing left-to-right. Without something equivalent to CSS writing-mode, the text doesn't render awkwardly, it just can't be rendered correctly at all. Arabic and Hebrew need proper bidirectional text handling; Thai has no word separators, so rendering it correctly requires the kind of line-breaking logic that plain text pipelines tend to quietly ignore; Tibetan and Khmer rely on complex ligature and stacking behaviour that falls apart without thoughtful font and layout support.
HTML's <ruby> element, for what it's worth, came from a real internationalization need. Microsoft introduced it for Internet Explorer 5 specifically because East Asian users needed it, and it eventually made it into the W3C standard. That's not the kind of complexity that crept in because advertisers wanted it. It's the kind that accumulated because the web was, at least sometimes, actually trying to accommodate how people write.
I think the Gemini designers were imagining a hypothetical average writer who uses a Latin alphabet, left to right, with no need for anything beyond ASCII-adjacent text semantics. That's a pretty specific person to design around and call it “simple.” Simplicity that only works for a subset of human writing systems isn't really simplicity. It's just a different set of assumptions made invisible by familiarity.
Even for European-centric authoring, there's basic deficiencies in gemtext. The lack of standardized bold or italic means you can't refer to citations (as in an academic context) etc. in a standard manner.
I gave Gemini publishing a fair shake but bounced off it. Nowadays I just rant in HTML, as God intended...
Not to mention CJK unification meaning you need language metadata to pick a font
That's a real issue, and the history behind it is worth knowing. Han unification couldn't be taken further because Unicode has a round-trip conversion guarantee: encoding a character into Unicode and back to the original charset must not lose information. Legacy Japanese charsets like JIS X 0208 distinguished glyph variants that are arguably the same abstract character—高 and 髙 being a well-known example—so Unicode was forced to encode them separately to preserve that round-trip fidelity. The incompleteness of unification isn't arbitrary; it's partly an artifact of not wanting to break existing encodings.
Whether that tradeoff was the right call is debatable. But the result is that yes, you do need language metadata to select the correct font for CJK text, and plain-text-with-UTF-8 doesn't get you out of that.
Which is the broader point: “it's UTF-8, so it's fine” treats encoding as the finish line when rendering is where most of the actual complexity lives.
Gemini does provide means to specify a language: not in the document format, but as a parameter to the mime type in the response, eg text/gemini; lang=zh-Hans-CN.
Fair correction, and worth acknowledging. A document-level lang parameter does help with font selection and some rendering decisions.
But it's one language per document. Real-world documents are often mixed: a Japanese text quoting Chinese, an English post with Japanese terms. Without a way to mark language spans within the document itself, a single lang parameter in the response header can't cover that.
And for furigana specifically, language identification isn't the issue. Knowing lang=ja doesn't tell the client which hiragana is a gloss on which kanji. That's a structural relationship, and there's no way to express it without markup. The lang parameter is a rendering hint, not a substitute for document structure.
So: better than nothing, and I should have acknowledged it existed. Still not enough for the cases I had in mind.
But it's one language per document. Real-world documents are often mixed: a Japanese text quoting Chinese, an English post with Japanese terms. Without a way to mark language spans within the document itself, a single lang parameter in the response header can't cover that.
Yes. This part was actually discussed on the mailing list, but no adequate solution was reached. I think the closest we got was a suggestion to be able to set language on preformat blocks, which are (perhaps by accident) the only block-level rather than line-level construct in gemtext. And obviously that's not a general solution even for that fairly specific problem. It was one of several cases where a commitment to minimalism prevented solving even known problems.
Thanks for the inside view. “A commitment to minimalism prevented solving even known problems” is a pretty honest summary, and it's essentially what I was getting at from the outside. The protocol froze around a set of assumptions before those problems were resolved, and the no-extensibility principle means they can't be resolved later either.
Not saying that was the wrong call for what Gemini set out to be. But it does mean the “just a client issue” framing doesn't hold up for cases where the format itself is the constraint.
Latin alphabet, left to right, with no need for anything beyond ASCII-adjacent text semantics
This feels unfair because nothing in the protocol is ASCII specific, documents are UTF-8. Maybe you’re right that someone who is able to communicate in UTF-8 is a western strawperson and that inline HTML support is required for Japanese speakers so that they can include <ruby> elements, but that hardly seems like Gemini’s problem. If you can’t author a coherent text-based document in UTF-8 it seems like you should bring that up with the Unicode consortium.
The encoding/rendering distinction matters here. UTF-8 encoding furigana and kanji is trivial; the question is whether you can express that a run of hiragana is a gloss on a specific kanji, attached to it, rendered above it. That relationship is what <ruby> encodes, and it has no equivalent in plain text. Writing 漢字(かんじ) is a workaround, not the same thing.
The Unicode consortium point is a non-sequitur: Unicode handles codepoints, not layout. Mongolian vertical text, Arabic bidi, Thai word-breaking—these are rendering problems, not encoding problems, and they're not Unicode's jurisdiction.
I'd also gently push back on “hardly seems like Gemini's problem.” That framing accepts the premise: Gemini genuinely can't do these things. My point was that this isn't a neutral technical tradeoff. It's a design choice that happens to be costless for Latin-alphabet writers and fairly significant for others.
The rendering issues aren't really germane to the document format. I agree that the missing ruby is a limitation in the document format, but the rest of them are client implementation issues. Some things, like text direction and ligatures in Arabic or text direction in Mongolian, would be handled by Harfbuzz, if you were to write a client that used it.
Side note: can you use ruby in Markdown without breaking out to HTML?
HarfBuzz handles glyph shaping, yes, but it needs to know the language to do it correctly. The same codepoint can shape differently depending on locale: Serbian and Russian share Cyrillic but have divergent italic forms for some letters, and CJK unified characters need language context to pick the right glyph variant. If the document format provides no language metadata, the client has to guess, and guessing is not the same as knowing.
Thai word-breaking is a separate case that HarfBuzz doesn't really address at all. That's dictionary-based segmentation, typically done by something like ICU. Again, getting it right depends on knowing you're dealing with Thai in the first place. A plain-text document gives the client nothing to work with except heuristics.
“Client implementation issue” is fair in a narrow sense, but it reframes the problem rather than solving it. Every client ends up needing to solve the same hard problem independently, without reliable hints from the document format. And some of those problems genuinely can't be solved reliably without metadata the format has no way to carry.
On the side note: no, standard Markdown (CommonMark, GFM) doesn't support <ruby> natively. You have to fall back to inline HTML, which is itself telling. Even Markdown, which makes no pretense of being a minimal format, delegates this to HTML.
I think the problem is that we call Gemini documents “documents.” It short circuits people’s brains. They go, “oh, like LaTeX documents” and then they’re suddenly unable to live without footnotes and inline images and bold and underline and table of contents and mathematical expressions. There was one guy who was working on a project to convert some textbooks to Gemtext, and he got hung up on the lack of inline math support.
But of course, all these same people go and post on Twitter or Facebook and don’t complain about a lack of <ruby> elements or any other HTML element for that matter. Maybe if we just called them “Gemini posts” then people would understand that they’re fundamentally plain-text and just happen to have headers.
The “posts not documents” reframe doesn't really rescue the argument. Gemini's own stated goal is to be a space for publishing content that would otherwise live on the web. If the scope is actually “just posts, like Twitter,” that's a significant step down from the project's own ambitions.
And the Twitter/Facebook comparison works against the point being made. Facebook has invested heavily in internationalization: it handles Arabic and Hebrew bidirectional text, Thai line-breaking, and a range of complex scripts reasonably well precisely because those are real requirements for a platform with a global user base. It's a case where a commercial platform did the work that Gemini's designers opted out of.
The “just call them posts” solution is cosmetic. Renaming the format doesn't change what it can and can't express.
I still think Gemini is important.
Gemini is performance art. It shows us how the web can be for some purposes. It shows how something that you can code in a couple of hours can do some stuff better than stuff no one can code (Microsoft gave up on maintaining a browser engine).
One thing I mentioned in IRC the other day that I think is not as well known is the Gemini subscription specification. Instead of RSS, gemtext pages can have an implicit feed by having multiple links with dates in them.
This sounds like something minor, but I think it's not. Nowadays, if you want to write a simple blog, you could do it with very simple tools... except for the RSS feed, which is a pain to write by hand. With Gemini you can create a subscribable blog with... just a text editor without a huge effort.
(My current blog uses this idea- I convert the gemtext to HTML and my converter adds an RSS feed if the gemtext contains an implicit feed.)
(Of course, yesterday I also faced the reality again that I'm slowly drifting apart from RSS feeds. That was not a happy place.)
Third, and related to the previous point: so far as I know, nobody is offering commercial Gemini hosting, with virtual hosting support.
My current setup is also designed to do this. Basically I've configured Apache to do MultiViews, serving both gemtext and HTML, and then my Gemini server is just a dumb proxy that is virtual host-capable. My server is designed to be a tilde, and for instance my ~user website is also served on mydomain.example.com. I would like to "productize" this a bit.
Markdown isn’t particularly hard to parse.
Markdown is extremely hard to parse. Please refer to https://github.github.com/gfm/
Just four days ago ew0k announced they're shutting down Antenna (http proxy) :(
I don't really participate in the Gemini community but I do like the project a lot, and Antenna was pretty much the front page of the internet Gemini for me. It's sad to see it go; I'm worried the ecosystem will split up such that we will no longer have such a single "front page". Still, I hope a worthy replacement will spring up.
I found this article linked from The “small web” is bigger than you might think, which I think is interesting, but not quite on-topic enough to be submitted as its own article here.
However, the experience of using Gemini, especially as it's had some time to grow, is an interesting topic, especially the rough edges that the author has run into, and the alternatives that have sprung up in the years since its introduction.
I stick to gopher, although Spartan is interesting.
The TLS and UTF-8 requirements, as well as not being able to query size before fetching, make Gemini too annoying, and as the protocol cannot evolve, it is non-fixable (by design).
What's wrong the the UTF-8 requirements? It's the default, not mandatory. You can send "text/gemini; charset=iso8859-1" as the MIME type.
Also, I did make a suggestion about sending the size of the resource, but Solderpunk said no. I tried.
Can you query size before fetching on Gopher? I don't believe so.
If you want to access Geminispace from Gopher, there is a gateway on cosmarmot.space. It doesn't do any conversion from UTF-8, but with Gopher, you need to correctly guess the codepage anyway.