I Replaced My Web Stack With Gopher (1991) and Failed Less
___
|_ _|
| |
|___|
___ _ _
| _ \ ___ _ __ | | __ _ __ ___ __| |
| / / -_) | '_ \ | | / _` | / _| / -_) / _` |
|_|_\ \___| | .__/ |_| \__,_| \__| \___| \__,_|
|_|
__ __
| \/ | _ _
| |\/| | | || |
|_| |_| \_, |
|__/
__ __ _
\ \ / / ___ | |__
\ \/\/ / / -_) | '_ \
\_/\_/ \___| |_.__/
___ _ _
/ __| | |_ __ _ __ | |__
\__ \ | _| / _` | / _| | / /
|___/ \__| \__,_| \__| |_\_\
__ __ _ _ _
\ \ / / (_) | |_ | |_
\ \/\/ / | | | _| | ' \
\_/\_/ |_| \__| |_||_|
___ _
/ __| ___ _ __ | |_ ___ _ _
| (_ | / _ \ | '_ \ | ' \ / -_) | '_|
\___| \___/ | .__/ |_||_| \___| |_|
|_|
__ _ ___ ___ _ __
/ / / | / _ \ / _ \ / | \ \
| | | | \_, / \_, / | | | |
| | |_| /_/ /_/ |_| | |
\_\ /_/
_
__ _ _ _ __| |
/ _` | | ' \ / _` |
\__,_| |_||_| \__,_|
___ _ _ _
| __| __ _ (_) | | ___ __| |
| _| / _` | | | | | / -_) / _` |
|_| \__,_| |_| |_| \___| \__,_|
_
| | ___ ___ ___
| |__ / -_) (_-< (_-<
|____| \___| /__/ /__/
╔─*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*─╗
║1 ........................................ 1║
║2* ........................................ *2║
║3 ........................................ 3║
║1 ...........Posted: 2026-01-22........... 1║
║2* Tags: gopher haskell my_warez my_servs . *2║
║3 ........................................ 3║
║1 ........................................ 1║
╚────────────────────────────────────────────────╝
# RFC-ish
Please *DO NOT* share.
If you're reading this it's because I think your opinion *particularly* matters
when it comes to software design and/or the Gopher Protocol, or something along
those lines.
I'm looking for comments along these lines:
* Spirit/abstract of this message as well as the style (the vibes and overall
message)
* Technical inaccuracies
* Missing counterarguments
* Places I'm being hand-wavy
* Links/sources I should add
* Alternative titles (or if you like the current, or could suggest another)* I
Replaced Complexity with Intimacy: A Love Letter to RFC 1436
* Scale Dazzles, Intimacy Sustains: A Formal Defense of Gopher
Please submit any comments to me via:
* IRC/XMPP: https://gopher.someodd.zip/services/irc.md (I'm also in the Bitreich
IRC, but I may miss your message)
* Email: hi@someodd.zip
* Mastodon: @someodd@fosstodon.org[1]
* You could even leave a comment on Phorum[2] or Interlog[3]
# Intimacy in the Forgotten Stack
*- Scale dazzles; intimacy sustains.*
> "I find no peace, and yet I make no war; I fear, I hope, I burn, and I am ice;
> I fly above the heavens, yet lie on the ground; And nought I have, and all the
> world I seize on." -- *Petrarch, Canzoniere 134*
*Don't worry, this isn't going to be one of those essays where a guy quotes
Petrarch and then explains Kubernetes.* However, I feel the simple prose of
Gopher replacing my modern software stack merits flourish.
I replaced a modern web stack with a 1991 protocol and got fewer failures and
more time to spend joyfully.
A system is a love poem. Perhaps short, hopefully faithful in form: composed of
verses that speak to each other, remembered by heart, and carried as one's own
craft.
Fidelity lives in intimacy. The romance of lovable systems lies in three
virtues:
* **Knowability**: small enough to live in your head.
* **Composability**: its parts can be *composed like verses*, each complete,
each
in dialogue.
* **Ownership**: you bear the stake, so you care.
From these emerge resilience, clarity, and joy.
My proof is **Gopher**: a 1991 protocol whose RFC you can whisper like a sonnet.
On it I've built and self-hosted a publishing stack. I chose it because those
three virtues endure.
Some say Gopher is dead. True. So am I... *eventually*. Until then, let's serve
menus :p
(IMG) Closeup of my server
## The Value (beyond vibes)
> "Neither can embellishments of language be found without the order of thought,
> nor thoughts shine without the light of language." -- Cicero, *De Oratore* III
> (trans.)
**Cognition**: Humans don't scale; architecture must. Compose into units one
brain can hold. Short feedback loops cut repair time. Treat complexity as a
budget: spend it at seams, not in guesswork. Intimacy helps individual
understanding; shared mental models are still hard to build.
**Contracts**: Interfaces are promises. State inputs, outputs, guarantees;
version them small. When seams aren't in daylight, microservices congeal into a
distributed monolith. Contracts alone don't create shared meaning.
**Ownership**: Reliability is a who. If everyone owns it, no one does. Name a
steward, grant authority, and keep accountability humane. Most failures begin at
unowned handoffs. The cost is a bus factor--so intimacy needs an exit plan, for
a new brain to rely on.
**Joy**: Joy is operational. Teams maintain what they love; miserable tools get
bypassed. Fast to hack means fast to debug and easy to teach: morale compounds
into uptime.
As an extreme case, I wrote a Gopher daemon in i386 assembly (gasm[4]): ~2 KB
binary, ~24 KB RAM at runtime.
This approach doesn't replace large-scale systems; it constrains parts of them.
Scale isn't forbidden. Aim to keep some components small enough to reason about.
I use this where it fits: edges, tools, internal services, publishing, glue.
This thesis locates exactly where intimacy belongs: at the seams.
## A Smaller Internet Taught Me This
> "Simplicity is intentional." -- *RFC 1436*
*I've seen stacks with more layers than a Viennese pastry. Gopher, by contrast,
is toast.*
Most people assume the web *is* the Internet. Click a link, scroll a page,
curtain falls; applause. But that's only one act of a much older play.
Gopher was born at the University of Minnesota, 1991. Specified in RFC 1436[5],
brief, deliberate, legible. In fact, "surfing the Internet" was coined before
the web by Gopher's own Mark McCahill[6].
Quick technical overview (see its simplicity, knowability, composability):
- Send a *selector* like `/foo/bar.txt` or `Hello, world!` to the server, get
back text/file/menu
- Menu-driven navigation: special text the client knows how to present; each of
its lines links to a *selector* with a letter code the client needs in order
to understand how to present the content it links to (text/menu/file)
- Its flourish, `IndexSearch`, simply sends a user-specified string to a
selector, getting a menu back
- Therefore, strict separation of navigation and content
- The rest is up to the client, the user, that's the contract
That's the whole contract. That restraint is decadent. Its simplicity is
permissive; I made/ported games on my gopherhole[7] (having even turned ALL of
Gopherspace into an MMORPG[8]).
The Internet Gopher Protocol hides a lesson in its structure: simple, easily
glued together, easy to master. The point is the shape of the relationships you
can still see.
Simplicity is compression for the mind.
### How I Fell In (and Stayed)
> "In striving to be brief, I become obscure." -- Horace, *Ars Poetica*.
I fell into Gopher by implementing the spec. I wrote a tiny client, Waffle[9],
straight from RFC 1436[10], that experience started a journey that rewired my
taste.
Pressure-testing Gopher through heavy self-hosting[11], adjacent protocols like
Gemini[12] (richer, but more complex), participation at Bitreich[13] (Gopher
liminalists led by a suckless[14] trickster), and conversations with people who
built these systems (including Gopher and first MMORPG[15] co-author Bob
Alberti[16]) made a pattern obvious: legibility enables punk hackability.
All this rewired my taste. I now bias toward protocols and tooling I can explain
end-to-end, because that collapses debugging time and makes iteration cheap.
Gopher is small enough that experimentation stays local--when something breaks,
the failure surface is still human-scale.
The smallness of the protocol also gave me room to experiment with
LiquidHaskell[17] and Nix[18]. Gopher's narrow grammar, thus clarity, separated
novelty from signal and sharpened my sense of the Unix creed: *do one thing
well, and glue it with joy.*
Constraints aren't cages; they're invitations.
*Tell someone you're writing a Gopher server in 2025 and they look at you like
you hand-weave shoelaces. Which... yes.*
## The Stack, the Masquerade
> "And all things are bound together, each by its secret affinity." -- Giordano
> Bruno, *De Vinculis in Genere* (On Bonds in General)
The masquerade is choreography.
It's three small daemons with narrow contracts: build, serve, search.
Behind the velvet masks and candle-smoke, everyone knows their part. The music
is simple. The rules are strict. That is why the dance holds.
**Bore: the Scrivener.**[19] At the corner table, he scratches furiously with a
quill. Every file I drop in a directory, he arranges into order: indexes, feeds,
flourishes, prepared for gopherspace. His fidelity is quiet and absolute.
**Venusia: the Confidant.**[20] From boring, quotidian tomes, to occult
incantations of READMEs which are actually Literate Haskell Scripts[21], she
whispers it onto the public wire. Private to published is a single breath.
**Ryvm: the Librarian.** [22] Among crowded shelves kept in careful order, he
retrieves fitting volumes according to inquiry. Technically, a full text search
engine for the file system which is formally verified (using LiquidHaskell
[practical here precisely because the surface area is small]): query in,
documents out. Memory without mysticism.
Together they dance: Scrivener, Confidant, Librarian. Their steps are simple,
their composition resilient.
Their secret: the masks are swappable.
Bore could be Make; Venusia, gophernicus; Ryvm, `grep`.
The names are mnemonic; the architecture (e.g., separable contracts) matters
more than the cast.
Keep the contracts and the choreography holds.
------------------------------
What this makes possible (beyond Gopher):
- **Dashboards** that expose system health with the same ease as serving a poem.
- **Journaling** where each entry is an artifact, mirrored seamlessly to the
web.
- **Resilient hosting** on shaky Wi-Fi or tiny single-board machines -- the
stack hums even on a gondola's bandwidth.
"Why not just Markdown + S3?" Because protocol primitives shape cognition. Menus
and selectors discipline navigation and recovery. Venusia[23] can serve static
files *or* shell-scripted gopherapps with equal, hackable grace.
Compose systems as you would compose a sonnet: strict form, infinite play.
*My observability stack is called `tail -F`. Sometimes I upgrade it to
"coffee."*
### How it feels to maintain my gopherhole
On my laptop I mount `source/` over `sftp`, write a phlog in plain text with
some frontmatter[24] and maybe a small ASCII flourish. **Save.** Bore rebuilds,
The ryvm-searchable results appear in `output/`, which is served to gopherspace
by Venusia, which I also have mounted. `output/` also contains non-generated
files like media and binaries (and more text!), untouched by the build.
When I want something dynamic, I write a small Literate Haskell script (or a
longer one[25]) and configure Venusia ( `routes.toml`) to execute it via
`runghc`. Some examples on my gopherhole[26]:
* GopherGPT[27]: an LLM you can talk to via Gopher
* Interlog[28]: an experimental phorum
* Colossal Cave: play the original text adventure game!
No ceremony, no framework gravity.
I host a friend's elegant Gopher-HTTP proxy[29] I modified (which I use
here[30]). Sometimes I mirror to the web[31]. Jekyll sweeps the artifacts to
HTTP; a friend's proxy speaks `Gopher <-> HTTP` without drama.
The fastest RCA is the one your brain can run in real time.
*Most of the system's reliability comes from the fact that there isn't much of
it.*
## Reflection: Techno-Romance, Not Neo-Luddism
-- yet another tech manifesto?
> "Be wise, drink free, and scale your long hopes to the short measure of time."
> -- Horace, *Odes* I.11
This is a preference for systems small enough to be held. Love is a positive
quality, rather than a differential relation like "anti-bloat." I fell when I
could hold it in my head. The RFC had margins. Daemons had names. The shape of
the system was legible. Intimacy was the revelation.
I stopped caring about bug counts. What mattered was how fast I could understand
them. The hard problem is actually the limits of minds.
> "Thinking of it like that, a method of easily serving directories of data,
> **rather than a scaled down web** makes the whole thing more appealing I
> think." -- Rob Sayers
From small, stubborn tools I learned something larger than any protocol: that
constraint *aims* creativity. That depth hides in restraint. That learning
happens fastest when a system resists excess and invites attention. A tool you
can know by heart teaches you how to think, not just how to deploy.
There was joy in the quiet satisfaction of care. Config files that behaved.
Systems whose quirks became familiar. That joy is a reliability feature, because
we maintain what we understand, and we understand what we stay close to.
Gopher got composted early (got this idea by interviewing Cory Doctorow for the
documentary), returning its nutrients to the soil: clarity, patience, craft.
What matters is choosing systems, and lives, that can be tended. To know a thing
deeply. To care for it responsibly. To leave it better than we found it.
That is enough.
## Closing invitation: Menu Walk with Me
I'm turning a page, and leaving a mark here. This stack remains my way of
publishing, my daily companion, my practice.
You can explore my gopherhole[32] (try Lagrange[33] [GUI] or Bitreich's sacc[34]
[TUI]) , open an issue on GitHub, or drop by my IRC/XMPP, or other services[35].
I'll be there: maintaining, debugging, supporting, building.
Come walk the menus. If the conversation holds, let's work together.
## Special thanks
- **Bob Alberti**, for generosity, history, and play. And y'know, for his work
on the Internet Gopher Protocol.
- **Screwlisp**
- **Bitreich**[36], without which this thesis and my deep love of Gopher would
never have crystalized. Their work on bringing Gopher with into 2026 and
beyond--and telling people why, is crucial.
- **Norm Macdonald**, for teaching restraint, timing, and when *not* to explain
the joke.
- **Federico Fellini**, **Andrea Zanzotto**, **Francesco Petrarca**, and
**Thomas Mann**, whose work shaped the voice and patience behind this essay.
*(Zanzotto collaborated directly on* Fellini's *Casanova*; this piece
knowingly borrows that lineage.)
- **The MADE**, for taking small histories seriously.
- The Gopher community and the wider smallnet/indieweb world, for keeping
clarity alive without spectacle.
- **Fosstodon**, for reviewing this document and for always being a well of
support.
- The users on my IRC and XMPP servers, who tolerate long explanations and ask
better questions.
And thank **you** for reading. At the core of all of this is a simple hope: that
care is legible, and that someone else might recognize it and respond.
## Footnotes
(HTM) [1]: @someodd@fosstodon.org: https://fosstodon.org/@someodd
(HTM) [2]: Phorum: https://gopher.someodd.zip/1//phorum
(HTM) [3]: Interlog: https://gopher.someodd.zip/1//interlog
(HTM) [4]: gasm: https://github.com/someodd/gasm
(HTM) [5]: RFC 1436: https://datatracker.ietf.org/doc/html/rfc1436
(HTM) [6]: Gopher's own Mark McCahill: https://en.wikipedia.org/wiki/Mark_P._McCahill
(BIN) [7]: my gopherhole: gopher://gopher.someodd.zip
(TXT) [8]: turned ALL of Gopherspace into an MMORPG: /phlog/gopherspace-rpg.gopher.md
(TXT) [9]: Waffle: /phlog/waffle.gopher.txt
(HTM) [10]: RFC 1436: https://www.rfc-editor.org/rfc/rfc1436
(HTM) [11]: self-hosting: https://gopher.someodd.zip/1/services
(HTM) [12]: Gemini: http://geminiquickst.art/
(TXT) [13]: participation at Bitreich: /phlog/brcon-2025.gopher.txt
(HTM) [14]: suckless: https://suckless.org
(TXT) [15]: first MMORPG: /phlog/scepter_of_goth.gopher.txt
(HTM) [16]: Bob Alberti: https://albatross.org
(HTM) [17]: LiquidHaskell: https://github.com/ucsd-progsys/liquidhaskell
(HTM) [18]: Nix: https://nixos.org/
(HTM) [19]: **Bore: the Scrivener.**: https://github.com/someodd/bore
(HTM) [20]: **Venusia: the Confidant.**: https://github.com/someodd/venusia/
(HTM) [21]: READMEs which are actually Literate Haskell Scripts: https://github.com/someodd/grpg/blob/master/README.md
(HTM) [22]: **Ryvm: the Librarian.** : https://github.com/someodd/ryvm
(HTM) [23]: Venusia: https://github.com/someodd/venusia
(HTM) [24]: frontmatter: https://jekyllrb.com/docs/front-matter/
(TXT) [25]: or a longer one: /phlog/gopherspace-rpg.gopher.md
(HTM) [26]: my gopherhole: https://gopher.someodd.zip
(HTM) [27]: GopherGPT: https://gopher.someodd.zip/0//phlog/chatgopherpt.gopher.txt
(HTM) [28]: Interlog: https://github.com/someodd/interlog
(HTM) [29]: a friend's elegant Gopher-HTTP proxy: https://github.com/sternenseemann/gopher-proxy
(HTM) [30]: here: https://gopher.someodd.zip
(HTM) [31]: I mirror to the web: https://www.someodd.zip/phlog-mirror
(TXT) [32]: my gopherhole: gopher://gopher.someodd.zip/
(HTM) [33]: Lagrange: https://gmi.skyjake.fi/lagrange/
(HTM) [34]: sacc: https://packages.debian.org/sid/sacc
(HTM) [35]: my IRC/XMPP, or other services: https://gopher.someodd.zip/services/
(BIN) [36]: **Bitreich**: gopher://bitreich.org