Open-source project
sartoopjj/thefeed avatar
sartoopjj/thefeed

thefeed review: DNS feed reading and encrypted chat in restricted networks

DNS-based feed reader and lite messenger for environments where only DNS queries work. Read Telegram channels and public X accounts, and exchange end-to-end-encrypted messages with other users — all over DNS.

1,593 stars87 forksGoMIT

At a glance

What is it?
thefeed carries Telegram and X feeds and encrypted user messages through DNS queries. It fits networks with limited connectivity, but operators must manage DNS, unsigned clients, and separate feed and chat domains.
Who is it for?
thefeed is appropriate for users whose networks permit only DNS and for operators willing to run a public DNS endpoint with delegated subdomains. It is a poor fit where DNS is filtered, blocked, logged aggressively or unsuitable for private messaging.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

thefeed targets DNS-only connectivity rather than general messaging

thefeed solves a transport problem rather than trying to replace a conventional feed reader or chat platform outright. Its documented environment is one where ordinary network access is restricted but DNS queries still get through. In that setting, a client can request Telegram channels and public X accounts through a thefeed server, and it can exchange end-to-end-encrypted messages with other thefeed users. The server sits outside the restricted network, collects the remote feed content, and returns it through encrypted DNS queries.

The intended users fall into two groups. Readers import a configuration into an existing client and do not need to operate infrastructure. Operators host a server outside the restricted environment, configure DNS delegation, choose Telegram channels and public X accounts, and distribute an import configuration to clients. The README divides these paths clearly: readers can import a configuration without running a server, while the server documentation is intended for operators hosting feeds for others.

This is a narrow design with a specific purpose. A standard RSS client still needs a network route to fetch a feed, and a normal web or application chat service expects more than DNS access. thefeed encodes its operations into DNS so the available protocol can carry them. That makes the project relevant where conventional endpoints are inaccessible. It does not claim that DNS is faster than ordinary HTTP, and the README gives no bandwidth or latency figures. Treating thefeed as a specialized fallback is more accurate than treating it as a universal messenger.

Server pull, encrypted DNS response and client import form thefeed's data path

The documented data flow begins with a server hosted outside the restricted network. It pulls content from Telegram channels and public X accounts, then answers encrypted DNS queries from clients. The client receives a configuration containing a domain, passphrase, server key shown as `sk=`, and bootstrap resolvers. That import object is important because the reader does not manually configure each feed or recreate the server protocol.

Feeds require DNS infrastructure. The operator must point `ns.example.com` at the server with an `A` record, then delegate `t.example.com` to that nameserver with an `NS` record. These are the two required records for the feed path. The messenger is optional and requires a separate delegated subdomain, such as `c.example.com`. Keeping chat on a distinct domain is not cosmetic guidance in this project: `.env.example` says the messenger domains must differ from the feed domains.

The server can answer additional feed domains through `THEFEED_EXTRA_DOMAINS`, allowing clients to spread queries across several names. The environment file describes this as load distribution and resilience when one domain is filtered, although it gives no quantitative measurement. The server also auto-generates an Ed25519 signing key in its data directory. According to `.env.example`, the server signs feed content and clients pin the public key through the `sk=` field. That integrity check is especially relevant to public configurations where the passphrase is shared.

The repository is primarily Go, with separate Android, iOS, macOS, mobile, server and shared internal areas. The module includes `github.com/miekg/dns`, Telegram client packages, cryptographic and networking dependencies, and BoltDB storage. Based on the repository layout, DNS handling, persistence and platform clients are separate implementation concerns. The README does not expose the complete query grammar, response encoding or chat relay algorithm, so those details should be checked in the relevant source files rather than inferred from dependency names.

Installing thefeed client and importing the first configuration

For a reader, the shortest documented route is to download the matching client and import a configuration. Android 7.0 and later can be installed through Google Play or by selecting the correct APK. TestFlight covers iOS 13 and later. Windows, macOS and Linux builds come from GitHub or GitLab release mirrors. Google Play and TestFlight are linked from the README, while direct desktop files are available through the release mirrors.

