A complete, production-ready IPFS (InterPlanetary File System) implementation in Dart, supporting offline, gateway, and full P2P modes. Built for a seamless multi-platform experience.
TL;DR: A pure-Dart IPFS node supporting Dart VM (Windows, macOS, Linux) and Web (Chrome, Firefox, Safari). The
IpfsPlatformabstraction automatically handles storage (File System vs. IndexedDB) and networking based on the target platform.
| Platform | Runtime | Storage | Networking |
|---|---|---|---|
| Windows | Dart VM | File System | TCP / UDP / QUIC |
| macOS | Dart VM | File System | TCP / UDP / QUIC |
| Linux | Dart VM | File System | TCP / UDP / QUIC |
| Web | JS / Wasm | IndexedDB | WebSocket / WebRTC |
- Architecture Guide β Deep dive into the Manager-Handler pattern
- Wiki β Guides, Installation, Architecture
- API Reference β Auto-generated Dart docs
- What's New in v1.10
- Features
- Quick Start
- Configuration
- Use Cases
- Architecture
- Security
- Performance
- Troubleshooting
- Examples
- Contributing
- Roadmap
- License
| Feature | Description |
|---|---|
| IpfsPlatform | Unified abstraction shielding core logic from platform differences. |
| IndexedDB Storage | Production-ready persistent storage for Web browsers. |
| SecurityManager | Multi-platform encrypted keystore for secure identity management. |
| Standardization | 100% compliance with Kubo (go-ipfs) protocol standards. |
| Browser Testing | Full CI/CD integration for Chrome and Firefox. |
- Content-Addressable Storage: CID v0 and v1 support
- UnixFS: Full file system implementation with chunking
- DAG-PB: MerkleDAG operations and IPLD traversal
- CAR Files: Import/export support
- Pinning: Content persistence management
- Bitswap 1.2.0: Efficient block exchange with wantlist management
- Kademlia DHT: Distributed hash table for peer/content routing
- AutoNAT: Automatic NAT type detection
- Direct connectivity testing
- Symmetric NAT detection
- Periodic dialback verification
- UPnP/NAT-PMP: Automatic port mapping via
NatTraversalService - Circuit Relay v2: Hole-punching via relay peers
- HOP protocol (relay serving)
- STOP protocol (connection handling)
- RESERVE protocol (relay reservations)
- libp2p Core: Native TCP/Noise transport for standard P2P networking
- PubSub: Real-time messaging (Gossipsub)
- mDNS: Local peer discovery
- Bootstrap Peers: Network connectivity initialization
- HTTP Gateway: Read-only and writable modes
- RPC API: Compatible with go-ipfs API
- IPNS: Mutable naming system with Ed25519 signatures
- DNSLink: Domain-based content resolution
- GraphSync: Efficient graph synchronization protocol
- Metrics: Prometheus-compatible monitoring
- Production Cryptography
- secp256k1 key exchange (128-bit security)
- ChaCha20-Poly1305 AEAD encryption
- SHA-256 content hashing
- Ed25519 IPNS signatures
- Encrypted Keystore (SEC-008)
- AES-256-GCM encryption
- PBKDF2 key derivation
- Automatic key rotation
- Memory zeroing on lock
- Sybil Protection (SEC-005)
- S/Kademlia Proof-of-Work for PeerId verification
- Configurable difficulty via
SecurityConfig.dhtDifficulty
- Rate Limiting
- Per-client authentication throttling
- DHT provider announcement limits
- Content Verification
- Automatic CID validation
- Merkle tree verification
- Block integrity checks
IPFSWebNode: Browser-compatible implementation- IndexedDB Storage: Persistent local storage
- WebSocket Transport: Networking via secure relays
- Bitswap & PubSub: Full protocol support in browsers
Add to your pubspec.yaml:
dependencies:
dart_ipfs: ^1.10.0Or from Git for latest development:
dependencies:
dart_ipfs:
git:
url: https://github.com/jxoesneon/IPFS.gitThen run:
dart pub getImportant: On Windows, P2P networking requires libsodium for cryptography.
β
Automatic Setup: dart_ipfs automatically detects and installs libsodium via winget on first run.
Manual Installation (if auto-install fails):
# Via winget (recommended)
winget install jedisct1.libsodium
# Or use offline mode (no P2P)
IPFSConfig(offline: true)import 'package:dart_ipfs/dart_ipfs.dart';
void main() async {
final node = await IPFSNode.create(
IPFSConfig(
dataDir: './ipfs_data',
offline: true, // No P2P networking
),
);
await node.start();
// Add content
final cid = await node.add('Hello, IPFS!');
print('Added with CID: $cid');
// Retrieve content
final retrieved = await node.cat(cid);
print('Retrieved: $retrieved');
await node.stop();
}final node = await IPFSNode.create(
IPFSConfig(
dataDir: './gateway_data',
offline: true,
gateway: GatewayConfig(
enabled: true,
port: 8080,
),
),
);
await node.start();
print('Gateway running at http://localhost:8080');
// Access content at: http://localhost:8080/ipfs/<CID>final node = await IPFSNode.create(
IPFSConfig(
dataDir: './p2p_data',
offline: false, // Enable P2P networking
network: NetworkConfig(
bootstrapPeers: [
'/dnsaddr/bootstrap.libp2p.io/p2p/...',
],
enableNatTraversal: true, // UPnP/NAT-PMP
),
),
);
await node.start();
print('P2P Node ID: ${node.peerID}');
// Node participates in DHT, Bitswap, PubSubimport 'package:dart_ipfs/src/core/ipfs_node/ipfs_web_node.dart';
void main() async {
final node = IPFSWebNode(
bootstrapPeers: ['wss://relay.node.address/p2p/...'],
);
await node.start();
final cid = await node.add(Uint8List.fromList('Hello Web!'.codeUnits));
print('Added: $cid');
final data = await node.get(cid.encode());
print('Retrieved: ${String.fromCharCodes(data!)}');
}IPFSConfig(
// Storage
dataDir: './ipfs_data',
// Networking
offline: false,
network: NetworkConfig(
bootstrapPeers: [...],
listenAddresses: ['/ip4/0.0.0.0/tcp/4001'],
enableNatTraversal: true, // UPnP/NAT-PMP port mapping
),
// Gateway
gateway: GatewayConfig(
enabled: true,
port: 8080,
writable: false,
cacheSize: 1024 * 1024 * 1024, // 1GB
),
// RPC API
rpc: RPCConfig(
enabled: true,
port: 5001,
),
// DHT
dht: DHTConfig(
mode: DHTMode.server, // client, server, or auto
bucketSize: 20,
),
// Security
security: SecurityConfig(
dhtDifficulty: 16, // S/Kademlia PoW difficulty
rateLimitWindow: Duration(minutes: 1),
maxAuthAttempts: 5,
keyRotationInterval: Duration(days: 30),
),
// Logging
debug: false,
verboseLogging: false,
)final file = File('document.pdf');
final bytes = await file.readAsBytes();
final cid = await node.addBytes(bytes);
print('Document CID: $cid');
// Content is permanently addressablefinal config = IPFSConfig(
gateway: GatewayConfig(
enabled: true,
port: 8080,
cacheSize: 1024 * 1024 * 1024,
),
);// PubSub messaging
await node.pubsub.subscribe('my-topic', (message) {
print('Received: $message');
});
await node.pubsub.publish('my-topic', 'Hello, peers!');final websiteDir = Directory('./my-website');
final rootCID = await node.addDirectory(websiteDir);
// Access via: http://gateway/ipfs/<rootCID>/index.htmldart_ipfs follows a Manager-Handler pattern, coordinated by a LifecycleManager. This architecture ensures modularity, where each major responsibility (Content, Network, Protocol, Security, Storage) is handled by a specialized manager.
The IpfsPlatform abstraction layer shields the core logic from platform-specific differences, automatically switching between dart:io (for Desktop/Server) and dart:html/idb_shim (for Web) implementations.
βββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β (Your Dart/Flutter Application) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β dart_ipfs Public API β
β (IPFSNode Facade & IpfsPlatform) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Service Layer β
β (Managers: Content, Network, etc.) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Protocol Layer β
β Bitswap β DHT β GraphSync β Relay β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Transport Layer β
β P2P (Native libp2p) β
β AutoNAT β Circuit Relay v2 β
β Crypto (Ed25519 + Noise) β
ββββββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββ
β Storage Layer β
β (Providers: FileStore vs IndexedDB) β
βββββββββββββββββββββββββββββββββββββββ
For more details, see the Architecture Guide.
IMPORTANT: Production use requires strict sandboxing. See
docker-compose.ymlfor a secure reference implementation.
- Immutable Filesystem: Run with a read-only root
- Non-Root Execution: Use UID > 1000 (e.g.,
10001) - Network Isolation: Bind ports to localhost (
127.0.0.1) only - IP Diversity Limits: Max 5 peers/IP to prevent routing table poisoning
// Unlock keystore with password
await node.securityManager.unlockKeystore('your-password');
// Keys are encrypted at rest with AES-256-GCM
// Master key derived via PBKDF2
// Automatic memory zeroing on lock// Enable Sybil protection in DHT
SecurityConfig(
dhtDifficulty: 16, // Require 16-bit PoW prefix
)
// Peers with insufficient PoW are rejected from routing table| Metric | Value |
|---|---|
| Content Hashing | ~50 MB/s (SHA-256) |
| Block Storage | ~1000 ops/sec (Hive) |
| Gateway Latency | <10ms (local cache hit) |
| P2P Handshake | <100ms (secp256k1 ECDH) |
| Memory Baseline | ~50MB + content cache |
None.
Symptom: Hangs during startup
Solution: Install libsodium:
winget install jedisct1.libsodiumSymptom: Peers can't connect to you
Solution: Enable port mapping:
NetworkConfig(enableNatTraversal: true)Symptom: findProviders takes >30s
Solution: Ensure bootstrap peers are reachable and check dhtDifficulty isn't too high.
Symptom: Content not found even though added
Solution: Check if content is pinned:
await node.pin(cid);See the example/ directory for full applications:
- π± Premium Dashboard: Flutter desktop app with glassmorphism UI
- π CLI Dashboard: Matrix-style terminal interface
Other examples:
- Basic Usage
- Offline Blog
- P2P Networking
- HTTP Gateway
- Full Node
- Keystore Unlock
- libp2p Bridge Verification
Run examples:
dart run example/blog_use_case.dart
dart run example/online_test.dart# Run all tests (VM)
dart test
# Run tests in Chrome (Web)
dart test -p chrome
# Run with verbose output
dart test -r expanded
# Static analysis
dart analyzeExpected results:
- β 0 errors
- β 0 warnings
- β 2326 tests pass
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure
dart analyzeanddart testpass - Submit a pull request
- Core IPFS protocols (Bitswap, DHT, PubSub)
- Offline, Gateway, and P2P modes
- Production cryptography
- Web platform support
- WebSocket, WebRTC, and WebTransport
- WebRTC-Direct for browser-to-browser P2P
- libp2p core migration
- Circuit Relay v2
- AutoNAT
- Encrypted keystore
- S/Kademlia PoW
- 95%+ Router Coverage
- Mobile optimization (Flutter performance)
- Native QUIC transport (Desktop/Server)
- Filecoin integration
- IPFS Pinning Service API (Remote Pinning)
| Feature | dart_ipfs | go-ipfs (Kubo) |
|---|---|---|
| Content Storage | β | β |
| UnixFS | β | β |
| CID v0/v1 | β | β |
| Bitswap 1.2.0 | β | β |
| Kademlia DHT | β | β |
| HTTP Gateway | β | β |
| RPC API | β | β |
| PubSub | β | β |
| IPNS | β | β |
| GraphSync | β | β |
| Circuit Relay v2 | β | β |
| AutoNAT | β | β |
| Language | Dart | Go |
| Mobile Support | β Flutter | β |
| Web Support | β Dart Web | β |
MIT License β see LICENSE file for details
Built with:
- dart_libp2p β Native P2P networking
- pointycastle β Cryptography
- hive β Storage
- protobuf β Protocol buffers
Inspired by:
- go-ipfs (Kubo) β Reference implementation
- js-ipfs β JavaScript implementation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- IPFS Docs: docs.ipfs.tech
Ready to build decentralized applications? Get started with dart_ipfs today! π