npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@alosha/monitor

v0.4.0

Published

Playwright-based website monitoring — zero-config uptime checks, retries, screenshots on failure, and multi-channel alerts.

Readme

@alosha/monitor

Playwright-based website monitoring for developers. Define checks, run multi-step journeys, assert on content, get notified on failures, and generate HTML reports — all from your terminal or CI pipeline.

npm version npm downloads Types included License: MIT

  • Real user journeys, not just pings — click, fill, hover, and wait through multi-step flows like login or checkout.
  • Assert on what matters — page title, URL, element visibility, text content, and response time.
  • Get told the moment something breaks — alerts to Slack, Discord, email, or any webhook.
  • Evidence on every failure — automatic screenshots and a self-contained HTML report, runnable locally or in CI/GitHub Actions.

Install

npm install -D @alosha/monitor
npx playwright install chromium

Quick start

Create a monitor.config.ts (or .js) in your project root:

import type { MonitorConfig } from '@alosha/monitor'

export default {
  checks: [
    // Simple URL check
    { name: 'Homepage', url: 'https://yoursite.com', interval: '5m' },

    // Multi-step journey with assertions
    {
      name: 'Login flow',
      url: 'https://yoursite.com/login',
      interval: '10m',
      steps: [
        { action: 'fill', selector: '#email', value: '[email protected]' },
        { action: 'fill', selector: '#password', value: process.env.TEST_PASS! },
        { action: 'click', selector: 'button[type=submit]' },
        { action: 'waitForURL', value: '/dashboard' },
      ],
      assertions: [
        { type: 'title', contains: 'Dashboard' },
        { type: 'visible', selector: '.welcome-message' },
        { type: 'responseTime', maxMs: 3000 },
      ],
    },
  ],
  notify: {
    slack: { webhookUrl: process.env.SLACK_WEBHOOK_URL! },
  },
} satisfies MonitorConfig

Then run once:

npx monitor run

Or keep it running on a schedule:

npx monitor watch

Production recipes

Real problems, complete solutions — copy, paste, ship.

Fail your CI build when a critical user journey breaks

The problem: a deploy can pass unit tests but still break login or checkout in a real browser — and you find out from a customer.

import { run } from '@alosha/monitor'

const report = await run({
  checks: [{
    name: 'Login flow',
    url: 'https://app.example.com/login',
    steps: [
      { action: 'fill',  selector: '#email',    value: process.env.TEST_EMAIL! },
      { action: 'fill',  selector: '#password', value: process.env.TEST_PASS! },
      { action: 'click', selector: 'button[type=submit]' },
      { action: 'waitForURL', value: '**/dashboard' }
    ],
    assertions: [{ type: 'visible', selector: '[data-test=user-menu]' }]
  }]
})

// Break the build if any check failed.
if (report.failed > 0) process.exit(1)

Why it works: run() drives a real Chromium session through the journey and returns a structured RunReport, so a single exit-code check turns "does login still work?" into a CI gate that blocks the deploy before users ever see the break.

Get a Slack alert with a screenshot the moment a page goes down

The problem: uptime pings tell you a URL returns 200, not that the page actually rendered — and they rarely show you what the user saw.

import { watch } from '@alosha/monitor'

// Runs continuously, firing each check on its own interval.
await watch({
  checks: [
    { name: 'Homepage', url: 'https://example.com', interval: '1m', maxResponseTimeMs: 2000 },
    { name: 'Checkout', url: 'https://example.com/checkout', interval: '5m' }
  ],
  notify: { slack: { webhookUrl: process.env.SLACK_WEBHOOK_URL! } }
})

Why it works: watch() schedules each check independently and, on failure, captures a full-page screenshot before posting to Slack — so your first signal of an outage is an alert with visual proof, not a support ticket.

Alert semantics in watch mode

watch() notifies only on status transitions, not on every failing run: you get one alert when a check goes from ok to failing, and one recovery alert when it goes back to ok. A site that's down for an hour at interval: '1m' sends exactly one alert, not sixty.

