Skip to content
In development Not available yet. Sign-up has not opened. Tell me when it launches
Extlytics

Analytics for browser extensions

Installs are not usage.

The Chrome Web Store counts who took your extension. Extlytics shows who actually opens it, which features they reach for, and which version they are still on — with no IP address stored anywhere.

  • 1.8 KB SDK, gzipped
  • Zero dependencies
  • MV3 native
Tab Manager Overview · last 30 days
Installs 12,410 what the store reports
Opened it 4,579 37% of installs
Never opened 7,831 counted as users anyway
30 days ago today
installs opened it the gap
A sample project, and the numbers are arithmetic rather than a screenshot. We will not show you invented figures and call them a product.

Two things worth reading first

Every claim on this page has a receipt.

Not testimonials — Extlytics has no customers yet and will not invent any. These are the two published statements the product is built on top of.

Their own documentation

The Users stats only captures installations; it doesn’t monitor whether users are active or not.
Google Chrome Web Store metrics documentation

A review rejection

Creating a worker using a blob URL violates the script-src policy we intend to apply to MV3 extensions.
Chrome Web Store reviewers Rejecting an extension that shipped a general-purpose analytics SDK

Why this exists

Manifest V3 broke every analytics library you know.

MV3 forbids remotely-hosted code. That single rule breaks the mainstream analytics SDKs, because they load or generate code at runtime — and an extension carrying one is an extension that can be rejected, at review, on your timetable, under your listing.

No dynamic code. Provably.

No eval, no new Function, no blob: worker, no remote URL — and no runtime dependency that might one day introduce one. A build gate reads the emitted artifact and fails if any of them appears.

1.8 KB, and it is a budget.

The SDK ships inside your product, so its weight is a cost your users pay. The size gate is set at 3 KB gzipped and the build fails above it — which is why it is still 1.8.

It cannot break your extension.

Every failure inside the SDK is swallowed. A bug we ship is a bug you fix by passing a fresh store review — so the SDK is written to be boring: frozen wire format, no dependency, every error caught.

How it works

Three lines in your service worker.

The SDK queues events in chrome.storage.local and flushes them on chrome.alarms — so nothing is sent while your user is waiting for anything, and a flush that fails is retried rather than lost.

It asks for storage and alarms, plus a host permission for the ingest endpoint. Nothing else, and nothing a store reviewer has to form an opinion about.

background.js
// Zero dependencies, 1.8 KB gzipped, no dynamic code.
import { extlytics } from '@extlytics/sdk';

extlytics.init({
  key: 'wk_live_…',
  version: chrome.runtime.getManifest().version,

  // 'stateless' is the default: no identifier is
  // stored, so there is no cohort to join.
  mode: 'stateless',
});

// A feature somebody reached for — not a page view.
extlytics.track('session_restored');
The whole integration. Everything else — sampling, retries, the flush schedule, the country lookup — happens without you configuring it.
  1. 1

    Install and initialise

    One import and one call, with your write key. No bundler configuration, because there is nothing to configure — the package has no dependencies.

  2. 2

    Name the things you care about

    A short event name and, optionally, the version it happened on. Not a page view — there are no pages. The unit is a feature somebody reached for.

  3. 3

    Read the dashboard

    The edge drops the IP, ingest samples and writes, an hourly job aggregates, and the dashboard reads the aggregates — never the raw events.

The boundary

No IP address is stored. Anywhere.

Not hashed, not truncated, not kept for ninety days and then dropped. The edge resolves a coarse country and discards the address before ingest ever sees it — so there is no column to leak, no table to subpoena and no retention policy to trust us on.

What arrives

Everything below is in the frozen wire format, and CI compares against it.

  • The event names you chose, and when they happened
  • Your extension’s version
  • A coarse country, resolved at the edge and never the address it came from
  • The sample rate every figure was computed at

That is the whole list. Ingest has no parameter that could carry an IP address — not an ignored one, not a nullable one. The column does not exist, so the promise is a shape rather than a policy.

What never arrives

