Enterprise-grade peer-to-peer networking library with advanced NAT traversal, end-to-end encryption, and publish-subscribe messaging. Built from the ground up in C++17 with comprehensive C, Node.js, Java, Python, and Android support.
Everything you need for robust P2P networking
UPnP, NAT-PMP, ICE, STUN, and TURN support with 99%+ success rate across any network topology. Automatic strategy selection for optimal connectivity.
Built-in UPnP IGD and NAT-PMP support. librats asks your router to open the listen port on startup — no manual configuration — and removes the mapping on shutdown.
Noise Protocol implementation with Curve25519 + ChaCha20-Poly1305. Automatic key management and perfect forward secrecy.
Scalable publish-subscribe messaging with mesh networking. Topic-based communication and message validation.
Chunked transfers with resume capability. Directory transfer support with parallel transmission and integrity verification.
DHT integration, mDNS local discovery, and STUN-based public IP discovery. Automatic peer reconnection.
Native C++17 implementation with zero-copy operations. Thread-safe design and minimal memory footprint.
Comprehensive language bindings for C++, C, Node.js, Java, Python, and Android. Consistent API across all platforms and languages.
Get up and running in minutes
Prefer runnable code? The examples/ directory has focused, self-contained programs — chat, pub/sub, typed messaging, file transfer, DHT discovery, and a batteries-included full_chat that finds its peers automatically over DHT + mDNS + PEX. Build them with -DRATS_BUILD_EXAMPLES=ON.
#include "node/node.h"
#include <iostream>
#include <thread>
#include <chrono>
using namespace librats;
int main() {
// A bare Node: encrypted transport (Noise_XX) + raw channel messaging.
Node node(NodeConfig{/*listen_port=*/8080});
// Callbacks run on a reactor thread; register them BEFORE start().
node.on_peer_connected([](const Peer& peer) {
std::cout << "✅ New peer connected: " << peer.id().short_hex() << std::endl;
});
node.on("chat", [](const Peer& peer, ByteView data) {
std::cout << "💬 Message from " << peer.id().short_hex() << ": "
<< std::string(reinterpret_cast<const char*>(data.data()), data.size()) << std::endl;
});
// Start the node
if (!node.start()) {
std::cerr << "Failed to start node" << std::endl;
return 1;
}
std::cout << "🐀 librats node running on port " << node.listen_port() << std::endl;
// Dial another peer (optional) — a bare Node never discovers peers on its own.
// node.connect("127.0.0.1", 8081);
// Send raw bytes to all connected peers on the "chat" channel.
std::string msg = "Hello from librats!";
node.broadcast("chat", ByteView(msg));
// Keep running
std::this_thread::sleep_for(std::chrono::minutes(1));
node.stop();
return 0;
}
#include "node/node.h"
#include "subsystems/dht_discovery.h"
#include <iostream>
#include <thread>
#include <chrono>
using namespace librats;
int main() {
NodeConfig config;
config.listen_port = 8080;
// The protocol is bound into the handshake: only peers with the exact same
// (name/version) can complete a connection.
config.protocol = "my_app/1.0";
Node node(config);
// DHT discovery announces + searches under a discovery key and dials any
// peers it finds. An empty key defaults to config.protocol, so peers of the
// same app/version discover each other automatically.
node.add_subsystem(std::make_unique<DhtDiscovery>(DhtDiscovery::Config{}));
node.on_peer_connected([](const Peer& peer) {
std::cout << "Discovered peer: " << peer.id().short_hex() << std::endl;
});
std::cout << "Protocol: " << node.protocol() << std::endl;
// start() brings up the DHT; announcing + searching runs on its own thread.
node.start();
std::this_thread::sleep_for(std::chrono::minutes(5)); // let discovery run
node.stop();
return 0;
}
#include "node/node.h"
#include "subsystems/message_json.h"
#include <iostream>
#include <string>
using namespace librats;
int main() {
Node node(NodeConfig{/*listen_port=*/8080});
node.add_subsystem(std::make_unique<MessageJson>()); // reached via node.json()
// Typed JSON handlers. The sender is the AUTHENTICATED PeerId from the
// handshake — it cannot be spoofed by a field in the payload.
node.json()->on("chat", [](const PeerId& from, const librats::Json& data) {
std::cout << "[CHAT] " << from.short_hex() << ": "
<< data.value("message", "") << std::endl;
});
node.json()->on("user_join", [](const PeerId& from, const librats::Json& data) {
std::cout << "[JOIN] " << data.value("username", "") << " joined" << std::endl;
});
// Announce ourselves whenever a peer connects.
node.on_peer_connected([&](const Peer& peer) {
std::cout << "✅ Peer connected: " << peer.id().short_hex() << std::endl;
node.json()->send("user_join",
librats::Json{{"username", "User_" + node.local_id().short_hex()}});
});
node.start();
// Broadcast a chat message to all connected peers.
node.json()->send("chat", librats::Json{{"message", "Hello, P2P chat!"}});
return 0;
}
#include "node/node.h"
#include "subsystems/pubsub.h"
#include "subsystems/dht_discovery.h"
#include <iostream>
using namespace librats;
int main() {
Node node(NodeConfig{/*listen_port=*/8080});
auto* pubsub = node.add_subsystem(std::make_unique<PubSub>());
node.add_subsystem(std::make_unique<DhtDiscovery>(DhtDiscovery::Config{})); // find peers to gossip with
// Optional: validate inbound messages before they are delivered or forwarded.
pubsub->set_validator("chat", [](const PeerId& from, const std::string& topic, ByteView data) {
// Only accept messages shorter than 1000 bytes.
return data.size() <= 1000 ? ValidationResult::Accept : ValidationResult::Reject;
});
// Subscribe: installs the delivery handler and joins the topic mesh.
pubsub->subscribe("chat", [](const PeerId& from, const std::string& topic, ByteView data) {
std::cout << "Chat from " << from.short_hex() << ": "
<< std::string(reinterpret_cast<const char*>(data.data()), data.size()) << std::endl;
});
node.start();
// Publish along the mesh — relayed to every subscriber, even several hops away.
std::string msg = "Hello, GossipSub world!";
pubsub->publish("chat", ByteView(msg));
return 0;
}
#include "node/node.h"
#include "subsystems/file_transfer.h"
#include <iostream>
using namespace librats;
int main() {
Node node(NodeConfig{/*listen_port=*/8080});
// Stage in-progress downloads in ./downloads; chunk size, window and
// integrity verification are set through FileTransfer::Config if needed.
auto* files = node.add_subsystem(std::make_unique<FileTransfer>("./downloads"));
files->on_progress([](const FileTransfer::Progress& p) {
std::cout << "\ud83d\udcc1 Transfer " << p.id
<< ": " << (int)p.percent() << "% complete"
<< " (" << (p.transfer_rate_bps / 1024) << " KB/s)" << std::endl;
});
files->on_complete([](uint64_t id, bool success, const std::string& path) {
if (success) {
std::cout << "\u2705 Transfer completed: " << path << std::endl;
} else {
std::cout << "\u274c Transfer failed: " << path << std::endl;
}
});
// Auto-accept incoming offers into ./downloads. Per-chunk CRC32 and a
// whole-file SHA-256 are verified before each file is moved into place.
files->on_offer([&](const FileTransfer::Offer& offer) {
std::cout << "\ud83d\udce5 Incoming: " << offer.name
<< " from " << offer.from.short_hex() << std::endl;
files->accept(offer.from, offer.id, "./downloads/" + offer.name);
});
node.start();
std::cout << "File transfer ready. Connect peers and exchange files!" << std::endl;
// With a peer's id (e.g. from on_peer_connected), send a file or a directory:
// files->send_file(peer_id, "my_file.txt");
// files->send_directory(peer_id, "./my_folder");
return 0;
}
Engineered for efficiency and resource optimization
Test Environment: AMD Ryzen 7 5700U, 16GB RAM
Ultra-low bandwidth consumption during peer discovery
The DHT discovery process uses minimal network bandwidth — only 350-450 bytes per second during continuous peer discovery. This ultra-low network footprint makes librats ideal for bandwidth-constrained environments, mobile devices, and applications where network efficiency is critical.
Connect across virtually any network topology
Automatic port forwarding via UPnP IGD and NAT-PMP opens your listen port on the router with zero configuration, with ICE / STUN / TURN handling the harder cases below.
| NAT Type | Direct | STUN | ICE | TURN | Success Rate |
|---|---|---|---|---|---|
| Open Internet | ✅ | ✅ | ✅ | ✅ | 100% |
| Full Cone NAT | ❌ | ✅ | ✅ | ✅ | 95% |
| Restricted Cone | ❌ | ✅ | ✅ | ✅ | 90% |
| Port Restricted | ❌ | ✅ | ✅ | ✅ | 85% |
| Symmetric NAT | ❌ | ❌ | ⚠️ | ✅ | 70% |
| Double NAT | ❌ | ❌ | ❌ | ✅ | 99% |
Real-world applications powered by high-performance P2P networking
Rats Search
A high-performance BitTorrent search program for desktop. Collects and indexes torrents from the DHT network, enabling powerful full-text search through millions of torrents with advanced filtering and P2P communication between clients.
Explore other applications and examples built with librats
Building something awesome with librats? We'd love to feature your project here and help showcase what's possible!
Have you built something cool with librats? Share it with the community!
Submit Your ProjectGet the latest version for your platform
Windows 10/11 (x64)
macOS 10.15+ (Universal)
Ubuntu 18.04+ / CentOS 7+
Compile librats yourself for maximum compatibility
git clone https://github.com/DEgITx/librats.git
cd librats
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
# Optional: build the runnable examples (off by default)
# cmake .. -DRATS_BUILD_EXAMPLES=ON && make -j$(nproc)
# ./bin/examples/full_chat 9000 lobby # auto-discovers peers
Cross-platform support with bindings for multiple programming languages
Production-ready implementations across all major platforms
| Platform | Build Environment | Compiler | Status |
|---|---|---|---|
|
Windows
|
MinGW-w64 | GCC 7+ | Fully Supported |
|
Windows
|
Visual Studio | MSVC 2017+ | Fully Supported |
|
Linux
|
Native | GCC 7+, Clang 5+ | Fully Supported |
|
macOS
|
Xcode/Native | Clang 10+ | Fully Supported |
Multi-language support for diverse development ecosystems
| Language/Platform | Binding Type | Status | Timeline | Notes |
|---|---|---|---|---|
|
C/C++
|
Native Library | Fully Supported | Available Now | Core implementation with full feature set |
|
Android (NDK)
|
Native C++ | Fully Supported | Available Now | Android NDK integration with JNI bindings |
|
Android (Java)
|
JNI Wrapper | Fully Supported | Available Now | High-level Java API for Android apps |
|
Node.js
|
Native Addon | Fully Supported | Available Now | Node.js native addon with async/await support (npm) |
|
Python
|
C Extension | Fully Supported | Available Now | CPython extension with asyncio integration |
|
Rust
|
FFI Bindings | Planned | Soon | Safe Rust bindings with tokio async support |
|
Go
|
CGO Bindings | Future | Soon | CGO wrapper for Go applications |
|
C#/.NET
|
P/Invoke | Future | Soon | .NET bindings for Windows/Linux/macOS |
Native mobile development for iOS and Android
NDK + JNI Implementation
Native C++ Implementation
Web and desktop application development
WebAssembly Implementation
Node.js Module
Rust Bindings
Everything you need to get started and build amazing P2P applications
Complete API documentation with all classes, methods, and types
Complete documentation for NAT traversal configuration and optimization
Efficient P2P file and directory transfer with resume capability
Event-driven messaging system with JSON support and callbacks
Publish-subscribe messaging with mesh networking and topic routing
End-to-end encryption details and key management
Configure custom protocols and discovery mechanisms