9.5 KiB
Copilot Instructions for Uptime Kuma
Warning: Only maintainers of Uptime Kuma can use these instructions. Other contributors must read AGENTS.md and CLAUDE.md. If the git user name does not match a maintainer (see the "For Maintainers" section in AGENTS.md), ignore this file to avoid being banned for AI slop.
Copilot's Goals/Tasks
- Check spelling
- Do not show "Pull Request Overview"
- You do not have to reply if there are no issues
Keep These Instructions in Sync
- If a PR/commit changes anything documented here (commands, paths, architecture, test files, workflows), update the related content in this file in the same PR/commit, so it does not drift.
Repository Overview
Uptime Kuma is a self-hosted monitoring tool for HTTP(s), TCP, DNS, Docker, etc. Built with Vue 3 (frontend) and Node.js/Express (backend), using Socket.IO for real-time communication.
- Languages: JavaScript, TypeScript, Vue 3, HTML, CSS/SCSS
- Backend: Node.js >= 26.2.0, Express.js, Socket.IO, SQLite (also MariaDB/MySQL), Better Auth
- Frontend: Vue 3, Vite, Bootstrap 5, Chart.js
- Package Manager: npm with
legacy-peer-deps=trueandmin-release-age=7(.npmrc)
Build & Validation Commands
Prerequisites
- Node.js >= 26.2.0 (see
enginesin package.json; CI runs Node 26), a recent npm, Git
Essential Command Sequence
-
Install Dependencies:
npm ci # Use npm ci NOT npm install -
Linting (required before committing):
npm run lint # ESLint + Stylelint npm run lint:prod # For production (zero warnings) -
Build Frontend:
npm run build # Builds to dist/ -
Run Tests:
npm run test-backend # Backend unit tests (node:test, run through tsx) npm test # Backend + Playwright E2E
Development Workflow
npm run dev # Frontend on port 3000, backend on port 3001
Project Architecture
Directory Structure
/
├── server/ Backend source code
│ ├── model/ Database models (auto-mapped to tables)
│ ├── monitor-types/ Monitor type implementations
│ ├── notification-providers/ Notification integrations
│ ├── routers/ Express routers
│ ├── socket-handlers/ Socket.IO event handlers
│ ├── modules/ Shared backend modules
│ ├── util/ Backend utilities
│ ├── server.js Server entry point (executed via tsx)
│ ├── uptime-kuma-server.js Main server logic
│ └── better-auth.ts Authentication (Better Auth)
├── src/ Frontend source code (Vue 3 SPA)
│ ├── components/ Vue components
│ ├── pages/ Page components
│ ├── lang/ i18n translations
│ ├── router.js Vue Router configuration
│ └── main.js Frontend entry point
├── db/ Database related
│ ├── knex_migrations/ Knex migration files
│ └── kuma.db SQLite database
├── test/ Test files
│ ├── backend-test/ Backend unit tests (.ts and .js)
│ └── e2e/ Playwright E2E tests
├── vite.config.mjs Vite build/dev config
├── playwright.config.js Playwright test config
├── tsconfig.json TypeScript config
├── dist/ Frontend build output (gitignored)
├── data/ App data directory (gitignored)
├── public/ Static frontend assets
├── docker/ Docker build files
└── extra/ Utility scripts
Backend Architecture
server/model/— RedBean models mapped to tables.monitor.jsholds the monitor loop and handles the core types inline:http,keyword,json-query,ping,push,docker,radius,kafka-producer.server/monitor-types/— one class per monitor type, registered inserver/uptime-kuma-server.js(monitorTypeList).server/notification-providers/— one file per provider (110+), registered inserver/notification.js.server/socket-handlers/— Socket.IO event handlers (most of the real-time API surface).server/routers/— Express routers:api-router.js(push/REST API),status-page-router.js,better-auth-router.ts.server/modules/,server/util/,server/utils/knex/— shared helpers.server/better-auth.ts+src/auth-client.ts— authentication (Better Auth, v3).
Key Configuration Files
- package.json: Scripts, dependencies, Node.js version requirement
- .eslintrc.js: ESLint rules (4 spaces, double quotes, JSDoc required)
- .stylelintrc: Stylelint rules (4 spaces indentation)
- .editorconfig: Editor settings (4 spaces, LF, UTF-8)
- tsconfig.json: TypeScript config
- .npmrc:
legacy-peer-deps=true,min-release-age=7 - .gitignore: Excludes node_modules, dist, data, tmp, private
Code Style (strictly enforced by linters)
- 4 spaces indentation, double quotes, Unix line endings (LF), semicolons required
- Prettier enforces
printWidth: 120; runnpm run fmtto format (also run automatically in CI) - Comments: keep them short (one concise line explaining what/why); no multi-line essays or restating the code
- Commits: one short sentence describing the change; no long body
- Naming: JavaScript/TypeScript (camelCase), SQLite (snake_case), CSS/SCSS (kebab-case)
- JSDoc is required on every function declaration and method (
jsdoc/require-jsdoc);*.tsrelaxes some JSDoc andanyrules - Notable ESLint rules:
no-var,one-var: never,max-statements-per-line: 1,jsdoc/require-throws - Module system: no
"type": "module"in package.json —*.jsis CommonJS (require),*.mjs/*.mtsare ESM, and*.tsis executed viatsx
CI/CD Workflows
auto-test.yml (push to master/1.23.X/3.0.X and every PR):
- Builds and runs backend tests on macOS, Ubuntu, Windows, and Ubuntu arm (Node 26)
check-lintersrunsnpm run lint:prodon Node 24e2e-testrunsnpm run buildthennpm run test-e2e(Playwright)
validate.yml (pushes to master, PRs to master/1.23.X/3.0.X):
- Validates JSON/YAML files and runs
extra/check-lang-json.js,extra/check-knex-filenames.mjs,extra/check-package-json.mjs
PR Requirements: All linters pass, tests pass, code follows style guidelines
Common Issues
- npm install vs npm ci: Always use
npm cifor reproducible builds - Stylelint warnings: Deprecation warnings are expected, ignore them
- E2E tests: Run
npm run buildbeforenpm run test-e2ein a clean checkout (or usenpm run test-e2e-local) - Port conflicts: Dev server uses ports 3000 (frontend) and 3001 (backend)
- First run: Server shows "db-config.json not found" - this is expected, starts setup wizard
Translations
- Managed via Weblate. Add keys to
src/lang/en.jsononly - Don't include other languages in PRs
- Use
$t("key")in Vue templates
Database
- Primary: SQLite (also supports MariaDB/MySQL)
- Migrations in
db/knex_migrations/using Knex.js; filenames areYYYY-MM-DD-HHMM-description.js(migration behavior is covered bytest/backend-test/test-migration.js) - Filename format validated by CI:
node ./extra/check-knex-filenames.mjs - v3 uses Better Auth for authentication
Testing
- Backend: Node.js test runner via tsx (
test/backend-test/**/*.{ts,js}). Usedescribe()/test()fromnode:testand one test per scenario (seetest/backend-test/README.md). - Database monitor tests use Testcontainers;
npm run test-e2e-localsetsSKIP_TESTCONTAINER=1to skip them. - E2E: Playwright specs in
test/e2e/specs/*.spec.js;setup-process.once.jsis a one-time setup project every spec depends on. Requiresnpx playwright install. - Test data lives in
data/playwright-test; reports go toprivate/playwright-report.
Adding New Features
New Notification Provider
There are 110+ existing providers in server/notification-providers/; copy an existing one as a template.
Files to modify:
server/notification-providers/PROVIDER_NAME.js(backend logic)server/notification.js(register provider)src/components/notifications/PROVIDER_NAME.vue(frontend UI)src/components/notifications/index.js(register frontend)src/components/NotificationDialog.vue(add to list)src/lang/en.json(add translation keys)
New Monitor Type
Core types (http, keyword, json-query, ping, push, docker, radius, kafka-producer) are handled inline in server/model/monitor.js. All other types are MonitorType subclasses in server/monitor-types/ registered via UptimeKumaServer.monitorTypeList in server/uptime-kuma-server.js.
Files to modify:
server/monitor-types/MONITORING_TYPE.js(backend logic)server/uptime-kuma-server.js(register monitor type)src/pages/EditMonitor.vue(frontend UI)src/lang/en.json(add translation keys)
Important Notes
- Trust these instructions - Search only if incomplete/incorrect
- Dependencies: Run
npm run audit(npm audit --omit=dev) instead of relying on a fixed vulnerability list - Git Branches:
master(v3 development),3.0.X(v3 release),2.5.X(v2),1.23.X(v1) - Node Version: >= 26.2.0 required
- Socket.IO: Most backend logic in
server/socket-handlers/, not REST - Docker:
docker/+compose.yaml; image tags use the3suffix (base3,nightly3,pr-test3) - Never commit:
data/,dist/,tmp/,private/,node_modules/