title: Gemini is Solutionism at its Worst
url: https://マリウス.com/gemini-is-solutionism-at-its-worst/
hash_url: cb9e84580f4cb201995be13a7df2117b

<p class="post-content-excerpt">While I don’t care too much about ideas and projects that I believe to be
dead ends or maybe even doomed to fail eventually, a recent interaction on
<a href="https://マリウス.com/superhighway84">Superhighway84</a> got me to write down a few thoughts on
why I believe Project Gemini is a really bad idea.</p>
<div class="post-content-body">
<p>It all started with a simple post by someone on
<a href="https://マリウス.com/superhighway84">Superhighway84</a> who shared a link to their Gemini site. While
I was interested to see what that person was writing about and working on, I
couldn’t, because that person did not share a HTTP link, with the Gemini URL
as an alternative to it. Instead, it was only a Gemini URL.</p>
<p>Up until a while ago, people were trying out Gemini and only used it as sort of
a mirror for their HTTP content, meaning that everyone could browse their site
one way or the other. However, it seems that more and more people these days
have limited either all or parts of their publishing activity to Gemini. One
better known example I stumbled upon is Drew DeVault, who has been publishing
Gemini-exclusive content for a while now.</p>
<p>As long as projects like Gemini don’t make it harder for people, that aren’t
interested in them, to continue using the internet the way they’re comfortable
with, I don’t have much of an opinion on them. However, with Gemini seemingly
taking over more and more chunks of the things I consume, I felt like pointing
out a few things about the project that I believe make it a really bad idea to
pursue.</p>
<p>My reply to the person’s post on Superhighway84 was the following:</p>
<blockquote>
<p>Hey there,</p>
<p>let me throw in some unpopular opinion, if I might.</p>
<p>I understand where people promoting the smol web (a.k.a Gemini) are coming from
and I feel the same pain on a daily basis. The modern web sucks.
However, I feel like Gemini is <em>solutionism at its worst</em>. If you compare a
single HTTP/1.1 request with a Gemini request you will find out that it’s not
the protocol that’s the issue. HTTP can be made incredibly light. In fact, it
can be so light that even embedded devices (e.g. Arduinos) these days know how
to talk it.</p>
<p>What Gemini is doing, is saying “we don’t need no videos, images, stylesheets,
nor JavaScripts, because we want to have a lightweight web experience, so we
throw all that crap out!”. Fine, sounds great. But why does it require a new
protocol for that? Why couldn’t one simply build on top of existing HTTP
infrastructure, throw away all the baggage and instead implement a new
Content-Type, which existing browsers then could parse?</p>
<p>Existing infrastructure could have been extended to offer a more lightweight
experience of the web that doesn’t come with JS, CSS or anything else. People
then could decide whether they want to go the extra mile of installing Lagrange
or any other dedicated Gemini browser, or simply have a browser extension that
would take care of rendering the Content-Type properly. But Gemini forces people
into a completely different stack. Different servers. Different browsers. Heck,
not even it’s “markdown” is actual markdown, because&amp;mldr;</p>
<blockquote>
<p>There are actually many subtly different and incompatible variants of Markdown
in existence, so unlike TLS all the different libraries are not guaranteed to
behave similarly.</p>
</blockquote>
<p>&amp;mldr; and that’s why it’s obviously a good idea to introduce <strong>another</strong> variant
of Markdown. Makes sense?</p>
<p>Pretty much everything that is being described in the Gemini FAQ could have been
solved on top of already existing protocols and technologies, making it more
available to people. (<a href="https://gemini.circumlunar.space/docs/faq.gmi">https://gemini.circumlunar.space/docs/faq.gmi</a>)</p>
<p>Also, Gemini is asking the wrong questions. For example:</p>
<blockquote>
<p>Why not just use a subset of HTTP and HTML?</p>
</blockquote>
<p>The question here shouldn’t be why not to use a subset of HTTP <em>and</em> HTML, but
rather, why not build <em>on top of</em> HTTP with a different markup layer other than
HTML. We have APIs using HTTP with JSON instead of HTML, for example.</p>
<p>Hence, Gemini, its own text/gemini format, and most of its design choices are
addressing problems that don’t really exist. It’s not significantly different to
existing HTTP infrastructure to justify introducing a new protocol - and it even
depends on it for e.g. offering large files for download.</p>
<p>It’s also not IPFS or ZeroNet. It’s not a blockchain. It’s not bittorrent. It
feels like the people working on/running Gemini infrastructure don’t want to
actually solve the issues with the modern day web and instead just wanted to be
different, for the sake of being different. But unlike for example DAT, that has
truly been different, Gemini however follows the same outdated ideas and
principles that have been around since the 80s and imposes restrictions on
everything they’re not comfortable solving, e.g. file downloads or data
submission.</p>
<p>To me Gemini feels like today’s over-hyped computer version of Teletext.</p>
</blockquote>
<p>In order to make it clear what I mean by <em>building on top of existing HTTP
infrastructure</em>, let me give an actual example.<br>
When your web browser requests a website, it has to connect to the server
hosting that website. That’s usually a TCP connection on port 80 or 443,
depending on whether or not that website is using any sort of transport
encryption. To keep it simple I’m not going into the details of SSL/TLS
here, however, as it’s an encapsulation around the HTTP protocol, requesting
content is identical no matter if the connection is encrypted or not.</p>
<p>Let’s assume I’d like to browse
<a href="http://motherfuckingwebsite.com">motherfuckingwebsite.com</a>. As soon as I enter
the URL in my browser’s address bar, my browser is going to do pretty much the
same that I’ll be doing here using the <code>telnet</code> command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh">telnet motherfuckingwebsite.com <span class="m">80</span>
Trying 108.62.0.112...
Connected to motherfuckingwebsite.com.
Escape character is <span class="s1">'^]'</span>.
GET /index.html HTTP/1.1
Host: motherfuckingwebsite.com

</code></pre></div><p>That’s it.
That’s the bare minimum that this server accepts in order for me to request
the website from it. Most of the time however, browsers will send more
information, like for example the <code>User-Agent</code>, the <code>Accept</code>, <code>Accept-Encoding</code>
and <code>Accept-Language</code> headers, maybe some <code>Cache-Control</code> info, and more
things, depending on which browser you use. While these bits of
information are helping the communication, it’s not like requesting
content without them wouldn’t work at all. The request that I typed into
<code>telnet</code> does not contain any of these headers, yet the server successfully
returns the website that I’m requesting, and even tells me how to interpret this
response:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh">HTTP/1.1 <span class="m">200</span> OK
Connection: Keep-Alive
Keep-Alive: <span class="nv">timeout</span><span class="o">=</span>5, <span class="nv">max</span><span class="o">=</span><span class="m">100</span>
content-type: text/html
last-modified: Sun, <span class="m">18</span> Jan <span class="m">2015</span> 00:04:33 GMT
accept-ranges: bytes
content-length: <span class="m">5108</span>
date: Sun, <span class="m">16</span> Jan <span class="m">2022</span> 22:10:29 GMT
server: LiteSpeed

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta <span class="nv">charset</span><span class="o">=</span><span class="s2">"utf-8"</span>&gt;
    &lt;meta <span class="nv">name</span><span class="o">=</span><span class="s2">"viewport"</span> <span class="nv">content</span><span class="o">=</span><span class="s2">"width=device-width, initial-scale=1"</span>&gt;

    &lt;!-- FOR THE CURIOUS: This site was made by @thebarrytone. Don<span class="s1">'t tell my mom. --&gt;
</span><span class="s1">
</span><span class="s1">    &lt;title&gt;Motherfucking Website&lt;/title&gt;
</span><span class="s1">&lt;/head&gt;
</span><span class="s1">
</span><span class="s1">&lt;body&gt;
</span><span class="s1">    &lt;header&gt;
</span><span class="s1">        &lt;h1&gt;This is a motherfucking website.&lt;/h1&gt;
</span><span class="s1">        &lt;aside&gt;And it'</span>s fucking perfect.&lt;/aside&gt;
    &lt;/header&gt;

        &lt;h2&gt;Seriously, what the fuck <span class="k">else</span> <span class="k">do</span> you want?&lt;/h2&gt;

        &lt;p&gt;You probably build websites and think your shit is special. You think your <span class="m">13</span> megabyte parallax-ative home page is going to get you some fucking Awwward banner you can glue to the top corner of your site. You think your 40-pound jQuery file and <span class="m">83</span> polyfills give IE7 a boner because it finally has box-shadow. Wrong, motherfucker. Let me describe your perfect-ass website:&lt;/p&gt;

        &lt;ul&gt;
            &lt;li&gt;Shit<span class="s1">'s lightweight and loads fast&lt;/li&gt;
</span><span class="s1">            &lt;li&gt;Fits on all your shitty screens&lt;/li&gt;
</span><span class="s1">            &lt;li&gt;Looks the same in all your shitty browsers&lt;/li&gt;
</span><span class="s1">            &lt;li&gt;The motherfucker'</span>s accessible to every asshole that visits your site&lt;/li&gt;
            &lt;li&gt;Shit<span class="s1">'s legible and gets your fucking point across (if you had one instead of just 5mb pics of hipsters drinking coffee)&lt;/li&gt;
</span><span class="s1">        &lt;/ul&gt;
</span><span class="s1">
</span><span class="s1">        &lt;h3&gt;Well guess what, motherfucker:&lt;/h3&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;You. Are. Over-designing. Look at this shit. It'</span>s a motherfucking website. Why the fuck <span class="k">do</span> you need to animate a fucking trendy-ass banner flag when I hover over that useless piece of shit? You spent hours on it and added <span class="m">80</span> kilobytes to your fucking site, and some motherfucker jabbing at it on their iPad with fat sausage fingers will never see that shit. Not to mention blind people will never see that shit, but they don<span class="s1">'t see any of your shitty shit.&lt;/p&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;You never knew it, but this is your perfect website. Here'</span>s why.&lt;/p&gt;

        &lt;h2&gt;It<span class="s1">'s fucking lightweight&lt;/h2&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;This entire page weighs less than the gradient-meshed facebook logo on your fucking Wordpress site. Did you seriously load 100kb of jQuery UI just so you could animate the fucking background color of a div? You loaded all 7 fontfaces of a shitty webfont just so you could say "Hi." at 100px height at the beginning of your site? You piece of shit.&lt;/p&gt;
</span><span class="s1">
</span><span class="s1">        &lt;h2&gt;It'</span>s responsive&lt;/h2&gt;

        &lt;p&gt;You dumbass. You thought you needed media queries to be responsive, but no. Responsive means that it responds to whatever motherfucking screensize it<span class="s1">'s viewed on. This site doesn'</span>t care <span class="k">if</span> you<span class="s1">'re on an iMac or a motherfucking Tamagotchi.&lt;/p&gt;
</span><span class="s1">
</span><span class="s1">        &lt;h2&gt;It fucking works&lt;/h2&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;Look at this shit. You can read it ... that is, if you can read, motherfucker. It makes sense. It has motherfucking hierarchy. It'</span>s using HTML5 tags so you and your bitch-ass browser know what the fuck<span class="s1">'s in this fucking site. That'</span>s semantics, motherfucker.&lt;/p&gt;

        &lt;p&gt;It has content on the fucking screen. Your site has three bylines and link to your dribbble account, but you spread it over <span class="m">7</span> full screens and make me click some bobbing button to show me how cool the jQuery ScrollTo plugin is.&lt;/p&gt;

        &lt;p&gt;Cross-browser compatibility? Load this motherfucker in IE6. I fucking dare you.&lt;/p&gt;

        &lt;h2&gt;This is a website. Look at it.  You<span class="s1">'ve never seen one before.&lt;/h2&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;Like the man who'</span>s never grown out his beard has no idea what his <span class="nb">true</span> natural state is, you have no fucking idea what a website is. All you have ever seen are shitty skeuomorphic bastardizations of what should be text communicating a fucking message. This is a real, naked website. Look at it. It<span class="s1">'s fucking beautiful.&lt;/p&gt;
</span><span class="s1">
</span><span class="s1">        &lt;h3&gt;Yes, this is fucking satire, you fuck&lt;/h3&gt;
</span><span class="s1">
</span><span class="s1">        &lt;p&gt;I'</span>m not actually saying your shitty site should look like this. What I<span class="s1">'m saying is that all the problems we have with websites are &lt;strong&gt;ones we create ourselves&lt;/strong&gt;. Websites aren'</span>t broken by default, they are functional, high-performing, and accessible. You <span class="nb">break</span> them. You son-of-a-bitch.&lt;/p&gt;

        &lt;blockquote <span class="nv">cite</span><span class="o">=</span><span class="s2">"https://www.vitsoe.com/us/about/good-design"</span>&gt;<span class="s2">"Good design is as little design as possible."</span>&lt;br&gt;
            - some German motherfucker
        &lt;/blockquote&gt;

    &lt;hr&gt;

    &lt;h2&gt;Epilogue&lt;/h2&gt;
    &lt;p&gt;From the philosophies expressed <span class="o">(</span>poorly<span class="o">)</span> above, &lt;a <span class="nv">href</span><span class="o">=</span><span class="s2">"http://txti.es"</span>&gt;txti&lt;/a&gt; was created. You should try it today to make your own motherfucking websites.&lt;/p&gt;

    &lt;!-- yes, I know...wanna fight about it? --&gt;
    &lt;script&gt;
      <span class="o">(</span><span class="k">function</span><span class="o">(</span>i,s,o,g,r,a,m<span class="o">){</span>i<span class="o">[</span><span class="s1">'GoogleAnalyticsObject'</span><span class="o">]=</span>r<span class="p">;</span>i<span class="o">[</span>r<span class="o">]=</span>i<span class="o">[</span>r<span class="o">]||</span><span class="k">function</span><span class="o">(){</span>
      <span class="o">(</span>i<span class="o">[</span>r<span class="o">]</span>.q<span class="o">=</span>i<span class="o">[</span>r<span class="o">]</span>.q<span class="o">||[])</span>.push<span class="o">(</span>arguments<span class="o">)}</span>,i<span class="o">[</span>r<span class="o">]</span>.l<span class="o">=</span>1*new Date<span class="o">()</span><span class="p">;</span><span class="nv">a</span><span class="o">=</span>s.createElement<span class="o">(</span>o<span class="o">)</span>,
      <span class="nv">m</span><span class="o">=</span>s.getElementsByTagName<span class="o">(</span>o<span class="o">)[</span>0<span class="o">]</span><span class="p">;</span>a.async<span class="o">=</span>1<span class="p">;</span>a.src<span class="o">=</span>g<span class="p">;</span>m.parentNode.insertBefore<span class="o">(</span>a,m<span class="o">)</span>
      <span class="o">})(</span>window,document,<span class="s1">'script'</span>,<span class="s1">'//www.google-analytics.com/analytics.js'</span>,<span class="s1">'ga'</span><span class="o">)</span><span class="p">;</span>

      ga<span class="o">(</span><span class="s1">'create'</span>, <span class="s1">'UA-45956659-1'</span>, <span class="s1">'motherfuckingwebsite.com'</span><span class="o">)</span><span class="p">;</span>
      ga<span class="o">(</span><span class="s1">'send'</span>, <span class="s1">'pageview'</span><span class="o">)</span><span class="p">;</span>
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;
</code></pre></div><p>On the other hand, according to its specification, a request on the Gemini
protocol looks like this:</p>
<blockquote>
<p>2 Gemini requests</p>
<p>Gemini requests are a single CRLF-terminated line with the following structure:</p>
<p>&lt;URL&gt;&lt;CR&gt;&lt;LF&gt;</p>
<p>&lt;URL&gt; is a UTF-8 encoded absolute URL, including a scheme, of maximum length
1024 bytes. The request MUST NOT begin with a U+FEFF byte order mark.</p>
<p>Sending an absolute URL instead of only a path or selector is effectively
equivalent to building in a HTTP “Host” header. It permits virtual hosting of
multiple Gemini domains on the same IP address. It also allows servers to
optionally act as proxies. Including schemes other than “gemini” in requests
allows servers to optionally act as protocol-translating gateways to e.g. fetch
gopher resources over Gemini. Proxying is optional and the vast majority of
servers are expected to only respond to requests for resources at their own
domain(s).</p>
<p>Clients MUST NOT send anything after the first occurrence of &lt;CR&gt;&lt;LF&gt; in a
request, and servers MUST ignore anything sent after the first occurrence of a
&lt;CR&gt;&lt;LF&gt;.</p>
</blockquote>
<p>When comparing the most minimal version of an HTTP request with a standard
Gemini request, it turns out that the only difference is a single additionally
required header (<code>Host</code>) and a few additional characters (<code>GET</code> and <code>HTTP/1.1</code>)
in the HTTP request. Hence, Gemini’s argument of being <em>“lighter than the web”</em>
doesn’t make that much of a difference at all from a protocol perspective, and
it certainly does not justify <strong>completely replacing existing infrastructure and
standards that humans have mutually agreed upon</strong>.</p>
<p><em>“But what about the response and the content?"</em>, you might be wondering.
Well, it’s a similar story there. By default, regular HTTP servers will include
all sorts of information in their response that will allow the browser to
process it more easily/without a lot of <em>guesstimating</em>. However, it would
nevertheless be possible to bend existing HTTP servers to only include the bare
minimum additional info in their response, that would still allow a modern
browser to process the data.</p>
<p>As for the actual content, it is easily possible to configure a modern HTTP
server like nginx to respond with nothing but pure Markdown. Users could then
install either of the
<a href="https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-webext/">dozens</a>
of
<a href="https://addons.mozilla.org/en-US/firefox/addon/markdown-viewer-chrome/">extensions</a>
available for their web browser, to be able to visit the Markdown-only websites
more comfortably. If Gemini would have gone that path, people interested in <em>the
smol internet</em> would still be able to develop custom tailored clients that only
work with these type of websites, and that would not include all the baggage that
comes with any modern browser. Everybody else, on the other hand, could continue
using the tools their familiar with and would still be able to to consume the
content.</p>
<p>Gemini instead opted for a different direction, which <strong>actively excludes people</strong>,
while it <strong>does not deliver anything new nor beneficial</strong> that would justify
dismissing existing standards and infrastructure in first place. Gemini is
solutionism at its worst and is more about exclusion of the mainstream over
bringing actual technological advancement, let alone fixing the issues it
baselessly claims to be fixing. Gemini does not bring new ideas to the table,
but instead uses decade old concepts from HTTP and Gopher, to implement a
castrated and badly designed version of its own, just for the sake of it not
being HTTP nor Gopher.</p>
<blockquote>
<p>To me, Gemini looks like a mix of Gopher and HTTP/0.9 and it’s a mystery to me
why you would rather write a new protocol so similar to those rather than just
stick to what already exists.<br>
– <a href="https://curl.se/mail/lib-2020-11/0084.html">Daniel Stenberg, founder and lead developer of cURL</a></p>
</blockquote>
<p><em>“But&amp;mldr; but&amp;mldr; it takes user privacy <strong>very seriously</strong>?"</em><br>
Okay, how so? Let’s quickly check the FAQ:</p>
<blockquote>
<p>2.1.2 Privacy</p>
<p>Gemini is designed with an acute awareness that the modern web is a privacy
disaster, and that the internet is not a safe place for plaintext. Things like
browser fingerprinting and Etag-based “supercookies” are an important cautionary
tale: user tracking can and will be snuck in via the backdoor using protocol
features which were not designed to facilitate it. Thus, protocol designers must
not only avoid designing in tracking features (which is easy), but also assume
active malicious intent and avoid designing anything which could be subverted to
provide effective tracking. This concern manifests as a deliberate
non-extensibility in many parts of the Gemini protocol.</p>
</blockquote>
<p>Turns out, neither the FAQ nor the protocol precisely pin-point how exactly
Gemini takes <em>privacy seriously</em>. They call out typical buzzwords like
<em>supercookies</em> and <em>fingerprinting</em> and suggest that due to the protocol’s
<em>non-extensibility</em> Gemini is more privacy-focused than the <em>modern web</em>. Then,
on the other hand, Gemini users
<a href="https://curl.se/mail/lib-2020-11/0083.html">write things like this</a>:</p>
<blockquote>
<ul>
<li>Certificate verification. Gemini servers rarely use certificates with
trust chain from certificates in /etc/ssl/certs; self-signed
certificates are the norm. Option -k should be the default for gemini
protocol.</li>
</ul>
</blockquote>
<p>Ah yes, that is how <em>taking privacy seriously</em> looks like. Besides, what about
the visitor’s IP address? Gemini servers can certaily see that. Nowhere in its
official documentation Gemini seems to care about telling users this detail, let
alone whether or not they’re able to browse via Tor or if there’s any client
that would support Tor right out-of-the-box.</p>
<p>Also, what if I wrote my own Gemini server – judging by its protocol that’s
something one could do within a few hours – that would attach
per-initial-request generated hashes to all links?
Thereby, when a user visits my Gemini site, they would get a unique
hash assigned, which would then be sent to my server every time they follow a
link to a different subsite. I could track the user’s browsing behaviour across
my site, just like HTTP sites do these days. If I store these requests,
plus the IP address the user is coming from, I would already gather some
interesting data points.<br>
What if I would perform a quick investigation of the TCP/IP packets
additionally? E.g. the initial packet size, the window- and segment-size, the
initial TTL, individual flags? I could make my Gemini server use such
fingerprinting techniques to gather more info and store that as well. If I’d
be really up to something, I could have all sorts of additional checks and
scans running for every new connection. Even if the user would connect through
a NATted IP, I could eventually gain enough intel to be able to tell
with relatively high confidence if a request was made by a visitor I’ve seen
before or not, especially with such a small user-base (as compared to HTTP).
Let alone all the still to be discovered exploits within individual client
implementations, that might as well lead to potential privacy or even security
risks.</p>
<p>Bottom line is, if you agree that the modern web has become an awful place,
let’s work on changing that for everyone, instead of abandoning it like a
bunch of billionaires trying to escape to a different place, before this
one collapses.</p>
<p>The reason this website looks the way it does, is not because it follows the
latest online trends, but because it’s everything that is required to efficiently
transport information from me to you, using tools that we’re both familiar with,
while staying out of both our ways.<br>
If you don’t like how modern websites track their users and flood them with
ads, then don’t do that on your website, contribute to projects like
uBlock Origin, Privacy Badger and Tor, and stop using websites that <strong>do</strong> track
their users or spam them with ads.
If you don’t like JavaScript, don’t use it or use it in a way in which
your site will still function even without it, and stop using websites that won’t
even load without JavaScript enabled.
If you’re not a fan of CSS, don’t use it, nobody forces you to style your HTML
and most browsers include a fairly accessible default stylesheet.
Heck, if you’re as much of a purist as the Gemini folks claim to be and don’t
want neither videos nor images on your website, simply don’t put any there.
<a href="http://motherfuckingwebsite.com">motherfuckingwebsite.com</a> is a perfect example
of a website that uses none of all that while still functioning flawlessly.</p>
<p>Ultimately, serving content solely via Gemini will only lead to it becoming
<strong>less</strong> accessible and available to other people. Moving to Gemini is the
opposite of inclusive, it’s exclusive. It’s a step in the wrong direction.</p>
