Documentation Index
Fetch the complete documentation index at: https://mintlify.com/amark/gun/llms.txt
Use this file to discover all available pages before exploring further.
Node.js Integration
GUN runs natively in Node.js and can be used as both a relay peer server and for server-side data operations.
Installation
Create a basic server
Set up a simple HTTP or Express server with GUN.
Configure persistence
Optionally configure file-based persistence or other storage adapters.
Basic HTTP Server
Here’s a minimal GUN relay peer using Node’s built-in HTTP module:
const Gun = require('gun');
const http = require('http');
const port = process.env.PORT || 8765;
const server = http.createServer(Gun.serve(__dirname));
const gun = Gun({
web: server.listen(port),
file: 'data' // Enable file storage
});
console.log('Relay peer started on port ' + port + ' with /gun');
module.exports = gun;
Express Integration
Integrate GUN with an Express.js application:
const express = require('express');
const Gun = require('gun');
const port = process.env.PORT || 8765;
const app = express();
// Serve GUN's client-side code
app.use(Gun.serve);
// Serve static files from your public directory
app.use(express.static(__dirname + '/public'));
// Create HTTP server
const server = app.listen(port);
// Initialize GUN
const gun = Gun({
file: 'data',
web: server
});
// Make gun accessible for debugging (optional)
global.Gun = Gun;
global.gun = gun;
console.log('Server started on port ' + port + ' with /gun');
module.exports = gun;
Production-Ready Server
A more robust setup with clustering and HTTPS support:
const cluster = require('cluster');
const fs = require('fs');
const Gun = require('gun');
if (cluster.isMaster) {
return cluster.fork() && cluster.on('exit', function() {
cluster.fork();
});
}
const env = process.env;
const opt = {
port: env.PORT || 8765,
peers: env.PEERS && env.PEERS.split(',') || []
};
// Check for SSL certificates
if (fs.existsSync((opt.home = require('os').homedir()) + '/cert.pem')) {
env.HTTPS_KEY = env.HTTPS_KEY || opt.home + '/key.pem';
env.HTTPS_CERT = env.HTTPS_CERT || opt.home + '/cert.pem';
}
if (env.HTTPS_KEY) {
opt.port = 443;
opt.key = fs.readFileSync(env.HTTPS_KEY);
opt.cert = fs.readFileSync(env.HTTPS_CERT);
opt.server = require('https').createServer(opt, Gun.serve(__dirname));
// Redirect HTTP to HTTPS
require('http').createServer(function(req, res) {
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url });
res.end();
}).listen(80);
} else {
opt.server = require('http').createServer(Gun.serve(__dirname));
}
const gun = Gun({
web: opt.server.listen(opt.port),
peers: opt.peers,
file: 'data'
});
console.log('Relay peer started on port ' + opt.port + ' with /gun');
module.exports = gun;
Hapi.js Integration
For Hapi.js applications:
const Hapi = require('@hapi/hapi');
const Gun = require('gun');
const path = require('path');
const init = async () => {
const server = Hapi.server({
port: process.env.PORT || 8765,
host: 'localhost'
});
// Register inert for static file serving
await server.register(require('@hapi/inert'));
// Serve static files
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: path.join(__dirname, 'public')
}
}
});
await server.start();
// Initialize GUN
const gun = Gun({
web: server.listener,
file: 'data'
});
console.log('Server running on %s', server.info.uri);
return { server, gun };
};
init();
Server-Side Data Operations
Use GUN on the server for data operations:
const Gun = require('gun');
const gun = Gun();
// Write data
gun.get('users').get('alice').put({
name: 'Alice',
email: 'alice@example.com',
joined: Gun.state()
});
// Read data
gun.get('users').get('alice').once((data, key) => {
console.log('User data:', data);
});
// Subscribe to updates
gun.get('messages').map().on((message, id) => {
console.log('New message:', message);
// Process message server-side
});
Environment Configuration
Use environment variables for configuration:
# .env file
PORT=8765
PEERS=https://peer1.example.com/gun,https://peer2.example.com/gun
HTTPS_KEY=/path/to/key.pem
HTTPS_CERT=/path/to/cert.pem
require('dotenv').config();
const gun = Gun({
web: server,
peers: process.env.PEERS ? process.env.PEERS.split(',') : [],
file: process.env.DATA_DIR || 'data'
});
Storage Adapters
File Storage (Default)
const gun = Gun({
file: 'data', // Stores data in ./data directory
web: server
});
Custom Storage Adapter
Gun.on('create', function(db) {
this.to.next(db);
db.on('get', function(request) {
// Custom read logic
this.to.next(request);
});
db.on('put', function(request) {
// Custom write logic
this.to.next(request);
});
});
Connecting to Other Peers
Connect your relay peer to other GUN peers:
const gun = Gun({
web: server,
peers: [
'https://gun-relay-1.example.com/gun',
'https://gun-relay-2.example.com/gun',
'wss://gun-relay-3.example.com/gun'
]
});
Process Management
Use PM2 for production process management:
npm install -g pm2
pm2 start server.js --name "gun-relay"
pm2 save
pm2 startup
ecosystem.config.js:
module.exports = {
apps: [{
name: 'gun-relay',
script: './server.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 8765
}
}]
};
Docker Deployment
Dockerfile:
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 8765
CMD ["node", "server.js"]
docker-compose.yml:
version: '3.8'
services:
gun-relay:
build: .
ports:
- "8765:8765"
volumes:
- gun-data:/app/data
environment:
- PORT=8765
restart: unless-stopped
volumes:
gun-data:
Best Practices
- Use clustering: Implement clustering for better reliability
- Enable persistence: Use file storage or custom adapters for data persistence
- Configure peers: Connect to multiple relay peers for redundancy
- Monitor resources: Track memory and CPU usage in production
- Implement logging: Add proper logging for debugging and monitoring
- Use HTTPS: Enable SSL/TLS for production deployments
- Set up backups: Regularly backup your data directory
Monitoring & Debugging
// Enable debugging
Gun.log.once = (msg) => console.log(msg);
// Monitor connections
gun.on('hi', (peer) => {
console.log('Peer connected:', peer.id);
});
gun.on('bye', (peer) => {
console.log('Peer disconnected:', peer.id);
});
// Track data changes
gun.get('stats').on((data, key) => {
console.log('Stats updated:', data);
});
Next Steps