I put Gopher on Nostr. Now every npub is a gopherhole A developer has built GopherKind, a publisher and reader that stores gopherholes as signed Nostr events, turning every Nostr public key into a gopherhole. The tool generates Gopher menus from a user's existing Nostr activity and supports publishing path-addressed pages as kind 31436 events, with a specification proposed as a NIP. I've built GopherKind https://github.com/forgesworn/gopherkind , a publisher and reader for gopherholes stored as signed Nostr events. Every Nostr public key already works as a hole. GopherKind turns the account's profile, notes, replies, long-form articles, and the follows and followers visible through its relays into ordinary Gopher menus and text. An author can then publish proper path-addressed pages as kind 31436 events, and those pages take over the same hole. The same content is readable through Gopher, Gemini, the web and a terminal. Reading needs no account. The CLI publisher uses a NIP-46 remote signer, and GopherKind refuses raw secret keys completely. Try the idea before reading the explanation: npx gopherkind why npx gopherkind read darren@600.wtf There is also a live bridge https://gopherkind.com/ if installing something to find out what it does feels a bit backwards. Some old protocols deserve their quiet retirement. Gopher isn't one of them. Gopher got one thing very right in 1991: it separates information from interface. A hole is menus and text. The client decides how those things look, navigation works the same everywhere, and there is very little available for a publisher to use against the reader. No cookie banner. No consent platform. No autoplay. No infinite scroll trying to trick me into donating another hour of my life. Cameron Kaiser's essay on why Gopher is still relevant makes the argument properly. GopherKind can read it directly: npx gopherkind read gopher://gopher.floodgap.com/0/gopher/relevance.txt A site has to stand on what it says because there isn't much glitz available to hide behind. I like that. I don't especially like the structural weakness that comes with it. In RFC 1436 https://www.rfc-editor.org/rfc/rfc1436 , a gopherhole is a host. The writing depends on the hobby box under someone's desk, its power supply, a domain registration and the person who still remembers how it was configured. When that box disappears, the hole disappears with it. Copying the files elsewhere can preserve the bytes, but Gopher has no idea who wrote them. There is no authorship in the protocol and nothing in the document that survives the hostname. Nostr has almost exactly the missing pieces. Identity is a public key, events are signed, and an author can put copies on more than one relay. The signature stays with the document regardless of which relay or bridge served it. That was too exact a fit to ignore. GopherKind defines one addressable event kind, 31436 , numbered after RFC 1436. One event is one text document at one path: { "kind": 31436, "tags": "d", "/phlog/hello.txt" , "type", "0" , "title", "Hello from my hole" , "content": "Hello gopherspace.\n" } The d tag is the exact path. Type 0 is plain text. Type 1 is a menu written as a kindmap , which is a normal gophermap with the host and port columns removed because the document no longer belongs to a host. Welcome to my hole 0About me /about.txt 1Phlog /phlog 1A friend's hole npub1friend... hMy website https://example.com Kind 31436 is addressable, so publishing a newer event with the same public key and path replaces that page. The link doesn't change and the rest of the hole doesn't need to be rebuilt. The complete format is deliberately small. Paths, replacement selection, expiry, deletion, menu parsing and test vectors are in the proposed specification https://github.com/forgesworn/gopherkind/blob/main/SPEC.md . The proposal is also open as nostr-protocol/nips PR 2429 https://github.com/nostr-protocol/nips/pull/2429 . It is a proposal, not an accepted NIP, and I won't pretend otherwise. This is the part I find most interesting. A Nostr user doesn't need to publish any kind 31436 events before GopherKind can read their hole. When an authored document isn't present, it generates a virtual structure from events the account already has: / /profile.txt /notes /replies /mentions /articles /follows /followers /feed.xml Notes become a phlog. NIP-23 long-form articles become text pages. Available follows and followers become menus, and threads are navigable without reconstructing the conversation from a flat timeline. npx gopherkind read npub1... npx gopherkind read npub1.../notes An authored kind 31436 page wins when it uses the same path, so turning the generated hole into your own space is just publishing. There is no migration ceremony and no new identity to create. Nostr clients are generally built around the scroll. A note appears, moves down the timeline and is effectively buried. Gopher has the opposite temperament. A menu stays where the author put it and nothing on the screen is bidding for attention. The two protocols cover each other's awkward bits surprisingly well. An npub is the durable identity, but it isn't a particularly friendly address to give somebody. GopherKind accepts NIP-05 names anywhere it accepts a hole target, including a path after the name: npx gopherkind read darren@600.wtf npx gopherkind read darren@600.wtf/notes darren@600.wtf currently resolves to npub1mgvlrnf5hm9yf0n5mf9nqmvarhvxkc6remu5ec3vf8r0txqkuk7su0e7q2 , then GopherKind reads the signed events for that public key. The live bridge does the same thing https://gopherkind.com/go?npub=darren%40600.wtf , redirecting the friendly name to the canonical npub path before it renders the hole. That distinction matters. NIP-05 is a human-readable way in, controlled by the domain. It is not the document identity. If the domain owner changes where that name points tomorrow, the existing documents do not silently acquire a new author. Their signatures still belong to the original public key. A hole on disk is just a directory of text and menu files: my-hole/ |-- index.map |-- about.txt -- phlog/ |-- index.map -- 2026-08-10-hello.txt Publishing goes through a NIP-46 signer you already control. GopherKind never asks for an nsec , never generates one, and refuses a raw secret key if you try to give it one. npm install --global gopherkind gopherkind pair 'bunker://...' gopherkind publish ./my-hole --dry-run gopherkind publish ./my-hole gopherkind inspect npub1... The publisher discovers the author's NIP-65 write relays, publishes to their union with the configured relays, and reads every document back. Relay acceptance and successful read-back are reported separately because an OK response is not evidence that a reader can retrieve the event later. When the relays can report their current state, editing one page signs one changed document. If they can't be queried, GopherKind republishes everything because not knowing what is there is not the same as knowing it is current. gopherkind export recovers a relay-held hole into editable files, including a manifest that preserves exact paths which filenames can't safely represent. That gives me a useful recovery loop: gopherkind inspect npub1... gopherkind export npub1... ./recovered-hole gopherkind publish ./recovered-hole inspect proves what is retrievable now. It does not prove a relay will keep it next year. That distinction matters. GopherKind can read the relay-held events directly from the command line, or a bridge can expose them over three frontends: signed kind 31436 events on Nostr relays | | | -- terminal | -- bridge -- Gopher |-- Gemini -- HTTP The public reference bridge is available at: gopher://gopherkind.com/ gemini://gopherkind.com/ The bridge doesn't own the hole. It is one route to signed events held by relays. Run another compatible bridge and it can serve the same documents, or skip bridges completely and read the relays from the CLI. That is the important difference from putting a Gopher frontend in front of another website. There is no origin website hiding behind it. This would be very easy to oversell, so here are the boundaries. Relays are not archives. Publishing copies to several relays removes one host as the single point of failure. It doesn't guarantee that any relay will retain an event forever. Keep an export and check retrievability. Deletion is a request. NIP-09 asks relays to remove an event. A relay can ignore it, and another client may already have a copy. NIP-40 expiry tells a compliant bridge not to serve an expired event, but it is not a durable tombstone for older revisions a relay still holds. A bridge is still a server. It can go down. The point is that it isn't the one server carrying the only copy of the writing. Gopher is plaintext and unauthenticated. Network Gopher is permanently read-only in GopherKind. Writing happens through the terminal, HTTP or Gemini with a signer the author controls. Kind 31436 is still proposed. The implementation and conformance vectors exist today. Acceptance into the NIPs repository does not. Those aren't small-print caveats. They are part of deciding whether this is useful for something you care about. GopherKind is open source, MIT licensed and still deliberately below 1.0.0 . It needs Node 24 or newer. Reading costs no identity and changes nothing: npx gopherkind why npx gopherkind read darren@600.wtf npx gopherkind read darren@600.wtf/notes npx gopherkind read gopherkind@gopherkind.com npx gopherkind read gopher://gopher.floodgap.com/1/ The source, documentation and protocol proposal are on GitHub https://github.com/forgesworn/gopherkind . The live bridge https://gopherkind.com/ is there if you want to poke around first. I don't expect Gopher to replace the web. I do think some writing deserves a calmer interface and an address that isn't load-bearing on one forgotten box. GopherKind is still pre-1.0. The bridge works, the npm package works and the NIP proposal remains a proposal. That's the honest state of it.