At any setting. There is no switch for these, and no plan that adds one.

  • IP addresses — discarded at the edge, stored nowhere
  • Page URLs, page content, or anything read from a tab
  • The other extensions installed alongside yours
  • Cookies, fingerprints, or any cross-site identifier

stateless is the default and stores no identifier at all. cohort — the mode that makes retention curves possible — requires an affirmed lawful basis, and the database refuses the row without one. It is a constraint, not a checkbox.

Enforced, not promised

Four things a build check refuses to let through.

Each of these is a promise that would be worth nothing as a sentence on a website. Each is a gate on every change, and each has been watched to fail — a gate nobody has seen fail is a wish.

The four CI gates and what each one stops
Gate What it stops Why it matters to you
audit:bundle Dynamic code reaching the emitted artifact The thing that gets a listing rejected at review
audit:size The bundle growing past 3 KB gzipped Weight inside your product is a cost your users pay
test:contract A wire change that breaks already-shipped SDKs Otherwise every customer owes a store review at once
test:browser A shipped SDK that cannot actually send The failure every mocked test in the world would miss

Planned pricing

Two plans, neither of them on sale yet.

These are the plans as designed. Nothing here can be bought today, and the figures may move before launch — if they do, this page moves with them.

Free

Always

$0

  • 1,000 monthly active users
  • 50,000 events a month
  • 14 days of history
  • Engagement, feature usage and version adoption

Enough to answer “does anybody open this?” for a real extension, rather than enough to see the shape of a dashboard.

Worth saying plainly: nobody has been asked what this is worth yet. Willingness to pay is untested, the validation week was skipped by decision, and the question gets answered by the first real customer rather than by a survey. That is recorded here rather than hidden.

Where it stands

Built, tested, and waiting on the unglamorous part.

Extlytics is not a landing page in front of an idea. The pipeline runs end to end, and what is left between here and a sign-up form is configuration and one store account.

Complete

Core

  • SDK, edge, ingest, rollups and retention
  • Events, features, version adoption and tracking health
  • All four CI gates green on every change
  • The SDK driven inside a real MV3 extension in real Chrome
Complete

Paid path

  • Plans, entitlements and the usage meter
  • Licence activation, billing screen and webhooks
  • Version comparison and feature-anchored retention
  • Password reset, email verification and outbound mail
In progress

Before sign-up opens

  • A real transactional mail provider wired in
  • Billing credentials and the webhook signature confirmed
  • A Chrome Web Store publisher account, and the example extension submitted
  • A data-processing agreement, reviewed by somebody who is not us

Questions

The things you would ask before shipping our code.

When can I actually use it?

There is no date, because a date we could not keep would be the first thing this page got wrong. Leave your address below and you will hear once, when sign-up opens — not a newsletter.

Will this get my extension rejected?

The SDK contains no dynamic code of any kind, which is the rule that gets analytics libraries rejected under MV3. It needs only storage and alarms, plus a host permission for the ingest endpoint — and the build refuses to emit an artifact that breaks the rule.

What happens if I go over the free limits?

The sampler starts sampling deterministically, and every figure on screen carries the rate it was computed at. Nothing is rejected, nothing is silently dropped, and no overage is billed to you.

Do my users have to consent to this?

In stateless mode — the default — no identifier is stored, so there is no cohort and no profile. cohort mode, which makes retention curves possible, requires you to affirm a lawful basis, and the database refuses the configuration without one. What you owe your own users is your call to make; the compliance disclosure the dashboard generates is a pure function of the mode you chose.

Is the SDK open?

The service is proprietary, and the SDK carries an explicit redistribution grant — without one you could not legally ship the thing you are paying for. The wire format it speaks is frozen and published, and CI compares against it on every change.

Who is behind it?

WaaFaa — the same team behind the other extensions and tools on this site. Support is one address, answered by the person who wrote the code: waafaaofficial@gmail.com.

Hear about it once, when it opens.

One email when sign-up opens, and nothing else. No newsletter, no drip sequence, and the address is not passed to anybody — which would be a strange way to start, on this of all products.

Prefer to wait quietly? This page is the status page. It changes when the product does.