Your website, under siege-proof armor.
Free flood, DDoS and scanner protection for Node.js websites — with live traffic numbers and instant Discord alerts when an attack starts, while it lasts, and when it ends.
Seven layers. Zero dependencies.
Every visitor gets a fair limit — stricter for your API and much stricter for login and checkout pages.
Caps how many requests one IP can keep open at once, so slow-loris attacks cannot drown your server.
Bots hunting for /.env, /wp-admin or /.git get a 404 — and a ban after a few tries.
Repeat offenders are banned for 10 minutes, doubling every time, up to 24 hours.
When your server is struggling, the heaviest visitors are slowed first so real people still get in.
A threat score is calculated every second. A real attack triggers alerts: started, still active, over.
Behind Cloudflare it still sees the real visitor IP — and cannot be fooled by a fake header.
Alerts only show partly hidden IPs (203.0.113.x). Nothing is sent anywhere except your own webhook.
Three steps.
Put siege-shield.js next to your server file. No npm install needed (Node 18+).
In Discord: channel settings → Integrations → Webhooks → New Webhook → Copy URL. Save it as SHIELD_WEBHOOK in your hosting variables.
Load it first, before your routes. Done — attacks now show up in your Discord.
Express
const shield = require('./siege-shield')({
webhookUrl: process.env.SHIELD_WEBHOOK, // Discord webhook for alerts
proxyHops: 1, // 1 on Railway / Render / Heroku, 0 on a plain VPS
});
app.use(shield.middleware); // first, before your routes
// optional: live numbers for your own dashboard
app.get('/admin/shield', (req, res) => res.json(shield.stats()));Plain Node http
const http = require('http');
const shield = require('./siege-shield')({ webhookUrl: process.env.SHIELD_WEBHOOK });
http.createServer((req, res) => {
if (shield.handle(req, res)) return; // blocked and already answered
res.end('Hello!');
}).listen(3000);Tune it (all optional)
require('./siege-shield')({
limits: {
all: { max: 150, per: 10 }, // any request, per IP
api: { max: 60, per: 10, prefixes: ['/api/'] },
critical: { max: 12, per: 60, prefixes: ['/login', '/checkout'] },
},
concurrency: 16, // open requests per IP
banMinutes: 10, // first ban, doubles for repeat offenders
allow: ['1.2.3.4'], // never limited (your office, uptime robots…)
skip: (req) => req.url === '/health',
onAlert: (embed, kind, stats) => { /* send it anywhere you like */ },
});
// shield.test() sends a sample alert so you can see it in DiscordNot on Node.js? Watch it from Discord.
Site Watch checks any website every few minutes: online or down, response time, SSL expiry, and even whether a word is still on the page. Alerts and a live status board go straight to your server.