Getting Started

Install and configure Bot Detector in your Express application.

@riavzon/bot-detector works as an Express middleware. Getting started requires installing the package, downloading the threat intelligence data sources, configuring the module, and creating the database schema.

Requirements

Before you begin, ensure your environment meets the following requirements:

  • Node.js 18 or later
  • Express 5
  • A supported database: SQLite, MySQL, PostgreSQL, Cloudflare D1, or PlanetScale for visitor persistence
  • mmdbctl: The CLI downloads and compiles data sources into MMDB format. The init command detects and installs it automatically if it is not found.
The punishmentType.enableFireWallBan option requires a Linux environment with ufw available and passwordless sudo access for the Node.js process. All other features run on any platform that supports Node.js 18+.

Quick Setup

The fastest way to get started is with the create package. Run this command in the root of your Express project:

npx @riavzon/bot-detector-create

This command installs all required dependencies, downloads and compiles every threat intelligence feed, generates a fully annotated botDetectorConfig.ts with all 17 checkers at their defaults, creates a ready-to-run Express entry point, and initializes the database tables. It defaults to better-sqlite3 as the database driver.

If you are starting a new project, the create package is the recommended path. Skip to Next Steps after running it.

Manual Setup

If you prefer to wire things up yourself, follow the steps below.

Install the package

Install @riavzon/bot-detector along with Express, cookie-parser, and your chosen database driver.

npm install @riavzon/bot-detector express cookie-parser better-sqlite3

Replace better-sqlite3 with your preferred driver. See Database Drivers for the full list and their peer dependencies.

Initialize data sources

Run the init command to download and compile the threat intelligence databases. This step is required before the middleware can run.

npx @riavzon/bot-detector init

The command verifies that mmdbctl is installed (and installs it if not found), prompts for a BGP.tools contact string required to download BGP data, then compiles all data sources in parallel. The compiled databases are written to _data-sources/ inside the package directory.

To skip the interactive prompt in CI or automated environments, pass your contact string as a flag:

npx @riavzon/bot-detector init --contact="MyApp - [email protected]"

Configure the middleware

Create a startup file and call defineConfiguration before attaching any middleware to your app. The only required field is store.main, which sets the database driver for visitor persistence.

server.ts
import express from 'express'
import cookieParser from 'cookie-parser'
import { defineConfiguration, detectBots } from '@riavzon/bot-detector'

const app = express()
app.use(cookieParser())
app.use(express.json())

await defineConfiguration({
  store: {
    main: { driver: 'sqlite', name: './bot-detector.db' },
  },
})

app.use(detectBots())

app.get('/', (req, res) => {
  res.json({ ok: true, banned: req.botDetection?.banned })
})

app.listen(3000)

defineConfiguration is async and must resolve before you call detectBots() or any getter function. Call it exactly once during startup.

Create the database tables

Run load-schema once after configuration to create the required tables in your database:

npx @riavzon/bot-detector load-schema --db sqlite --db-name=./bot-detector.db

You can also call it programmatically with createTables(db). Pass getDb() to provide the initialized instance, call this after defineConfiguration resolves:

import { defineConfiguration, createTables, getDb } from '@riavzon/bot-detector';

await defineConfiguration({
store: {
  main: { driver: 'sqlite', name: './bot-detector.db' },
},
});

// createTables expects a Database instance, pass getDb()
await createTables(getDb());
Run load-schema before starting the server for the first time. It is safe to skip on subsequent restarts.

Schedule data source refreshes

Threat intelligence data degrades over time. Run refresh at least once every 24 hours to redownload and recompile the latest feeds:

npx @riavzon/bot-detector refresh

Add this command to a cron job or a CI/CD pipeline to keep the data current.

Database Drivers

The store.main field accepts the following drivers. Each requires the corresponding peer dependency to be installed separately.

DriverValuePeer Dependency
SQLitesqlitebetter-sqlite3
MySQL poolmysql-poolmysql2 >= 3
PostgreSQLpostgresqlpg
Cloudflare D1cloudflare-d1Worker environment binding
PlanetScaleplanetscaleServerless driver
server.ts
// SQLite
{ driver: 'sqlite', name: './bot-detector.db' }

// MySQL pool
{ driver: 'mysql-pool', host: 'localhost', user: 'root', password: 'secret', database: 'mydb' }

// PostgreSQL
{ driver: 'postgresql', connectionString: 'postgres://user:pass@localhost/mydb' }

Cache Drivers

By default, visitor state and behavioral data are stored in memory. This works for single-process deployments. For multi-process or distributed deployments, configure a shared storage driver so all instances share the same visitor cache.

server.ts
await defineConfiguration({
  store: { main: { driver: 'sqlite', name: './bot-detector.db' } },
  storage: { driver: 'redis', host: 'localhost', port: 6379 },
})
DriverValueNotes
Memory (default)(omit storage)Single-process only
LRU cachelruIn-process LRU; set max and ttl
RedisredisShared across instances
Upstash RedisupstashServerless Redis via HTTP
FilesystemfsLocal persistent storage for development
Cloudflare KV (binding)cloudflare-kv-bindingPass binding
Cloudflare KV (HTTP)cloudflare-kv-httpPass accountId, namespaceId, apiToken
Cloudflare R2cloudflare-r2-bindingPass binding
VercelvercelVercel Runtime Cache
Logo