DEV Community

mohamed salah
mohamed salah

Posted on

It works on my machine, but is it working for my users?

Every time I shipped something, the same thought hit me a few hours later:

It works on my machine. It works in staging. But is it actually working for the people using it right now?

I had analytics. I had a green dashboard. And I still had no honest answer to that question. Users would quietly leave, a button would silently break on Safari, a page would crawl on a mid-range Android, and I'd find out days later, if at all.

That gap is what I ended up building HeronSignal to close. But before I talk about the tool, let me talk about the pain, because I think you've felt at least one version of it.

The pain, depending on who you are

If you're a vibe coder / solo builder

You ship fast. Cursor, Claude, v0, a Vercel deploy, and it's live. Beautiful.

Then… nothing. You have no idea what happens after "Deploy successful." Is the checkout button throwing an error on mobile? Is your landing page slow enough that half your visitors bounce before it paints? You don't know, because setting up "real" monitoring feels like a second job: a Datadog dashboard you'll never look at, a Sentry config you half-finish.

So you just… hope. And hope is not a monitoring strategy.

If you're an engineer

Your problem isn't no data. It's too much. Ten dashboards, alert fatigue, a Sentry inbox with 400 issues where 390 are noise. Something's clearly wrong, but which thing actually matters? You spend your morning triaging instead of fixing. And when you finally pick an error, you get a stack trace with zero context: no idea what page it happened on, what the user was doing, or how to reproduce it.

Triage is not the job. Fixing is the job. But the tools make you do the triage first.

If you're a product person

You can see in your funnel that people drop off at step 3. What you can't see is why. Was it a JS error? A slow page? A confusing layout? Your analytics tool tells you what happened but never why, and the engineering dashboards that might explain it are unreadable walls of numbers.

So you guess. You open a ticket that says "checkout feels broken?" and hope someone figures it out.

What HeronSignal actually is

Short version: it watches your real visitors (not synthetic tests, not your own machine) and tells you what to fix first, and why it matters.

It captures the stuff that actually breaks experiences: JavaScript errors, unhandled promise rejections, failed network requests, slow pages, Core Web Vitals, sessions, funnels, custom business events. Then an AI reads all of it together and ranks it by user impact, not by event count.

That last part is the whole point.

Why it's different

Most tools stop at "here's the data, good luck." HeronSignal is built around three steps: see it, understand it, fix it. The first step is table stakes. It's the other two that are different.

1. It tells you what to fix first.
Instead of 400 issues sorted by timestamp, you get a ranked, plain-language answer: "Mobile visitors are erroring out on /checkout before they can pay. This is costing you the most, fix it first." It connects the error to the page, the sessions, and the business impact. A product person can read it. An engineer can act on it.

2. It can open the pull request.
This is the part people don't believe until they see it. When HeronSignal spots a real error, its coding agent can spin up a sandbox, clone your repo, make the smallest correct fix, and open a draft PR, with the reproduction context (the page, the browser, the conditions) already in the description. You review it. You merge it or you don't. It never touches your main on its own. It's not "AI writes your whole app." It's "AI does the boring triage-and-first-draft so you don't have to."

3. It plugs into your coding agent.
There's a read-only MCP endpoint, so your own agent (Cursor, Claude, whatever) can pull live monitoring context while you're fixing something: "what's actually breaking on production right now?" No copy-pasting stack traces.

How to actually use it

Here's the part that matters to the "setting it up is a second job" fear: it's one script tag. No build step, works with any stack.

<script>
  window.heronsignalConfig = {
    publicKey: "YOUR_PUBLIC_KEY"
  };
</script>
<script src="https://api.heronsignal.com/tracker.js" async></script>
Enter fullscreen mode Exit fullscreen mode

That's it. The script is ~16KB, loads async so it never blocks your page, and batches events in the background with sendBeacon, so it doesn't slow down the thing it's measuring. (You can literally watch its own footprint in your dashboard.)

Prefer npm? There's a @heronsignal/web package with an initHeronSignal() call for React/Next apps, and a Node SDK for the backend.

Once it's in, you get real-user errors, performance, and sessions automatically. The interesting part is what you add on top.

Custom events: track what matters to your product

Fire an event whenever something you care about happens. First argument is the name, second is an optional payload:

// A visitor started checkout
window.heronsignal.event("checkout_started", { plan: "pro", amount: 49 });

// They finished it
window.heronsignal.event("checkout_completed", {
  plan: "pro",
  amount: 49,
  currency: "USD",
  coupon: "LAUNCH20",
});

