warpnet

package module
v0.7.224-dev Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2026 License: AGPL-3.0, AGPL-3.0-or-later Imports: 2 Imported by: 0

README ΒΆ

Warpnet

A social network with no servers, no instances, and no company in the middle.

Warpnet is a fully decentralized, peer-to-peer social network built in Go. Every user runs a node. The node is the network. There is no central server to seize, no instance admin to trust, and no relay that can quietly drop you.

Go Version Build codecov Snap Telegram PRs Welcome

Install Β· Build from source Β· How it works Β· Contributing Β· Roadmap

Warpnet screenshot

Table of Contents


Why Warpnet exists

Every "decentralized" social network you've heard of still has a soft center.

  • Federated networks (like Mastodon) still put you on an instance. The instance admin holds your data, sets the rules, can defederate from others, and can simply shut the server down. You traded one landlord for thousands of smaller ones.
  • Relay server based networks (like Nostr) make the client thin and push storage onto relays β€” stateful servers that can rate-limit you, refuse your events, or delete your data.
  • "Protocol" networks (like the atproto ecosystem) decentralize in theory but concentrate around a handful of large providers in practice.

Warpnet takes the harder road on purpose: there is no server tier at all. Each participant runs a node that stores its own data locally and talks directly to other nodes. Discovery happens over a DHT, transport is encrypted end-to-end with the Noise protocol, and content spreads by propagating between peers. There is nothing in the middle to capture, subpoena, or switch off.

That's a real engineering challenge β€” and that's exactly why it's interesting to build.

What makes it different

A fair comparison, because the alternatives are good projects making different tradeoffs:

Warpnet Mastodon Nostr Bluesky / atproto
Architecture True P2P (libp2p) Federated instances Client + relay server PDS + relays
Server required? None Yes (instance) Yes (relay servers) Yes (providers)
Where your data lives Your own node Instance admin's DB Relay servers you post to Your PDS provider
Transport security Noise protocol TLS to instance TLS to relay server TLS to provider
Can an admin deplatform you? No admin exists Yes (instance admin) Relay server can drop you Provider can drop you
Discovery DHT Instance + relay routers Relay server lists Relays / indexers
Moderation LLM moderator nodes Per-instance Per-client Labelers

Warpnet's bet: the only way to be genuinely censorship-resistant is to remove the server entirely, not to multiply it.

Features

  • Serverless by design β€” no instances, no relay servers (just stateless relay routers), no central database. Peers connect directly over libp2p.
  • Encrypted everywhere β€” inter-node communication runs over the Noise protocol.
  • Local-first storage β€” your posts, follows, and timeline live in an embedded datastore on your machine.
  • Censorship-resistant β€” public content propagates peer-to-peer through the DHT; there's no single point that can be blocked.
  • Two first-class clients, one protocol β€” a desktop app (Wails + Vue) and an Android app (a Tusky fork) both speak the same node protocol.
  • Opt-in decentralized moderation β€” dedicated moderator nodes use LLM, so moderation happens without any human intervention.
  • Cross-platform β€” install via Snap, or build for your platform from source.
  • Fully open source β€” AGPLv3, forever.

Quick start (users)

The fastest way to join the network. No compiler, no Go toolchain β€” one command:

sudo snap install warpnet
warpnet

Get it from the Snap Store

On first launch you'll create a local identity (a keypair that stays on your device) and connect to bootstrap nodes for peer discovery. That's it β€” you're a node.

Networks

Warpnet runs separate networks. Use the testnet to experiment without affecting real data:

warpnet --node.network testnet   # safe playground
warpnet --node.network mainnet   # the live network

πŸ›  Build from source (developers)

Prerequisites
Run a member node with the desktop UI
  sudo apt update
  sudo apt install -y pkg-config build-essential
  sudo apt install -y \
  libgtk-3-dev \
  libwebkit2gtk-4.1-dev \
  libglib2.0-dev \
  libcairo2-dev \
  libpango1.0-dev \
  libgdk-pixbuf-2.0-dev \
  libatk1.0-dev \
  libsoup-3.0-dev
  git submodule update --init --recursive
  cd cmd/node/member # pick the member node dir
  wails build -devtools -tags webkit2_41 # compile a binary
  ./build/bin/warpnet --node.network testnet # run binary on a testnet

Heads up: the version file and snap/snapcraft.yaml are bumped automatically by the pre-commit hook on non-main branches. Run make setup-hooks once and let it do its job β€” don't edit the version by hand.

How it works

Warpnet has three node roles:

