@vex-chat/spire
v1.0.1
Published
Vex server implementation in NodeJS.
Readme
@vex-chat/spire
Reference server implementation for the Vex protocol.
What's in the box
- REST API (Express 5) for full e2e messaging including auth, registration, users, servers, channels, invites, and file upload.
Install
Or clone the repo:
git clone [email protected]:vex-protocol/spire-js
cd spire-js
npm ciRunning the server (Docker)
From a clone, with Docker and Docker Compose installed:
cp .env.example .env
# set SPK, JWT_SECRET, DB_TYPE, … (see Configuration)
docker compose up --buildCompose builds the image from this repo’s Dockerfile, starts Spire with a persistent spire-data volume mounted at /data (SQLite + files/, avatars/, emoji/), and fronts it with nginx on port 8080. Use http://localhost:8080 for HTTP and WebSocket.
Running without Docker
For local development or if you installed from npm, Spire runs with node --experimental-strip-types (no separate compile step):
npm start
# or: node --experimental-strip-types src/run.tsFrom an npm install, sources live under node_modules/@vex-chat/spire/src/:
node --experimental-strip-types node_modules/@vex-chat/spire/src/run.tsConfiguration
Spire reads configuration from environment variables. Docker Compose: put them in a .env file next to docker-compose.yml (the env_file entry injects them into the container). Bare Node: dotenv loads .env from the process working directory when you run src/run.ts.
Required
| Variable | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SPK | Server private key, hex-encoded. Generate with npm run gen-spk (prints SPK and JWT_SECRET lines). Used for server identity signing (NaCl). |
| JWT_SECRET | Hex or string used as the HMAC secret for JWTs — required and must be separate from SPK. npm run gen-spk emits a dedicated value; do not reuse SPK here. |
| DB_TYPE | sqlite, sqlite3, or sqlite3mem. All values use SQLite via better-sqlite3 (file or :memory:). sqlite3mem is for tests. The string mysql is still accepted for compatibility but maps to the same SQLite setup as the default (there is no MySQL driver). |
Optional
| Variable | Default | Description |
| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API_PORT | 16777 | Port for the REST API and WebSocket server (see Spire default in code if unset). |
| NODE_ENV | (unset) | Set to production to disable interactive /docs / /async-docs. If unset or any other value, doc viewers are mounted. helmet() runs in all modes. |
| CORS_ORIGINS | (empty) | Comma-separated allowed Origin values for cors. If unset or empty, no cross-origin browser access (origin: false). |
| CANARY | (unset) | |
Sample .env
# Run `npm run gen-spk` and paste the two lines it prints (SPK + JWT_SECRET).
SPK=a1b2c3...
JWT_SECRET=d4e5f6...
DB_TYPE=sqlite
# CANARY=true
API_PORT=16777
NODE_ENV=productionDevelopment
npm run build # tsc (sanity check — runtime uses --experimental-strip-types)
npm run lint # eslint strictTypeChecked
npm run lint:fix # eslint --fix
npm run format # prettier --write
npm run format:check
npm test # vitest run
npx type-coverage # type-coverage (≥95%)
npm run license:check # license allowlist gateSee AGENTS.md for the release flow (changesets → publish → deploy-hook) and the rules for writing changesets.
