Hotjar

hotjar.comcontributed by Samuele Ongaro

ALMOST

A weekend of work, and real gaps remain.

Watches what visitors do on a page: records sessions, draws heatmaps of clicks and scroll depth, and asks them a question in a pop-up survey.

Promptfree, for everyone, and the only version there is
Build me session replay and heatmaps that replace Hotjar — and read the warning first.

Two things make this ALMOST. **Replay that survives real pages** — single-page applications, shadow DOM, lazy content — is genuinely difficult. And **automatic masking**, without which a recording quietly becomes a database of what people typed, including things they should never have typed into a form you are recording. That second one is not a technical risk, it is a breach waiting to happen. Mask by default or do not build this.

STACK
- Node 20+ with Fastify
- SQLite through better-sqlite3 for metadata, files or object storage for the streams
- rrweb for recording and playback. Do not write a DOM recorder — it is years of edge cases, and the edge cases are exactly what makes this ALMOST
- Playwright for page snapshots
- Caddy in front

MASKING, BEFORE ANYTHING ELSE
- Mask by default, reveal by exception. The opposite ordering guarantees something sensitive is captured on the first day
- Every input's value masked unless explicitly allow-listed. Password fields never captured under any configuration — delete the code path rather than making it a setting
- Payment fields and anything marked sensitive replaced with blocks in the browser, before the data leaves. Masking on the server is too late
- Text maskable by selector, so a page showing personal data records as layout without content
- A test page with a password, a card number and an address, recorded, with the stored stream read by hand before this goes near production. Do that every release

REPLAY THAT SURVIVES REAL PAGES
- Single-page applications: record route changes as events so the timeline has meaningful boundaries, and make sure the DOM snapshot at each is complete
- Shadow DOM and web components need explicit handling; a recorder that ignores them records a page with holes in it
- Lazy-loaded content and virtualised lists produce enormous mutation streams. Cap the events per session and stop recording rather than degrading the page
- Iframes and canvases are not captured unless deliberately enabled, and their absence is shown in the player rather than silently blank
- Fonts and stylesheets must resolve at playback time — inline what you can, and store what you cannot, or every replay renders in a fallback font and looks wrong

WHAT MAKES A REPLAY USEFUL
- Automatic detection of rage clicks, dead clicks, error events and abandoned forms, marked on the timeline. Those markers turn hours of video into a short list worth watching
- Console errors and failed requests beside the player
- Skip inactivity by default, speed control, and a keyboard for the whole thing
- Sampling: a percentage of sessions plus every session with an error, which is where the value is

HEATMAPS
- Per breakpoint, always. A click at 390 pixels and one at 1440 are not the same click, and one map over one screenshot is a picture of nothing
- Coordinates stored as a selector plus an offset as well as a ratio, so the map survives a layout change
- An element-based map — this button was clicked 412 times — is more useful than a pixel cloud and is immune to reflow. Build that first
- Scroll depth normalised against the document height at the time, per breakpoint
- A minimum session count before a map is shown, with the count displayed. Forty sessions looks convincing and means nothing

SURVEYS
- A short question triggered by page, behaviour or an event from your own code
- Frequency rules first and conservative: once per person, not in the first session, not within days of another. A product that asks constantly is a product people mute

RETENTION AND RIGHTS
- Days, not months, enforced by a sweeper that deletes metadata and blobs
- Deletion by user identifier in one command
- Every replay viewing recorded with who watched what. That log is what keeps the tool honest inside your own company
- All of it written in your privacy notice in plain words

OPERATIONS
- .env: DATABASE_PATH, BLOB_PATH, BASE_URL, HASH_SALT, SESSION_SECRET, RETENTION_DAYS, SAMPLE_RATE
- Migrations on boot, each once; measure bytes per session early and set sampling from that
- Health endpoint reporting ingest lag and free space

WHAT MATTERS MOST
Masking, then per-breakpoint maps. Read a real recorded stream by hand and look for anything you would not want to read aloud; everything else here is a video player.

What you lose

  • Session replay that survives single-page apps, shadow DOM and lazy-loaded content
  • Automatic masking of inputs, so recordings do not quietly become a database of typed passwords
  • Heatmaps aggregated across viewport sizes rather than one screenshot with dots on it
  • Storage and playback of thousands of sessions without you paying for the bandwidth
  • On-page surveys with targeting rules and a response dashboard

If you would rather not build

  • Microsoft Clarity — free, closest paid-feature parity, with its own tracking
  • FullStory — paid, replay and analytics for larger teams

What it costs

as published on their pricing page

PlanBilled monthlyBilled yearlyLast read
—$39/mo——

Their pricing page is where these came from. Seeing a different price? Tell us.

The escape hatch

open source · no votes, no paid placement

OpenReplay

$0

Session replay and DOM recording, self-hosted so the video never leaves your servers.

openreplay/openreplayfree · open source

PostHog

$0

Product analytics, session replay and flags in one self-hostable stack.

PostHog/posthogfree · open source

Why this verdict

our own opinion · changed only by a person

52/100

Verdict kinda at 52: heatmaps and a one-question survey are a genuine weekend, and the relative-coordinate trick is the only hard idea in it. Session replay is the other half of the product and is a much larger build with a much larger privacy surface — the prompt deliberately leaves it out.

History

tracked since 9 Aug 2026 · nothing is ever overwritten

Interest · last 30 dayspeak 1/day
views0130 Aug4 Sept9 Sept14 Sept19 Sept24 Sept28 Sept
— views— prompt copies none yet— votes none yet

Questions about Hotjar

answered from the record above

Is Hotjar free?

No — the plan we track is $39 a month. Observe Plus around $39/month billed annually for 100 daily sessions; recordings and heatmaps are priced separately by volume.

Can you replace Hotjar by building your own?

ALMOST. A weekend of work, and real gaps remain. Replacement score 52 out of 100, build time a weekend. Read what you lose before you decide.

How much does Hotjar cost?

$39 a month on Observe Plus — $468 a year. Recorded 9 Aug 2026.

What do you lose by replacing Hotjar?

Session replay that survives single-page apps, shadow DOM and lazy-loaded content; Automatic masking of inputs, so recordings do not quietly become a database of typed passwords; Heatmaps aggregated across viewport sizes rather than one screenshot with dots on it; Storage and playback of thousands of sessions without you paying for the bandwidth; On-page surveys with targeting rules and a response dashboard. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Hotjar?

Yes: OpenReplay, PostHog. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 36 in Analytics

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc