Crazy Egg

crazyegg.comcontributed by Samuele Ongaro

ALMOST

A weekend of work, and real gaps remain.

Heatmaps, scroll maps and click reports for a page, plus simple A/B testing. You point it at a URL and it shows where people clicked and how far down they read.

Promptfree, for everyone, and the only version there is
Build me heatmaps that replace Crazy Egg — and know exactly why this is ALMOST.

The recording is easy. The hard part is that **a click at 390 pixels wide and one at 1440 are not the same click**. A heatmap that averages across breakpoints is a picture of nothing, and that single problem is why this category is harder than it looks. Solve it and the tool is genuinely useful; ignore it and you have a colourful lie.

STACK
- Node 20+ with Fastify
- SQLite through better-sqlite3, WAL mode
- A tracking script under 6KB gzipped, from my own domain
- Playwright for the page snapshots
- Caddy in front

THE DATA MODEL
- pages: id, site_id, path_pattern, name, is_active
- snapshots: id, page_id, breakpoint, image_path, dom_html_gzip, width, height, captured_at — the page as it looked, per breakpoint, so a map can be drawn over it later
- clicks: id, page_id, snapshot_id, breakpoint, x_ratio, y_ratio, element_selector, element_text, viewport_w, viewport_h, doc_h, scroll_y, is_rage, is_dead, session_hash, bot, at
- scrolls: id, page_id, breakpoint, session_hash, max_scroll_ratio, doc_h, at
- moves: bucketed, not raw — a grid cell and a count, because storing every pointer position is a great deal of data for very little insight
- experiments and variants, if you build the testing half
- Every event carries the breakpoint bucket. Nothing is ever aggregated across them

BREAKPOINTS, WHICH IS THE PROBLEM
- Define buckets — phone, tablet, small desktop, large desktop — and record which one every event belongs to
- Every map is drawn per bucket, over a snapshot taken at that width. Never one map over one screenshot
- Coordinates stored twice: as a ratio of the viewport, and as a selector plus an offset within the element. The second is what survives a layout change, and it is what makes the map still meaningful after a redesign
- An element-based map — this button was clicked 412 times — is more useful than a pixel cloud on almost every site, and it is immune to reflow. Build that first and treat the pixel map as the illustration

SCROLL DEPTH
- Normalised against the document height at the time, per breakpoint, because a page is a different length on a phone
- Report the percentage of people who reached each section, with the fold marked. That is the number people act on
- Record the document height with every event, or a page whose content changed will produce nonsense

CLICKS WORTH KNOWING ABOUT
- Rage clicks: several clicks in a small area within a second or two, which usually means something looks interactive and is not
- Dead clicks: a click on something that produced no navigation, no network request and no visible change
- Both flagged at capture time and listed separately, with the element. Those two lists are the most actionable output of the whole tool

SNAPSHOTS
- Render the page with a real browser at each breakpoint on a schedule, storing the image and the markup
- Deterministic: fonts settled, animations stopped, lazy images loaded, external requests blocked
- A page that changes often needs a fresh snapshot, or the map is drawn over the wrong layout. Detect it by comparing a hash of the structure and warn

BOTS AND HONESTY
- Flag, never drop, and exclude through a SQL view
- A minimum session count before a map is shown, with the count displayed. A heatmap of forty visits looks convincing and means nothing, and stating the sample is the difference between analysis and decoration

PRIVACY
- No input values, ever. Record that a field was clicked, never what was typed
- Mask text in the snapshot by selector for anything sensitive
- No cookie beyond a session-scoped identifier, no third-party requests

OPERATIONS
- .env: DATABASE_PATH, STORAGE_PATH, BASE_URL, HASH_SALT, SESSION_SECRET
- Migrations on boot, each once; retention with a sweeper
- Health endpoint

WHAT MATTERS MOST
Per-breakpoint maps and element-based coordinates. Build those before any colour is drawn, and put the sample size next to every map.

What you lose

  • Heatmaps that stay meaningful across breakpoints, which is the hard part — a click at 390px and one at 1440px are not the same click
  • Scroll depth normalised across page lengths
  • A snapshot of the page as it looked when the data was collected, so an old map still means something after a redesign
  • A/B testing wired into the same script

If you would rather not build

  • Microsoft Clarity, which does this for nothing

What it costs

read from their page 15 Aug 2026

PlanBilled monthlyBilled yearlyLast read
—$29/mo—15 Aug 2026

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

Self-hosted replay and heatmaps in one deployment.

openreplay/openreplayfree · open source

PostHog

$0

Product analytics with a heatmap toolbar, self-hostable.

PostHog/posthogfree · open source

Why this verdict

our own opinion · changed only by a person

55/100

Verdict kinda at 55. Collecting clicks is trivial; keeping a map honest across breakpoints and redesigns is what takes the weekend.

History

tracked since 10 Aug 2026 · nothing is ever overwritten

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

Questions about Crazy Egg

answered from the record above

Is Crazy Egg free?

No — the plan we track is $29 a month. Plus at $29/month billed monthly, around $24 annually, for 75,000 tracked page views.

Can you replace Crazy Egg by building your own?

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

How much does Crazy Egg cost?

$29 a month on Plus — $348 a year. Recorded 9 Aug 2026.

What do you lose by replacing Crazy Egg?

Heatmaps that stay meaningful across breakpoints, which is the hard part — a click at 390px and one at 1440px are not the same click; Scroll depth normalised across page lengths; A snapshot of the page as it looked when the data was collected, so an old map still means something after a redesign; A/B testing wired into the same script. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Crazy Egg?

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