Documentation, a product tour, and a short video: vizoalica.dev.
Vizoalica is an open-source (MIT) web and product analytics platform that you host yourself on Cloudflare Workers, D1, and R2. One script tag on your site sends privacy-filtered page views, clicks, and custom events to your own backend. A local console shows traffic over time, top pages, referrers, browsers, devices, unique visitors, and countries, and a local MCP server lets your AI assistant answer questions from the same data. Visitor data stays in your own Cloudflare account.
At a glance
- Ask your AI assistant: a local, read-only MCP server and skill for Claude Code, Claude Desktop, Codex, and Cursor ("How did my websites do last week?"). See Use Vizoalica with AI.
- Install on a website: one script tag, on any host. Nothing is stored in visitors' browsers: no cookies, no local storage. (Only if you opt your own browser out of being counted, with
?vizoalica_ignore=1, does it store one value on your own device.) - Runs on: Cloudflare Workers (event ingestion and admin API), D1 (aggregates), and R2 (raw event batches), all in your account.
- Collects: page views (each screen of a single-page site, with identifiers such as
/orders/8841grouped as/orders/:id), clicks on buttons and links as actions (and a count of rage clicks, bursts of rapid clicks on one control), custom events, and the UTM source, medium and campaign of the landing address, with URLs, referrers, and properties minimised before delivery. It never collects form values, typed text, page text, click positions, or session replay, and it records the consent state on every event. - Standards: CloudEvents batches, JSON Schema validation, and optional short-lived signed (JWT/JOSE) ingest tokens.
- Setup:
npm install -g vizoalica,vizoalica env add prod(deploys the backend to your Cloudflare account, explaining each question), thenvizoalica console. You need Node.js 22 or newer and a Cloudflare account. macOS and Linux are supported; Windows is not yet. - License: MIT.
Deployment in four steps
Set these up in order, because each step needs something the previous one produces. The three parts you end up with:
The backend has three secrets, and none of them is ever in browser code. vizoalica env add saves the first for
you and shows none of them:
Step 1: Install the vizoalica cli
You need Node.js 22 or newer on macOS or Linux, and a Cloudflare account. No source checkout is required.
npm install -g vizoalica
vizoalica help
Update with npm update -g vizoalica; remove with npm uninstall -g vizoalica. Your settings stay in
~/.config/vizoalica/.
Something not working? Add --verbose to any command (for example vizoalica deploy prod --apply --verbose).
It prints, with timings, what the command is doing: the files and settings it uses, each question it asks, each
request it makes, and each Wrangler step with its output. It never prints a secret, a credential, or your
answers, so the output is safe to paste into an issue.
Step 2: Create your backend
One command creates your backend in your Cloudflare account and saves it on this computer:
vizoalica env add prod
Have a Cloudflare API token ready with Workers Scripts: Edit, D1: Edit, Workers R2 Storage: Edit, and Account
Settings: Read (My Profile → API Tokens → Create Token → Custom token), and R2 enabled on the account. It asks
one question at a time and explains each. Say yes to deploying. It creates a D1 database, an R2 bucket, and
a Worker named prod-vizoalica-…, then checks that they work. It never changes or deletes anything that already
exists, and Ctrl-C stops without changing anything. Add --verbose to see each step.
There is no secret to copy. The admin key is saved in ~/.config/vizoalica/environments.json,
readable only by you, and never printed. The token secret is needed only by websites that require signed
tokens; get it when you first need it with vizoalica rotate prod token. Setting this up with an AI coding
agent? Run this step yourself, so your Cloudflare API token does not pass through an agent conversation.
To script it, give the answers as options; a script needs no terminal:
export CLOUDFLARE_API_TOKEN=...
vizoalica env add prod --deploy --yes
Deploying is also a command of its own (vizoalica deploy prod shows the plan, --apply creates it, and
--update brings it to the installed version). See Create a backend.
Then open the console:
vizoalica console
It starts the console on your computer at http://127.0.0.1:4318 and opens it in your browser. If something is
not set up yet, a welcome page says what is wrong and which command fixes it. The console does not deploy or
update a backend; update one with vizoalica deploy <name> --update.
More than one backend, or someone else's. Say no to deploying to connect to a backend that already
exists, with the access key you were given. Run vizoalica env add once per name to keep dev and prod side
by side; a picker in the console switches between them. See
Run more than one backend and Access keys.
To keep secrets in a vault instead of a file, see OneCLI.
Returning operators: Start the console day to day.
Step 3: add your websites
In the console, open Websites and choose Add website. Its first field is an empty, required project choice; then enter the site's address. Saving takes you to that website's Install page, which shows one script tag to paste into your pages:
<script
defer
src="https://prod-vizoalica.<you>.workers.dev/vizoalica.js"
data-source="<website key>"
data-token-url="none"
></script>
Your backend serves the script, and it accepts events only from the addresses you entered for the website. Any host works: GitHub Pages, Netlify, WordPress, or plain HTML. Nothing is stored in your visitors' browsers; unique visitors are counted with an identifier that changes every day (see privacy defaults).
Signed tokens (optional). Turn on Require a signed token for a website whose server can run a
small function, so fake events are harder to send. The Install page then offers two paths:
GitHub → Cloudflare Pages (a generated workflow deploys your site with Vizoalica's
dynamic configuration and token endpoint) or Paste a snippet (a static snippet, with an
SDK file and token endpoint you host). The token endpoint needs VIZOALICA_TOKEN_SECRET; get it with
vizoalica rotate <backend> token the first time. The values in either snippet are public browser configuration,
not secrets.
Full guide: docs/operations/pages.md; SDK reference: docs/operations/browser-sdk.md.
Step 4: verify it works
Open your site, then choose Check now on the website's Install page to see the page views arrive. Want to see the console with data before your own site is connected? From a source
checkout, pnpm vizoalica demo --env <name> adds sample page views for a make-believe website
(pnpm vizoalica demo --env <name> --remove deletes them).
The console showing sample data sent through your own backend.
If a step fails, see troubleshooting and resume at that step. A
signed-token website whose events are rejected with invalid_signature has a different
VIZOALICA_TOKEN_SECRET from its Worker.
Ask an AI assistant
Let Claude, Codex, or Cursor answer questions about your analytics and the health of your backends, read-only:
vizoalica mcp install --client claude-code # or claude-desktop, codex, cursor
vizoalica skill install --client claude-code # or codex
The MCP server runs on your computer, works on every environment you have, names the environment in every answer, and never hands a secret to the AI client. See Use Vizoalica with AI.
For contributors: build from source
You do not need this to use Vizoalica. It is for contributors and for anyone who deploys a reviewed tag
or commit from source. You need Node.js 22 or newer, Git, and Corepack, which supplies the pinned pnpm
(9.15.4). The commands below, and the pnpm vizoalica <command> entry point in a checkout, are for that
path only.
git clone https://github.com/ehud-am/vizoalica.git && cd vizoalica
git checkout YOUR_APPROVED_TAG_OR_COMMIT # deploy a reviewed tag or commit, not a moving branch
corepack enable && corepack prepare [email protected] --activate
pnpm install --frozen-lockfile
pnpm build # compiles every workspace package and the console
pnpm browser-sdk:build # script-tag bundles for a website (optional)
- Backend: Wrangler bundles the Worker from source when you deploy, so there is nothing to publish by hand.
- Console:
pnpm vizoalica consoleruns it from the checkout. Nothing is installed system-wide. - Website: the Worker serves the SDK at
/vizoalica.js. For a signed-token website that hosts its own copy,pnpm browser-sdk:buildwritespackages/browser-sdk/dist/vizoalica.jsandvizoalica-loader.js. The same build refreshes the Worker's copy inapps/ingest-worker/src/generated/.
To check a checkout, run pnpm validate (type check and all tests), plus pnpm lint and
pnpm format:check. pnpm test:e2e runs the Chromium responsive and accessibility scenarios and
pnpm coverage enforces the coverage gates. Prefer the manual, step-by-step install, for example
under an approval process? It is documented in full in the
backend guide.
Releases, pushes, tags, and builds never deploy your Worker: an operator does, with
vizoalica deploy (guide) or from a chosen checkout with the
backend guide. A Git-connected website may deploy on
its own push; the website guide explains the difference.
Privacy defaults
Vizoalica avoids collecting sensitive information by default:
- nothing stored in the visitor's browser: no cookies or local storage (the optional
?vizoalica_ignore=1switch writes one value to your own browser, only when you open a link asking for it). Unique visitors are counted by the backend with a daily-rotating identifier whose daily salt is deleted after the day ends; - no raw form values;
- no passwords, payment data, API keys, cookies, or auth headers;
- no raw URL query values;
- no page text, DOM snapshots, heatmaps, or session replay;
- custom properties are filtered by name, type, count, and value length.
Client-side filtering is a convenience, not a trust boundary: the backend also rejects sensitive-looking payloads before persistence. See privacy operations.
No custom domain, paid Workers subscription, hosted dashboard, or always-on local process is required for a small test. Review current Cloudflare pricing and configure retention and usage alerts; included usage is not a guaranteed spending cap. See the cost model.
Architecture
Website
└─ One script tag: the browser SDK, served by your Worker
├─ builds CloudEvents JSON events
├─ redacts URL, query, and referrer data; stores nothing in visitors' browsers
├─ queues events in memory with bounded size
├─ optionally obtains a short-lived ingest token from the website's own server
└─ sends non-blocking event batches
Cloudflare Worker
├─ /vizoalica.js, /healthz, /v1/events:batch, /v1/admin/*
├─ origin authorization, and token verification for signed-token websites
├─ daily-rotating visitor identifier (salt deleted after each day)
├─ CloudEvents + JSON Schema validation, event-age and token checks
├─ quota and payload-size enforcement, backend privacy guard
└─ safe metrics and logging
Storage
├─ R2: immutable raw JSON event batches
└─ D1: projects, websites, quotas, audit, and bounded daily/hourly/minute aggregates
Your computer (on demand)
├─ React console → loopback API → Worker administration and aggregates
└─ AI assistant → local MCP server (read-only) → the same aggregates
Open standards in use: CloudEvents envelopes and batches, JSON Schema validation, optional short-lived JWT/JOSE-compatible ingest tokens, the Model Context Protocol, and an explicit consent state on every event.
Get involved
Vizoalica is built in the open, and it gets better when the people who run it help shape it. You do not need to write code.
- Share an idea, or ask a question: start a discussion. What would make Vizoalica more useful to you?
- Something broke or was confusing: open an issue. A bug report, a docs problem, or a specific request.
- Show how you run it: post in Show and tell.
- Help build it: pick a
good first issueor ahelp wantedissue, or fix a page with the Edit this page on GitHub link on vizoalica.dev.
CONTRIBUTING.md explains how to propose a bigger change and what the project holds to (privacy-minimal, self-hosted, easy to audit). Everyone taking part follows the code of conduct, and SUPPORT.md says where each kind of question goes.
Documentation
Vizoalica is released under the MIT License.