Architecture matters on Android. The README says `arm64-v8a` suits phones from around 2017 onward, while `armeabi-v7a` is for older 32-bit devices. It warns that installing the wrong ABI can produce an application that will not run. Linux and Termux users run `thefeed-client`, then open the local web interface shown in the documentation:

bash
thefeed-client

The client should then serve the interface at `http://127.0.0.1:8080`. That is the first concrete result to check. A public configuration is available through `@thefeedconfig`, or an operator can provide the domain and passphrase. On the client, open `Settings → Configs`, import the configuration, or paste the domain and passphrase. DNS resolvers are managed separately in the `Resolver` tab through a shared Bank, and the included Scanner can look for more resolvers.

No package-manager installation command is documented for these prebuilt clients, so none should be invented. The README also does not explain exactly how the Scanner identifies usable resolvers or how retries work when every resolver fails. Readers should distinguish an imported configuration problem from an inability to discover or reach a resolver before assuming that feed delivery is broken.

Running a thefeed server with DNS delegation and Docker

An operator must establish DNS before starting the server. For the README's example, create an `A` record for `ns.example.com` pointing to `203.0.113.10`, then delegate `t.example.com` to `ns.example.com`. Add a separate delegation for `c.example.com` only when enabling chat. These values are examples and must be replaced with the operator's actual server address and domains.

On Linux with systemd, the documented installer prompts for the domain, passphrase, channels and X accounts. It also asks whether to use Telegram login, with public channels listed as workable without login. Running the same installer again is documented as the update path. The GitHub command is:

bash
sudo bash -c "$(curl -Ls https://raw.githubusercontent.com/sartoopjj/thefeed/main/scripts/install.sh)"

The alternative GitLab command forces that mirror:

bash
sudo bash -c "$(curl -Ls https://gitlab.com/sartoopjj/thefeed/-/raw/main/scripts/install.sh)" -- --gitlab

Docker avoids a local Go toolchain. Copy the environment template, enter the required domain and passphrase, copy the channel list into the data directory, and start the compose service:

bash
cp .env.example .env && nano .env
mkdir -p data
cp configs/channels.txt data/
docker compose up -d
docker compose logs -f

The optional X account file is copied with the same pattern documented in the README:

bash
cp configs/x_accounts.txt data/

The container publishes UDP port `5300`, while the host normally receives ordinary DNS on port 53. The compose comments require packet redirection from external port 53 to 5300. After startup, print the import configuration containing the domain, key, server key and resolvers:

bash
docker compose run --rm server --print-config

These steps are an operator tutorial. They are intended for deployments where DNS is an approved communication path, not for evading network policy.

Telegram login is optional, while chat depends on stricter server configuration

The Docker quick start starts the server with `--no-telegram`, which supports the documented public-channel workflow. Access to private channels is different. The compose file documents a one-time Telegram login command that includes `TELEGRAM_API_ID`, `TELEGRAM_API_HASH` and `TELEGRAM_PHONE`. After login, the server command must be changed to enable Telegram mode. The install-script version prompts for whether Telegram login is wanted and recommends declining it for public channels.

Enabling the messenger also changes the setup. `.env.example` says `THEFEED_CHAT_DOMAINS` accepts one or more dedicated subdomains, with messenger disabled when the variable is empty or unset. Those names must differ from the feed domains. It also states that chat requires feed integrity signing and that clients enable chat only when the public key is pinned through `sk=`.

The README calls user messages end-to-end encrypted, but it does not state the key exchange, identity verification, attachment handling, retention policy or abuse controls. `MESSENGER_PROTOCOL.md` is present in the repository, yet its contents are not reproduced in the README. Those protocol details must be checked directly before treating the messenger as suitable for sensitive communication. The repository and description support encrypted DNS transport and end-to-end-encrypted messaging, but not broader claims such as metadata protection, anonymity or resistance to a malicious server.

This limitation is architectural rather than an installer omission. Chat depends on correct public DNS delegation, a distinct chat subdomain, a pinned signing key and working clients. Misconfiguration can leave feed access functional while chat remains disabled.

DNS-only access creates concrete limits for thefeed

