gopherkind

Gopher · Nostr · kind 31436

Your writing outlives the box it was served from.

Gopherspace has one endemic disease: holes die. gopherkind turns gopher documents into signed Nostr events, so a hole belongs to your npub instead of a hostname, and any bridge that can fetch a copy serves it to any gopher client written since 1991.

MIT licensed. No token, no ads, no telemetry, no custody of your key. This page has no JavaScript and no trackers, which felt like the least we could do.

a hole that nobody published
$ gopherkind read npub1mgvlrnf5hm9yf0n5mf9nqmvarhvxkc6remu5ec3vf8r0txqkuk7su0e7q2
TheCryptoDonkey
===============

  TheCryptoDonkey
  a virtual hole generated from Nostr events

  Bitcoin, freedom, decentralisation, liberty advocate.

  Profile
      /npub1mgvlrnf.../profile.txt
  Notes
      /npub1mgvlrnf.../notes
  Articles (long-form)
      /npub1mgvlrnf.../articles
  Follows
      /npub1mgvlrnf.../follows
  Followers
      /npub1mgvlrnf.../followers
  Search
      /_gopherkind/search/npub1mgvlrnf...

Nobody published that. Every npub is already a hole, generated from the events the account has anyway. gopherkind also has a hole of its own, published the ordinary way: gopherkind read gopherkind@gopherkind.com

The problem

A hole is a host, and hosts stop.

The hobby box behind your favourite phlog loses power. A domain lapses. A university closes an alumni account. Fifteen years of writing stop existing, all at once, with no forwarding address.

This is structural, not careless. RFC 1436 has no notion of an author, so nothing in the protocol survives the hostname, and nothing in the wire format can prove who wrote a document even while the host is up.

Gopher had

Interface divorced from information

Menus and text, navigated identically, rendered by anything with a TCP stack. No fonts to load, no consent dialog, nothing bidding for your attention. It is why a protocol from 1991 still has readers.

Gopher lacked

Authorship and permanence

Copy a phlog to another server and it is just somebody's file: identical bytes, no provenance, no way to prove it was ever yours.

Nostr supplies

Keypair identity, signed documents

Events are signed, addressable and copied to relays you choose. Exactly the two things gopher never had. In return, gopher gives Nostr a reading room instead of a timeline.

How it works

A directory in, four protocols out.

Kind 31436 is named for the RFC. The d tag is the document's exact path, the type tag is the gopher item type, and menu content is a kindmap: a gophermap with the host and port columns removed, because the document no longer has a host.

Text files are signed into kind 31436 events, stored on relays, and served by any bridge to gopher, Gemini, HTTP and terminal clients. my-hole/ index.map about.txt sign kind 31436 d = /about.txt type = 0 signed by your npub publish relay relay relay your choice, plus NIP-65 fetch bridge any bridge gopher gemini http / lynx terminal Lose the bridge and the documents remain. Any other bridge serves the same signed events.
One router, four frontends. Reading needs no identity anywhere; writing always goes through a NIP-46 signer or a NIP-07 extension you control.

What changes

Four things gopher never had.

The hole belongs to an npub

Lose the machine and another bridge serves the same events from relays that still hold them. The hostname stops being a single point of failure.

Every document proves its author

The signature travels with the text, so a copy served by a stranger is still verifiably yours.

Editing keeps the address

Addressable replacement: change a file, publish again, and the document at that path is replaced everywhere. No dead links, no cache busting.

Everyone already has a hole

Profile, notes, replies, threads, articles, follows and followers render as menus and text with nothing published at all. Gopherspace grows by the entire Nostr userbase.

Four front doors

Pick the one you already live in.

SurfaceWhat it is forIdentity
gopherRFC 1436, type 7 search, every client since 1991 Read-only over the network, permanently. Plaintext has no safe credential.
geminigemtext, status 10 input, Lagrange and friends Client certificate bound to your NIP-46 signer
httpPlain HTML and real forms, aimed at lynx first Loopback is you; remote visitors use NIP-46 or a NIP-07 extension
terminalInteractive client in the VF-1 tradition, plus one-shot commands Your paired signer, or none at all for reading

It is a gopher client too, so traditional gopherspace renders through the same interface, and a gophermap that links to a bridge with an npub selector or a nostr: URI is followed natively through your own relays. Floodgap and an npub are the same kind of object once you are inside.

Quickstart

Ten minutes, and reading costs none of them.

needs Node 24 or newer
$ npm install --global gopherkind

# read anything, no key, no account, no configuration
$ gopherkind read npub1...
$ gopherkind read gopher://gopher.floodgap.com/1/
$ gopherkind why

# connect a signer you already control (Amber, nsec.app, Signet...)
$ gopherkind pair 'bunker://...'

# a directory of text files becomes a signed hole
$ gopherkind publish ./my-hole --dry-run
$ gopherkind publish ./my-hole
$ gopherkind inspect npub1...     # per-relay proof it is retrievable

# serve it: gopher 7070, gemini 1965, http 8070, loopback by default
$ gopherkind serve
$ lynx http://localhost:8070/

Never

Your key does not enter this program

No nsec input, no key generation, no custody of any kind. Signing happens in your NIP-46 signer or your NIP-07 extension. A bridge stores only its own client key, a TLS certificate and a mode-600 pairing file.

Also never

No build step, no database

Runs directly on Node 24 type stripping. A bridge keeps a state directory and a few minutes of cache. Two runtime dependencies, both pinned.

Full getting started guide →   FAQ →   The kind 31436 spec →

Honest limits

What this does not fix.

A project that oversold this would deserve to be ignored, so here is the whole list before you install anything.

  • Relays are not archives. Removing the single host removes one point of failure. It does not promise any relay keeps an event forever. Publish to relays you trust, keep an export, re-check with gopherkind inspect.
  • Deletion is a request. NIP-09 asks relays to forget and some will not. NIP-40 expiry is enforced by well-behaved bridges but is not a tombstone for a path with older revisions.
  • A bridge is still a host. It is simply no longer the host. If one disappears, the documents do not.
  • Kind 31436 is proposed, not accepted. The submission is PR #2429, unmerged at the time of writing. It ships with a language-neutral fixture and an independent Python implementation which passes it, because a format only one program can read is not a format.
  • Gopher stays read-only over the network. No authentication, no encryption, so no credential may ever cross it. 1991 gets to read; 2026 gets to write.

Support the work

Funding buys evenings. Evenings are all this is made of.

gopherkind is MIT licensed and unfunded. There is no company behind it, no token, no premium tier, no advertising and no data to sell, because it holds nothing about you. What there is: a public bridge with a monthly bill, and a maintainer writing after work.

Zap the maintainer directly:

npub1mgvlrnf5hm9yf0n5mf9nqmvarhvxkc6remu5ec3vf8r0txqkuk7su0e7q2

What it unlocks

  • Getting kind 31436 through NIP review, which is what makes other clients implement it
  • Packaging so running a bridge is a fifteen-minute job for someone else
  • A conformance suite so a second implementation is a weekend, not a month
  • Archival tooling: scheduled retrievability checks and alerts when copies thin out

Free ways to help

  • Publish a hole, so there is more to read
  • Run a bridge; more bridges is the entire point
  • Review the NIP, which is worth more than money
  • Report what broke, especially in odd clients
  • Tell one person. The failure mode here is silence, not criticism

What the money does, and what it will never do →