A modern, modular toolkit for bridging Squad game servers with external services like Discord, web dashboards, and CLI tools.
Built as a clean rewrite of the original SquadJS - redesigned from the ground up for modularity, type safety, and extensibility.
See the full technical comparison: COMPARISON.md
graph TD
GS["Squad Game Server"] <-->|"RCON / TCP"| SRV["@squadjs/server<br/>(RCON + log parser + state)"]
SRV -->|"WebSocket"| DC["@squadjs/discord<br/>(bot + plugins)"]
SRV -->|"WebSocket"| CL["@squadjs/client<br/>(SDK)"]
SRV -->|"WebSocket"| CU["Any custom WS client<br/>(dashboard, CLI, etc.)"]
DC --> DA["Discord API"]
style GS fill:#4a5568,stroke:#e2e8f0,color:#e2e8f0
style SRV fill:#2b6cb0,stroke:#bee3f8,color:#bee3f8
style DC fill:#2f855a,stroke:#c6f6d5,color:#c6f6d5
style CL fill:#2f855a,stroke:#c6f6d5,color:#c6f6d5
style CU fill:#2f855a,stroke:#c6f6d5,color:#c6f6d5
style DA fill:#805ad5,stroke:#e9d8fd,color:#e9d8fd
Key design: the server and clients are separate processes. The server bridges the Squad game server over WebSocket. Any number of clients can connect - a Discord bot, a web dashboard, a CLI tool, or anything that speaks WebSocket.
| Problem in Original SquadJS | Solution in v5 |
|---|---|
Monolithic - everything in one giant SquadServer class (734 lines) |
Modular - 6 independent packages, install only what you need |
| No type safety - plain JavaScript, bugs only surface at runtime | TypeScript - full IntelliSense, compile-time error checking |
| Tightly coupled - plugins directly access the server object | Process-separated - WebSocket bridge, clean API boundaries |
| No RCON timeout - if the server stalls, the bot freezes forever | Configurable timeout - auto-flush queue + reconnect |
| One bot = one server - can't scale | Many-to-many - multiple clients per server, multiple servers per client |
| Forced telemetry - sends server data to external API, can't disable | Zero telemetry - nothing sent anywhere, ever |
| Plugin crashes kill the process | Error isolation - safe() wrapper catches plugin errors |
Yarn 1.x only - npm install explicitly breaks |
Standard npm workspaces |
| No remote access built-in | Built-in WebSocket server with auth and event subscriptions |
For a deep dive with code examples, see the full comparison.
- Modular Monorepo - each package is independently publishable to npm. Use the whole stack or just
@squadjs/rcon(zero dependencies). - Type-Safe Plugins -
definePlugin()with typed option schemas, env-var fallback, and validation. - WebSocket Bridge - real network protocol with JSON messages, token auth, event filtering.
- Async-Safe - recursive
setTimeoutprevents interval overlap; non-blocking throughout. - Auto-Reconnect - exponential backoff with coalesced reconnect (no duplicate reconnect storms).
- Plugin Auto-Discovery - publish a plugin to npm, declare
"squadjs": { "plugin": true }inpackage.json, and it's automatically loaded. - Error Isolation - one buggy plugin can't crash other plugins or the server.
- Structured Logging - Pino-based with scoped child loggers, JSON output, and pretty-printing.
- Node.js 20+
- A Squad game server with RCON access
# 1. Clone and install
git clone https://github.com/Antonio112009/squadjs-2.git
cd squadjs-2
npm install
# 2. Build all packages
npm run build
# 3. Configure (create config files with your values)
# See example/ directory and .github/CONNECTION_GUIDE.md for details
# 4. Run
cd example
npx tsx start.ts| Script | Description |
|---|---|
example/start.ts |
Combined server bridge + Discord bot |
example/server.ts |
Server bridge only (RCON to WebSocket) |
example/discord-bot.ts |
Discord bot connecting to an existing server bridge |
example/discord-bot-auto.ts |
Discord bot with plugin auto-discovery |
example/client.ts |
Standalone WebSocket client |
| Package | Description | Dependencies |
|---|---|---|
@squadjs/rcon |
Game-agnostic RCON client with TCP packet handling | 0 (Node built-ins only) |
@squadjs/logger |
Structured logger built on Pino | Pino |
@squadjs/server |
Squad server bridge - RCON commands, log parser, WebSocket server | @squadjs/rcon, ws |
@squadjs/client |
WebSocket client SDK with auto-reconnect | ws |
@squadjs/discord |
Discord.js bot framework with plugin system | discord.js, @squadjs/client |
@squadjs/plugins |
Default plugin collection (16 plugins) | @squadjs/discord |
server-status - layer-updates - killfeed - teamkill - chat-commands - ping - admin-request - admin-broadcast - auto-tk-warn - auto-kick-unassigned - seeding-mode - round-ended - round-winner - fob-hab-damage - intervalled-broadcasts - discord-rcon
import { definePlugin } from '@squadjs/discord';
export default definePlugin({
name: 'my-plugin',
description: 'Does something cool',
requiresServer: true,
optionSchema: {
channelId: { type: 'string', required: true, env: 'MY_PLUGIN_CHANNEL' },
cooldown: { type: 'number', default: 5000 },
},
setup(ctx, options) {
ctx.on('PLAYER_WOUNDED', (data) => {
ctx.log.info(`Player wounded: ${data.victim}`);
});
},
});Plugins are just functions - no class inheritance, no boilerplate. Publish to npm and they're auto-discovered.
This project is inspired by and based on the original SquadJS by Thomas Smyth. Thank you for creating the foundation that made this rewrite possible.
Rewritten and maintained by Anton