thefeed is the wrong tool when ordinary HTTP or native application traffic is available. A normal feed client can fetch remote resources directly without encoding operations into DNS, while a conventional chat application can use a persistent connection more naturally. Adopting thefeed in that situation adds server hosting, DNS delegation and client configuration without a documented performance advantage.

DNS can also be constrained even when it is not completely blocked. Resolvers may reject unusual query names, truncate responses, apply rate limits or log unusual traffic. thefeed addresses some discovery concerns with a resolver Bank, Scanner and multiple feed domains, but the README does not claim that any discovered resolver will be usable. An environment that permits ordinary name resolution for a small set of enterprise resolvers may also restrict the destination domains needed for delegation. In that case, installing the client will not solve reachability.

Desktop distribution presents a separate adoption issue. The Windows executable is unsigned, may trigger SmartScreen or Defender quarantine, and the README instructs users to compare its SHA-256 value with the release page if needed. The macOS application is also unsigned; the documented workaround removes its quarantine attribute. Those steps increase trust and review burden. They should not be treated as proof of safety, because release documentation cannot replace artifact inspection.

The messenger is described as a lite messenger, not a full replacement for established communication systems. The README does not document group sizes, file transfer, message retention, notification guarantees, account recovery or offline delivery. An operator or reader needs those boundaries defined before depending on it for daily communication.

thefeed maintenance, upgrades and MIT license implications

The repository is not archived. Its last push was on 2026-10-13, followed by the `v0.38.2` release on the same date. Earlier listed releases include `v0.38.1` on 2026-10-12 and `v0.38.1-rc2` on 2026-08-26. This history shows recent project work, but the README does not promise a support window for older versions.

For script-managed Linux installations, upgrade cost is relatively explicit because the README says re-running the installer updates the installation. The installer also offers `--version` for a specific tag, which the README labels as rollback, along with `--pre`, `--list`, `--login`, `--config` and `--uninstall`. No automated migration policy, client-server compatibility matrix or database upgrade procedure is documented. Server operators should check release notes before replacing a working instance.

Docker has its own recurring cost. The image builds the Go server in a `golang:1.26-alpine` stage and runs it in `alpine:3.21` as the non-root `thefeed` user with UID 1000. It stores server data under `/data`, including files and cache material named by the environment comments. Updating images and preserving that data directory are separate concerns.

The repository uses the MIT license. That permits use, modification, distribution and merging under the license's stated conditions, while copied software remains subject to its own notices. This is a factual reading of the declared license, not legal advice. Operators also need to account for the terms of Telegram, X, DNS infrastructure and the operating systems under which they deploy clients.

Editorial conclusion

thefeed is appropriate for users whose networks permit only DNS and for operators willing to run a public DNS endpoint with delegated subdomains. It is a poor fit where DNS is filtered, blocked, logged aggressively or unsuitable for private messaging. Before adoption, verify the client ABI, unsigned desktop warning handling, server domain delegation and, most importantly, whether the feed domain and separate chat domain can reach every resolver the target network permits.

Frequently asked questions

Does thefeed require a server to read feeds or send messages?

No. The README says readers and chat users can import a configuration into the client without operating a server. An operator needs a server when hosting feeds for others.

What configuration does a thefeed client need?

A configuration contains the server domain, passphrase, pinned server key in the `sk=` field and bootstrap resolvers. Users can import the configuration or paste the domain and passphrase through `Settings → Configs`.

How do I enable the thefeed messenger on a server?

Configure one or more dedicated subdomains in `THEFEED_CHAT_DOMAINS` and delegate them separately from the feed subdomain. `.env.example` also says that messenger clients require a pinned `sk=` key.

Can thefeed read private Telegram channels?

The compose documentation supports Telegram login for private channels, but the public-channel quick start uses `--no-telegram` and does not require login. The Docker login flow requires the configured Telegram API credentials and phone number.

Why does thefeed need a separate DNS subdomain for messenger setup?

The feed path uses the main feed subdomain, while the messenger must use subdomains that differ from the feed domains. `.env.example` lists `THEFEED_CHAT_DOMAINS` for those dedicated names.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sartoopjj/thefeed on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sartoopjj-thefeed.svg)](https://hysenlabs.com/projects/sartoopjj-thefeed)

Was this useful?