Arrow.js is a lightweight reactive JavaScript library that uses native ES6 Proxy objects for fine-grained DOM reactivity — no virtual DOM, no compiler step, just plain JavaScript objects that automatically update the DOM when they change. When your Arrow.js application is in production, you need to know the moment it becomes unavailable. Vigilmon gives you continuous uptime monitoring, heartbeat checks, and instant alerts to email or Slack.
What You'll Build
- A health endpoint for your Arrow.js app's backend
- Vigilmon HTTP monitors covering your reactive app and API
- A heartbeat for scheduled background jobs
- Alert channels (email and Slack)
- An uptime badge wired into Arrow.js reactive state
Prerequisites
- An Arrow.js project (with a Node/Express API backend)
- A free Vigilmon account
Step 1: Add a Health Endpoint
Arrow.js apps are served as static bundles backed by an API server. Add a /health route to your Express backend:
// server.js
import express from "express";
const app = express();
app.get("/health", async (_req, res) => {
const checks = {};
let degraded = false;
// Database connectivity check
try {
// await db.execute("SELECT 1");
checks.database = "ok";
} catch (err) {
checks.database = `error: ${err.message}`;
degraded = true;
}
// External dependency check
try {
const response = await fetch("https://api.example.com/ping", {
signal: AbortSignal.timeout(3000),
});
checks.externalApi = response.ok ? "ok" : `http_${response.status}`;
} catch {
checks.externalApi = "unreachable";
degraded = true;
}
res.status(degraded ? 503 : 200).json({
status: degraded ? "degraded" : "ok",
timestamp: new Date().toISOString(),
checks,
});
});
app.listen(process.env.PORT ?? 3000);
Test it locally:
curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-07-03T...","checks":{"database":"ok","externalApi":"ok"}}
Step 2: Configure Vigilmon HTTP Monitors
Log in to Vigilmon → Monitors → New Monitor.
Monitor 1: Arrow.js App
| Field | Value |
|---|---|
| URL | https://yourapp.com/ |
| Method | GET |
| Expected status | 200 |
| Expected body | A stable string from your rendered HTML |
| Check interval | 1 minute |
Monitor 2: Health API
| Field | Value |
|---|---|
| URL | https://yourapp.com/health |
| Method | GET |
| Expected status | 200 |
| Check interval | 1 minute |
Two monitors cover two distinct failure classes: static file serving and backend data layer failures.
Step 3: Heartbeat for Background Jobs
Arrow.js apps often pair with server-side scheduled work — data ingestion, cache refresh, notification queues. Use a Vigilmon heartbeat to detect silent failures.
npm install node-cron
// scheduler.js
import cron from "node-cron";
const VIGILMON_HEARTBEAT_URL = process.env.VIGILMON_HEARTBEAT_URL ?? "";
async function pingHeartbeat() {
if (!VIGILMON_HEARTBEAT_URL) return;
try {
await fetch(VIGILMON_HEARTBEAT_URL, { signal: AbortSignal.timeout(5000) });
} catch {
// Never let monitoring crash the job
}
}
cron.schedule("*/10 * * * *", async () => {
try {
await runDataIngestion();
await pingHeartbeat();
} catch (err) {
console.error("[scheduler] Data ingestion failed:", err);
// Vigilmon fires after the heartbeat window expires with no ping
}
});
async function runDataIngestion() {
// Your scheduled task logic here
}
Create the heartbeat in Vigilmon:
- Monitors → New Heartbeat Monitor
- Set Expected interval to 20 minutes (2× the cron interval)
- Copy the ping URL into your environment:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx
Step 4: Display an Uptime Badge with Arrow.js Reactive State
Arrow.js uses native Proxy objects for reactivity. You can wire the badge into your app's reactive state to reflect live status:
// src/status.js
import { reactive, effect } from "@arrow-js/core";
const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";
// Reactive state for monitoring status
const monitorState = reactive({
loaded: false,
badgeUrl: BADGE_URL,
statusUrl: STATUS_URL,
});
// Render badge into the footer using Arrow.js template tag
import { html } from "@arrow-js/core";
const badgeTemplate = html`
<a
href="${() => monitorState.statusUrl}"
target="_blank"
rel="noopener noreferrer"
aria-label="Service uptime status"
>
<img
src="${() => monitorState.badgeUrl}"
alt="Uptime"
width="120"
height="20"
/>
</a>
`;
// Mount into footer
const footer = document.querySelector("footer");
if (footer) {
badgeTemplate(footer);
monitorState.loaded = true;
}
Arrow.js's Proxy-based reactivity means any change to monitorState.badgeUrl or monitorState.statusUrl will automatically re-render the relevant DOM nodes — no manual DOM manipulation required.
Step 5: Configure Alert Channels
In Vigilmon's Alert Channels settings:
- Alert Channels → Email → add your on-call address
- Attach to both HTTP monitors and the heartbeat
Slack
- Create a Slack Incoming Webhook for
#alerts - Alert Channels → Webhook → paste the webhook URL
- Payload template:
{
"text": "🚨 *{{ monitor.name }}* is DOWN\n{{ monitor.url }}\nStatus: {{ event.status }}\n<https://vigilmon.online|Open Vigilmon>"
}
Step 6: Verify Everything Works
# 1. Confirm the health endpoint
curl -s https://yourapp.com/health | jq .
# 2. Simulate a DB failure → confirm health returns 503
# Expected: Vigilmon alert within ~2 minutes
# 3. Remove VIGILMON_HEARTBEAT_URL and let the scheduler run
# Expected: heartbeat alert after the grace window
# 4. Vigilmon → "Test Alert" → confirm delivery to Slack/email
Summary
| Monitor | What It Catches | |---|---| | HTTP app check | CDN failures, broken static deploys | | HTTP health API | Database, external API, and service failures | | Heartbeat | Silent scheduler failures, broken background jobs |
Next Steps
- Create separate monitors for staging and production environments
- Use Vigilmon's response time graphs to catch latency regressions across releases
- Route critical alerts to Slack, low-severity alerts to email
Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.