For outages you want to be reminded about while they're ongoing, set reAlertInterval on the check (e.g. '30m') to re-send the down alert on that cadence until it recovers. It defaults to off — sustained failures stay silent between the initial alert and the recovery alert.

{ name: 'Checkout', url: 'https://example.com/checkout', interval: '1m', reAlertInterval: '30m' }

This state is per-process: restarting watch() forgets prior status, so the first result for each check after a restart is treated as a transition if it's a failure (you'll get a fresh down alert, not silence).

Configuration

| Option | Type | Default | Description | |---|---|---|---| | checks | CheckConfig[] | required | List of checks to run | | notify | NotifyConfig | — | Alert destinations | | screenshotsDir | string | ./monitor-screenshots | Where to save failure screenshots | | reportsDir | string | . | Where to save monitor-report.html | | concurrency | number | 4 | Max checks running at once against the shared browser |

CheckConfig

| Option | Type | Default | Description | |---|---|---|---| | name | string | required | Human-readable label | | url | string | required | Full URL to navigate to | | interval | string | "5m" | Watch mode interval. Supports "30s", "5m", "1h", "2h30m" | | reAlertInterval | string | off | Watch mode: re-send the down alert on this cadence while a check stays failing | | retries | number | 2 | Retry attempts before marking failed | | timeout | number | 10000 | Timeout per action in ms | | screenshotOnFailure | boolean | true | Save a screenshot on failure | | steps | StepAction[] | — | Multi-step journey actions | | assertions | Assertion[] | — | Assertions to verify after steps | | maxResponseTimeMs | number | — | Shorthand for { type: 'responseTime', maxMs } assertion |

Steps

steps: [
  { action: 'click',            selector: 'button' },
  { action: 'fill',             selector: '#email', value: '[email protected]' },
  { action: 'select',           selector: 'select#plan', value: 'pro' },
  { action: 'hover',            selector: '.dropdown' },
  { action: 'waitForSelector',  selector: '.modal' },
  { action: 'waitForURL',       value: '/dashboard' },
  { action: 'waitForLoadState', value: 'networkidle' },
  { action: 'screenshot',       name: 'after-login' },
]

Assertions

assertions: [
  { type: 'title',        contains: 'Dashboard' },
  { type: 'url',          contains: '/dashboard' },
  { type: 'visible',      selector: '.welcome-message' },
  { type: 'text',         selector: 'h1', contains: 'Welcome' },
  { type: 'responseTime', maxMs: 3000 },
]

Notifications

notify: {
  email:   { to, from, smtpHost, smtpPort?, smtpUser, smtpPass },
  slack:   { webhookUrl },
  discord: { webhookUrl },
  webhook: { url, headers? },
}

GitHub Actions

Drop this in .github/workflows/monitor.yml to run your checks every 15 minutes in CI:

name: Monitor

on:
  schedule:
    - cron: '*/15 * * * *'
  workflow_dispatch:

jobs:
  monitor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install
      - run: npx playwright install chromium --with-deps
      - run: npx monitor run
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: monitor-report
          path: |
            monitor-report.html
            monitor-screenshots/

Programmatic usage

import { run, watch } from '@alosha/monitor'

// One-shot run
const report = await run({ checks: [{ name: 'Homepage', url: 'https://example.com' }] })
console.log(report.passed, report.failed)

// Continuous watch
await watch({ checks: [{ name: 'Homepage', url: 'https://example.com', interval: '5m' }] })

Support & custom work

@alosha/monitor is free and MIT-licensed, and always will be. When you need more than the open-source CLI, there's a paid path backed by the maintainer — not a ticket queue:

  • Priority support — a direct line to the person who wrote it, with prioritised fixes.
  • Custom work — bespoke checks, assertions or notifier integrations, and help wiring Monitor into your CI/CD.

Get in touch at alosha.dev/support.


Docs & live demo: monitor.alosha.dev · Built by Alosha