Gemini is, in its words:

Gemini is a new, collaboratively designed internet protocol, which explores the space inbetween gopher and the web, striving to address (perceived) limitations of one while avoiding the (undeniable) pitfalls of the other.

Gemini is very lightweight, very simple, and lacks many of the features I’m used to on the modern web. I ❤ it for that.

This post aims to explain some of the reasons why I’m excited about Gemini.


The primary reason I’m drawn to Gemini is the simplicity and clarity of purpose. Gemini doesn’t try and be a replacement for the web. It isn’t trying to be an application platform. It’s a simple protocol for dishing up small files. Typically, those small files are text written in its own markup language (GemText - a simplified Markdown-like syntax)

In the design criteria for Gemini… FAQ

The protocol should be easy to read and understand.

It should be possible for somebody who had no part in designing the protocol to accurately hold the entire protocol spec in their head after reading a well-written description of it once or twice.

Implementing a client should be easy.

A basic but usable (not ultra-spartan) client should fit comfortably in 50 or so lines of code in a modern high-level language. Certainly not more than 100.

A client comfortable for daily use which implements every single protocol feature should be a feasible weekend programming project for a single developer.

Another nice aspect of the text-based approach taken by Gemini and GemText is that it puts the consumer in control of formatting. I can set the colors and font-sizes that I like, rather than being subjected to whatever the content provider used.


Part of the appeal of Gemini is that it’s privacy-friendly by design.

It explicitly does not support tracking-type technologies like cookies, referrer headers, and custom headers. There really just isn’t any room in the protocol for the client to leak personal details to the server. The protocol is also closed to prevent those mechanisms from being added in the future.


Gemini takes an interesting approach to encryption and TLS.

Gemini requires the use of TLS. I like this. TLS improves privacy and avoids MITM type data tampering. It also makes it safer to access over Tor since it’s more difficult for a malicious Tor Exit Node to tamper with results.

A really cool difference between Gemini and the web (and other TLS-based systems), is that Gemini doesn’t require the use of CAs but instead suggests that clients take a SSH-like Trust on First Use (TOFU) approach. As a result, many Gemini Capsules (Sites) just use self-signed SSL certificates.

  • Don’t require CA issued certificates
  • Aren’t forced to trust the approximately 3,000 Root CAs :)
  • Easily able to use TLS on internal services (where getting CA-issued certificates is hard)
  • Server software can (and does) automatically create and manage their own certificates

Client Authentication

Closely related to the mandatory use of TLS, is how Gemini handles client authentication and authorization.

Gemini doesn’t include an equivalent to HTTP Basic Auth, or HTTP header based authorizations.

Instead, user authentication & authorization in Gemini is handled by client TLS certificates. This is awesome for lots of reasons:

  • You can manage multiple identities and choose which identity to share with each capsule
  • You control what information is included in your client TLS certificate
  • You control the lifetime of the client TLS certificate (long-lasting v. temporary)
  • The server doesn’t have to store / manage sensitive user credentials (no password breaches. no weak password checks.)

Browsing Gemini Content

Because Gemini is a brand-new-thing, you need a Gemini browser to browse Gemini capsules.


My favourite Gemini browsers are Lagrange (graphical and beautiful), and AV-98 (text-based and super keyboard friendly). There are already lots of options including Gemini browsers for iOS and Android.

In addition, there are plenty of web-to-gemini gateways that let you get started without requiring additional software.

My Gemini Capsule on (via. gateway)

Creating a Hidden Gemini Service

I’m actually pretty excited about Gemini hidden-services over Tor. Using the modern-web over Tor is scary for several reasons:

  • Modern web servers have a pretty huge attack surface
  • Modern web browsers have a massive attack surface (JavaScript)
  • It is hard to configure modern web browsers to avoid leaking data (WebRTC, JavaScript, etc.)

Gemini, on the other hand…

  • Doesn’t even have a mechanisms for the client to leak information to the server
  • Doesn’t have support for client-side executable content
  • Has a much simpler client, and presumably smaller attack surface
  • Has a much simple server, and presumable smaller attack surface

Setting up a Gemini-based Tor hidden service is fairly easy. These instructions are for Linux (Debian).

Start by ensuring you have a modern version of Tor running on your machine.

Next, get your Gemini server of choice. I selected gmnisrv.

I’m going to gloss over setting up some of the Gemini server. Obviously, make sure it’s running as an unprivileged user and chrooted / sandboxed as appropriate.

The first step is to configure Tor to expose your Gemini server as a new hidden service. To do this, add the following lines to /etc/tor/torrc:

HiddenServiceDir /var/lib/tor/hidden_gemini/
HiddenServicePort 1965

And restart Tor.

$ sudo service tor restart

This will create a new set of keys for the hidden service in /var/lib/tor/hidden_gemini.

We need to get the hostname for our new hidden service.

$ cat /var/lib/tor/hidden_gemini/hostname

Now, we can setup our gmnisrv configuration file like so.

You’ll need to make sure the user running gmnisrv has r/w to the configured certificate store and root.

Make sure to configure gmnisrv to listen only to so you don’t inadvertently expose your Gemini capsule to the clearnet.


# Path to store certificates on disk

# Optional details for new certificates
organization=Hidden Gemini


Create some content:

echo "# Hello World" > /var/gemini/index.gmi

Start the server:

$ torify gmnisrv -C gmnisrv.config 
[gmnisrv] generating certificate for 4cesl34prayq4n2tiw3bhnfe6gckjuhjt3nllt5uexmv6mq4lxwcoiyd.onion
[gmnisrv] listening on
[gmnisrv] gmnisrv started

And test it out with your client of choice (making sure that it’s also going through Tor or the .onion won’t resolve properly):

$ torify lagrange 4cesl34prayq4n2tiw3bhnfe6gckjuhjt3nllt5uexmv6mq4lxwcoiyd.onion

You should now be serving content via. Gemini as a Tor Hidden Service.