Serve your WordPress site over the Gopher protocol (RFC 1436). Because the web peaked in 1991.
____ _ ____
/ ___| ___ _ __ | |__ ___ _ __| _ \ _ __ ___ ___ ___
| | _ / _ \| '_ \| '_ \ / _ \ '__| |_) | '__/ _ \/ __/ __|
| |_| | (_) | |_) | | | | __/ | | __/| | | __/\__ \__ \
\____|\___/| .__/|_| |_|\___|_| |_| |_| \___||___/___/
|_|
Serving the web since 1991.
GopherPress runs a lightweight Gopher TCP daemon from inside WordPress, turning your posts, pages, and categories into a proper Gopher hole. It also exposes a REST endpoint so Gopher content is always reachable over HTTP — useful for managed hosts, curl, and the bundled local proxy.
Three ways to browse your site over Gopher:
| Mode | How | Requires |
|---|---|---|
| Native daemon | Point any Gopher client at gopher://yoursite.com:7070/ |
exec() or proc_open() on the server |
| REST endpoint | GET /wp-json/gopherpress/v1/serve?selector= |
Nothing — always available |
| Local proxy | Run node gopher-proxy.js locally, then use any Gopher client |
Node.js on your machine |
- WordPress 5.9+
- PHP 8.0+
exec()orproc_open()for the live daemon (optional — see below)
Install from the WordPress plugin directory, or drop the plugin folder into wp-content/plugins/ and activate it. Then go to the GopherPress admin page, set your port (default: 7070), and click START.
If exec() and proc_open() are both disabled on your host (common on managed WordPress platforms), the daemon controls are hidden. Your content is still fully accessible via the REST endpoint and the local proxy.
| Selector | Content |
|---|---|
(empty) or / |
Root menu |
recent |
Last 10 posts |
categories |
Category list |
category/{slug} |
Posts in a category |
post/{id} |
Individual post (by ID or slug) |
tags |
Tag cloud menu |
tag/{slug} |
Posts with a tag |
authors |
Author list |
author/{slug} |
Posts by an author |
archives |
Archive menu |
archives/{year} |
Year menu |
archives/{year}/{month} |
Month post list |
about |
About page |
about-gopher |
Gopher protocol history document |
search\t{query} |
Full-text search (Type-7) |
gopher |
ASCII gopher art |
secret |
Alias for about-gopher |
Post documents render with FIGlet ASCII art headings, inline images converted to aalib ASCII art, and [LINK: text → url] substitutions for hyperlinks.
The local proxy lets you browse your site with any legacy Gopher client without opening a public TCP port. It's a zero-dependency Node.js script that listens locally and forwards selectors to the GopherPress REST endpoint over HTTP.
Get the script
Download gopher-proxy.js from the Local Proxy section of the GopherPress admin page, or grab it directly from this repo at proxy/gopher-proxy.js.
Run it
node gopher-proxy.js --url=https://yoursite.comBy default it listens on localhost:7070. Use --port to change that:
node gopher-proxy.js --url=https://yoursite.com --port=7071Browse
Point any Gopher client at gopher://localhost:7070. For example, with Lynx:
lynx gopher://localhost:7070Options
| Flag | Default | Description |
|---|---|---|
--url |
(required) | Base URL of your WordPress site |
--port |
7070 |
Local port to listen on |
The proxy binds to 127.0.0.1 only — it is not reachable from other machines on your network.
Prerequisites: Composer, PHP 8.0+
git clone https://github.com/emrikol/gopherpress.git
cd gopherpress
composer install
npm installcomposer test # Run PHPUnit test suite
composer test:coverage # Run tests with coverage report
composer lint # Run PHPCS (WordPress Coding Standards)
composer lint:fix # Run PHPCBF auto-fixer
composer stan # Run PHPStan static analysis
composer dist # Build distributable zip → dist/gopherpress-{version}.zip
npm run lint:js # Run ESLintgopherpress.php # Plugin entry point, constants, hooks
inc/
class-admin.php # Admin page, AJAX handlers
class-content.php # Gopher content dispatcher (menus, posts, pages)
class-daemon.php # Daemon process management (start/stop/status)
class-rest.php # REST endpoint
class-figlet.php # FIGlet ASCII art renderer
class-aalib.php # AAlib ASCII art renderer (images → ASCII)
gopher-server.php # Gopher TCP server (spawned as a child process)
polyfills.php # WP function backports
assets/
admin.css # Retro terminal admin styles
admin.js # Admin page JS (AJAX controls, live log polling)
proxy/
gopher-proxy.js # Local Node.js proxy — bridges Gopher clients to the REST endpoint
tests/ # PHPUnit test suite
Tests use PHPUnit 11 with WordPress stubs — no running WordPress instance required.
This is a personal project. Issues and pull requests are not accepted. See CONTRIBUTING.md.
GPL-2.0-or-later. See LICENSE.