// A feature got used
window.heronsignal.event("export_clicked", { format: "csv", rows: 1280 });
Enter fullscreen mode Exit fullscreen mode

Name a few of these along a journey (signup_started, email_verified, first_project_created) and you've got a funnel. Now you can see the exact step people fall off at, and whether an error or a slow page is what's pushing them out. "People drop at step 3" and "there's a JS error on step 3" finally live in the same place.

If you're using the npm package instead of the script tag, it's the same call, just imported:

import { event } from "@heronsignal/web";

event("checkout_completed", { plan: "pro", amount: 49 });
Enter fullscreen mode Exit fullscreen mode

Custom logs: your own breadcrumbs

Sometimes you don't want an event, you want a log line: a note about what happened, with a level. Levels are debug, info, warn, error:

window.heronsignal.log("info", "Coupon applied", { code: "LAUNCH20", discount: 20 });

window.heronsignal.log("warn", "Payment retried", { attempt: 2, gateway: "stripe" });

window.heronsignal.log("error", "Checkout failed to load prices", {
  endpoint: "/api/prices",
  status: 500,
});
Enter fullscreen mode Exit fullscreen mode

These show up in a searchable feed. You can filter by level, or by any attribute you attached, e.g. search @endpoint:/api/prices to pull every log tied to that call. It's the context you always wish you had when a user says "it didn't work."

Catching errors you handle yourself

Runtime errors and unhandled rejections are captured automatically. But the errors you catch in a try/catch are invisible unless you report them, so report them, with the context that makes them fixable:

try {
  await pay(order);
} catch (err) {
  // Simplest form, just pass the error:
  window.heronsignal.captureError(err);

  // Or attach your own context so it's actually fixable:
  window.heronsignal.captureError({
    name: "PaymentError",
    message: err.message,
    stack: err.stack,
    metadata: { orderId: order.id, plan: order.plan, amount: order.amount },
  });

  showRetryButton();
}
Enter fullscreen mode Exit fullscreen mode

That metadata rides along to the dashboard, and if you let HeronSignal's agent open a fix PR, that same context lands in the PR description so it knows what broke and where.

Backend too (optional)

There's a Node SDK if you want server-side events and errors in the same timeline as the frontend:

import { event, log, captureError } from "@heronsignal/node";

event("subscription_renewed", { plan: "pro", mrr: 49 });
log("warn", "Webhook signature mismatch", { source: "stripe" });
captureError(err, { route: "POST /api/checkout" });
Enter fullscreen mode Exit fullscreen mode

Real examples: what this looks like day to day

Three situations I actually built this for:

1. "Signups dropped this week and I don't know why."
You've got signup_started, email_verified, first_project_created as events. HeronSignal shows the funnel, and the drop is at email_verified. You click in, and it turns out there's a spike of captureError on the verify page, only on Safari, only on mobile. Analytics would've told you signups are down. This tells you the verify button throws on mobile Safari. That's a fix, not a mystery.

2. "A customer says checkout is broken, but it works for me."
You search the log feed for their session and see: warn: Payment retried (attempt 2), then error: Checkout failed to load prices (status 500), with the endpoint and orderId you attached. You didn't need them to screen-record anything. You've got the exact call, the status, and the order id.

3. "I just shipped a new feature. Is anyone using it, and is it holding up?"
You drop one line: event("new_export_clicked", { format }). Next morning you can see how many people clicked it, which formats they pick, and whether any captureError fired around it. Real usage and real reliability, on day one, from a single line of code.

The pattern is always the same: a little bit of naming (events plus logs) turns raw traffic into answers you can actually act on.

A note on privacy, because you should ask

It's not a session-replay tool and it's not trying to hoover up your users' data. Password and payment fields aren't recorded. Sensitive URL params (tokens, emails, secrets) get redacted. IPs are hashed, not stored raw. And you can mark any element with data-heronsignal-mask or data-heronsignal-ignore to keep it out entirely.

Who it's honestly for

If you have a live website or app with real users and you've ever thought "I hope that's working out there", it's for you. Solo builders who want visibility without a PhD in observability. Engineers who are tired of triaging noise. Product people who want the why, not just the what.

If you have zero traffic and nothing shipped yet, come back when you do.

Try it without installing anything

The fastest way to see what I mean: run a free scan. No signup, no script needed. Paste your URL and you get a report on performance, SEO, AI-crawler readiness, and what real-user monitoring would catch:

👉 Scan your site free at heronsignal.com

If you install it and it catches something on day one that you didn't know about, I'd genuinely love to hear what. That's the whole reason I built it.

I'm the founder of HeronSignal. Happy to answer anything in the comments.

Top comments (0)