Uptime monitoring for your websites, Discord bots, and servers β from Discord and the web. Built with π by Crystal Studio Labs β github.com/Crystal-Studio-Labs
Crystal Uptime keeps your online services online. It pings your websites, Discord bots, Minecraft servers, and raw IP addresses every 30 seconds, records their uptime history, posts live status embeds to your Discord server, and alerts you β with role pings β the moment something goes down. Manage everything from Discord or from the web dashboard, and share live status pages with your community.
- Monitor anything β websites (HTTP), Minecraft servers, or raw IPs (ICMP ping).
- Live status embeds in Discord with uptime %, latency, and a recent-history graph.
- Instant up/down alerts with optional role pings to a dedicated error channel.
- Web dashboard β add, remove, and view your monitors from any browser.
- Public status pages β share a live status page for your services.
- Premium & Enterprise tiers with redeemable codes and higher monitor limits.
- Multi-database β Postgres (Supabase, Neon, Railway), SQLite, MySQL, or MongoDB (native driver or Mongoose) via a single env switch.
- Runs on any free host β no native modules in the default path, no local storage,
PORT-aware web server.
ββ Discord bot ββββββββββββββ ββ Website (same Express server) ββ
β /register /remove β β Landing Β· Discord OAuth2 login β
β /details /my-monitors β β Dashboard Β· Public status pages β
β ββ 30s monitor loop βββββββΌβββΊβ Premium Β· Stats β
βββββββββββββββ¬ββββββββββββββ ββββββββββββββββ¬βββββββββββββββββββ
ββββββββββββΊ src/database ββββββββ
(multi-DB: Postgres/SQLite/MySQL/MongoDB)
Monitors are owned by a Discord user ID. Monitors added on the website show up in Discord β and vice versa β because both surfaces read the same data.
A React + Vite single-page app served by the same Express server (no separate deploy β the bot hosts it):
| Route | Page |
|---|---|
/ |
Landing β hero, features, live bot stats |
/login |
Discord OAuth2 sign-in (redirects to /api/auth/login) |
/dashboard |
Manage monitors (add/remove, live status, 30-day uptime), public-page toggle |
/status/:username |
Public status page (opt-in per user) |
/premium |
Plan tiers + redeem-code form |
/stats |
Leaderboard + system counts |
Source lives in web/ and talks to the same API the Discord commands use:
GET/POST/DELETE /api/monitorsβ list, register, remove (auth)GET/POST /api/settingsβ profile + public-page toggle (auth)GET /api/premium/plansΒ·POST /api/premium/redeem(auth)GET /api/status/:usernameβ public status pageGET /api/statsβ leaderboard + system counts
Protected routes require the Discord login session; everything is same-origin
behind the /api rate limiter and CSP headers.
- Node.js β₯ 18
- A Discord application (bot token + client ID) from the Discord Developer Portal
- A database: Postgres (Supabase, Neon, Railway), MySQL, or SQLite for local dev
npm installcp .env.example .env # then fill in your valuesRequired: TOKEN, CLIENT_ID, and a database (DB_TYPE + DATABASE_URL).
See .env.example for the full list β including CLIENT_SECRET (website login),
log channels, and brand links.
npm run migrate # creates the schema (also runs automatically at boot)npm run build:web # builds the React + Vite app into web/distThe Express server serves web/dist when it exists (SPA fallback for
/dashboard, /status/:username, β¦). For frontend work, npm run dev:web
runs Vite with hot reload and proxies /api to the bot.
npm start # boots the Discord bot + web serverThe web server binds process.env.PORT (default 8089) and serves the web
dashboard and the bot stats API.
npm test # data-layer smoke test (in-memory SQLite)
npm run test:mongo # MongoDB backends smoke test (mongodb + mongoose)
npm run security # secret scan + dependency vulnerability audit
npm run build:web # production build of the React web app
curl localhost:8089/health # web liveness probe (200 when DB connected)| Category | Commands |
|---|---|
| Monitor | register, remove, details, group, checkurl, my-monitors, ssl-reminder, malware-check |
| Info | about, help, stats, invite, ping, profile, socials, discord, alert |
| Premium | buy, redeem, gencode, perks |
| Owner/Staff | announcement, blacklist, control-panel, shutdown |
| Other | vote, feedback, suggestion, settings |
| Backend | Type | Notes |
|---|---|---|
| Supabase β | postgres |
Default / recommended β hosted Postgres, generous free tier |
| Neon | postgres |
Serverless Postgres, always-on free tier |
| Railway Postgres | postgres |
Hosted Postgres add-on |
| SQLite | sqlite |
Local dev only (no server needed) |
| MySQL / MariaDB | mysql |
Any MySQL-compatible host |
| MongoDB Atlas | mongodb |
Native mongodb driver β M0 free tier (512 MB) works |
| MongoDB Atlas | mongoose |
Mongoose ORM on the same Atlas cluster |
MongoDB (Phase 2.5): two selectable backends share the exact same repo API (
DB_TYPE=mongodbnative driver,DB_TYPE=mongooseMongoose). Both are schemaless βnpm run migrateis a no-op and unique/query indexes are ensured at boot. Validate either withnpm run test:mongo(in-memory MongoDB, or setSMOKE_MONGO_URLto point at a real Atlas cluster).
We use Supabase (Postgres) as the primary database. It's free, hosted, works from any host, and the data layer is written so you can switch or add backends without code changes.
Connect up to 5 databases of the same type at once β for example 5 different
Supabase projects. All connections share the same type (DB_TYPE); mixing types
is not supported.
# Primary connection
DB_TYPE=postgres
DATABASE_URL=postgres://user:pass@supabase-a/db
# Additional connections (DB_2 β¦ DB_5) β same type, up to 5 total
DB_2_URL=postgres://user:pass@supabase-b/db
DB_3_URL=postgres://user:pass@supabase-c/dbThe data layer (src/database/) is a repository layer over Knex for SQL
backends (postgres | sqlite | mysql β shared schema and migrations), and a
parallel repository layer for MongoDB (mongodb native driver and
mongoose ORM β index management instead of DDL). All backends expose the same
repo API and output shape, so switching DB_TYPE needs no code changes.
Migrations run automatically at boot and via npm run migrate (no-op on
Mongo); npm test validates the SQL layer and npm run test:mongo validates
both Mongo backends.
- Runs on any free PaaS/VPS that can run a Node.js process and reach the internet.
- Recommended for true 24/7: Oracle Cloud Always Free (ARM) or Railway.
- Free tiers of Render/Koyeb/Replit/Glitch sleep on inactivity β the bot's Discord gateway disconnects while asleep; keep that in mind.
- The default path uses pure-JS database drivers and writes no local files, so ephemeral filesystems are fine.
- Port & shutdown: the web server binds
PORT(default 8089); the process handles SIGINT/SIGTERM gracefully (closes the web server, database connections, and the Discord gateway).
- No secrets in the repository β every credential is read from the environment.
- Secure web login β Discord OAuth2 with a CSRF
stateparam, server-side token exchange, andhttpOnlycookies; only SHA-256 session-token hashes are stored. - Multi-DB connections use least-privilege roles and TLS where available.
- A built-in
npm run securityscanner checks for leaked secrets and dependency vulnerabilities before every release.
Need help, have a feature request, or want to report an issue?
- π§ Email: connect.crystalstudio@gmail.com
- π GitHub: open an issue
- π Documentation: developers.txt Β· llms.txt Β· CONTRIBUTING.md
MIT Β© 2026 Crystal Studio Labs