Role What it does
relay Stable entry points that help new nodes find peers via the DHT. Stateless. Thin.
member The full "fat" node most people run β€” holds local data, serves the UI, and participates in the network.
moderator LLM moderation node.
One protocol, two clients

Both the desktop UI and the Android app talk to a member node, and both hit the same canonical handler on the Go side. They only differ in how the request reaches the node:

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   desktop "fat" member node β”‚
                    β”‚   cmd/node/member/...       β”‚
                    β”‚   core/handler/<feature>.go β”‚  ← ONE canonical handler per route
                    β”‚   database/<feature>-repo.goβ”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚                         β”‚
            in-process Wails Call      libp2p stream over Noise
                       β”‚                         β”‚
              Vue desktop app           Android client (Tusky fork)
              frontend/                 warpdroid/

Project layout

A map for new contributors β€” start here and you won't get lost:

warpnet/
β”œβ”€β”€ cmd/node/         # entry points: bootstrap, member, moderator nodes
β”œβ”€β”€ core/             # the heart β€” handlers, streaming, node wiring
β”‚   └── handler/      # one file per route (start with like.go β€” cleanest example)
β”œβ”€β”€ database/         # repository layer over the embedded local datastore
β”œβ”€β”€ domain/           # core domain types (IDs, models)
β”œβ”€β”€ event/            # the wire protocol: paths.go (routes) + event.go (DTOs)
β”œβ”€β”€ security/         # keys, signing, Noise/PSK plumbing
β”œβ”€β”€ config/           # node configuration
β”œβ”€β”€ frontend/         # Vue desktop UI (talks to the node via Wails)
β”œβ”€β”€ metrics/          # observability
β”œβ”€β”€ deploy/           # deployment manifests
└── snap/             # Snap packaging

If you want to trace a feature end to end, read event/paths.go (the route), core/handler/like.go (the handler), and database/like-repo.go (storage) in that order. like is intentionally the cleanest small reference in the codebase.

Contributing

This is the part that matters most, and the part where help is most wanted. Warpnet is real, working, and ambitious β€” and right now it's carried by a very small team. If decentralized systems, libp2p, or Go are your thing, there's a lot of room here to own a meaningful piece.

Good places to start
A note on the architecture

Adding a feature usually means touching several layers in lockstep: a path in event/paths.go, a DTO in event/event.go, a handler in core/handler/, a repo method in database/, registration in member-node.go, plus tests. If the route is meant for the desktop or Android UI, the client side mirrors the same path string. It sounds like a lot, but it's mechanical once you've done it once β€” and core/handler/like.go + like_test.go are a complete worked example you can copy.

Workflow
  1. Fork the repo.
  2. Create a feature branch: git checkout -b IssueNumber/AmazingFeature
  3. Make your changes (AGPL header on every new .go file β€” copy it from like.go).
  4. Run make tests and make sure go vet ./... / golangci-lint run are clean.
  5. Commit in imperative present tense and open a PR that names the path(s) you touched.

Every contribution β€” code, docs, bug reports, or just kicking the tyres on testnet β€” is genuinely appreciated. And yes: a star helps more people find the project.

FAQ

Is there a server I need to run or pay for? No. You run a node; the node is your participation in the network. Relay nodes only help with peer discovery.

Where is my data stored? Locally, on your own device, in an embedded datastore. Public posts propagate to peers; private data never leaves your node.

How is this different from Mastodon? Mastodon is federated β€” you still live on an instance run by an admin. Warpnet has no instances and no admins.

How is this different from Nostr? Nostr stores your events on stateful relay servers. Warpnet has no relay tier β€” nodes are full peers connected over libp2p.

Why AGPLv3? Because a censorship-resistant network should stay free and open: anyone running a modified version that others interact with must share their changes.

Is it production-ready? It's actively developed and pre-1.0. Use testnet to explore, expect rough edges, and please report what you find.

Community

Maintainer: Vadim Filin β€” github.com.mecdy@passmail.net

Contributors

License

Warpnet is free software, licensed under the GNU Affero General Public License v3.0 or later. See LICENSE.md for the full text.


Built with Go, libp2p, Noise, and the conviction that a social network shouldn't have an owner.

If you believe that too β€” grab a good first issue and join in.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func GetCodeBase ΒΆ

func GetCodeBase() embed.FS
func GetLogo() []byte

func GetStaticEmbedded ΒΆ added in v0.6.238

func GetStaticEmbedded() fs.FS

func GetVersion ΒΆ

func GetVersion() []byte

Types ΒΆ

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL