tutorial

Monitoring Your Hyperapp Application with Vigilmon: Health Checks, Heartbeats & Uptime Alerts

Add production-grade monitoring to a Hyperapp application — a health API, background job heartbeats, and instant alerts when your functional UI or backend goes down.

Hyperapp is a micro-framework for building web applications using a functional paradigm — tiny footprint, pure state management, and effects-as-data. But a minimal footprint won't protect you from silent outages or failed background tasks. Vigilmon gives you the observability layer you need: continuous HTTP monitoring, heartbeat checks, and instant alerts via email or Slack.

What You'll Build

  • A health API endpoint alongside your Hyperapp frontend
  • Vigilmon HTTP monitors for your SPA and backend
  • A heartbeat for scheduled background tasks
  • Alert channels (email and Slack)
  • An uptime badge rendered inside your Hyperapp view

Prerequisites

  • A Hyperapp project (Vite + Hyperapp or vanilla setup)
  • Node.js/Express backend for the health endpoint
  • A free Vigilmon account

Step 1: Add a Health Endpoint

Hyperapp is purely a frontend library, so health checks belong on your backend. Add a /health route:

// server.js (Express)
import express from "express";

const app = express();

app.get("/health", async (req, res) => {
  const checks = {};
  let degraded = false;

  // Database check
  try {
    // await db.query("SELECT 1");
    checks.database = "ok";
  } catch (err) {
    checks.database = `error: ${err.message}`;
    degraded = true;
  }

  // Storage check
  try {
    // await storageClient.stat("healthcheck");
    checks.storage = "ok";
  } catch (err) {
    checks.storage = `error: ${err.message}`;
    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:

curl http://localhost:3000/health | jq .
# {"status":"ok","timestamp":"2026-07-03T...","checks":{"database":"ok","storage":"ok"}}

Step 2: Configure Vigilmon HTTP Monitors

Log in to VigilmonMonitors → New Monitor:

Monitor 1: Hyperapp SPA

| Field | Value | |---|---| | URL | https://yourapp.com/ | | Method | GET | | Expected status | 200 | | Expected body | A stable string from your HTML (e.g. <div id="app"> or page title) | | 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 independent failure surfaces: your CDN/static layer and your backend data layer.


Step 3: Heartbeat for Background Tasks

Hyperapp's functional approach works well with pure background jobs — but those jobs can silently fail without anyone noticing. A Vigilmon heartbeat alerts you when the expected ping stops arriving.

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 {
    // Monitoring must never crash the job
  }
}

cron.schedule("*/5 * * * *", async () => {
  try {
    await processQueuedEvents();
    await pingHeartbeat();
  } catch (err) {
    console.error("[scheduler] Event queue processing failed:", err);
  }
});

async function processQueuedEvents() {
  // Your actual event processing logic
}

Set up the heartbeat in Vigilmon:

  1. Monitors → New Heartbeat Monitor
  2. Set Expected interval to 10 minutes (2× the cron interval)
  3. Copy the ping URL to your .env:
VIGILMON_HEARTBEAT_URL=https://vigilmon.online/api/heartbeat/xxxxxxxx

Step 4: Display Uptime Status in Your Hyperapp View

Hyperapp uses virtual DOM nodes (h) and effects for side effects. Here's how to fetch and display the badge:

// src/StatusBadge.js
import { h } from "hyperapp";

const BADGE_URL = "https://vigilmon.online/api/badge/your-monitor-id.svg";
const STATUS_URL = "https://vigilmon.online/status/your-monitor-slug";

export const StatusBadge = (state) =>
  h("a", { href: STATUS_URL, target: "_blank", rel: "noopener noreferrer", "aria-label": "Service uptime" },
    h("img", {
      src: BADGE_URL,
      alt: "Uptime",
      width: 120,
      height: 20,
      style: {
        opacity: state.badgeLoaded ? "1" : "0",
        transition: "opacity 0.2s",
      },
      onload: (state) => ({ ...state, badgeLoaded: true }),
    })
  );

Wire it into your main app:

// src/main.js
import { app, h } from "hyperapp";
import { StatusBadge } from "./StatusBadge";

app({
  init: { badgeLoaded: false, /* ...rest of your state */ },

  view: (state) =>
    h("div", {},
      h("main", {}, /* your views */),
      h("footer", {}, StatusBadge(state))
    ),

  node: document.getElementById("app"),
});

Step 5: Set Up Alert Channels

In Vigilmon's Alert Channels settings:

Email

  1. Alert Channels → Email → add your on-call email
  2. Attach to both HTTP monitors and the heartbeat

Slack

  1. Create a Slack Incoming Webhook for #alerts
  2. Alert Channels → Webhook → paste the URL
  3. 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. Health endpoint
curl -s https://yourapp.com/health | jq .

# 2. Break the DB connection string → confirm health returns 503
# Expected: Vigilmon alerts within 2 minutes

# 3. Remove VIGILMON_HEARTBEAT_URL → let the scheduler run without pinging
# Expected: heartbeat alert fires after the grace window expires

# 4. Vigilmon → "Test Alert" → confirm delivery to Slack/email

Summary

| Monitor | What It Catches | |---|---| | HTTP SPA check | CDN failures, broken static deploys | | HTTP health API | Database, storage, and third-party API failures | | Heartbeat | Scheduler crashes, silent queue processing failures |


Next Steps

  • Create separate monitors for staging vs. production environments
  • Use Vigilmon's response time graphs to track backend latency trends
  • Configure multi-channel alerting: email for low-severity, Slack for critical incidents

Ready to get started? Sign up for Vigilmon free — have your first monitor running in under 5 minutes.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →