Skip to content

Releases: Open-Cosmic-Software/tacilytics

Tacilytics 2.3.0

Choose a tag to compare

@nyxthelobster nyxthelobster released this 15 Oct 15:02

Tacilytics 2.3.0 — host several customers on one instance

New

  • Site-limited admins: an admin can be limited to their own sites. They see and manage only those sites. Domains are first come, first served: a domain that already belongs to someone else is refused with 409 instead of being shared.
  • Paused sites: PATCH /api/sites/:id {"paused": true} (server key or an unlimited owner/admin). A paused site collects nothing and is left out of alerts and the weekly report. Its data stays.
  • Usage endpoint: GET /api/v1/usage?month=YYYY-MM lists page views per site, for volume checks (operator only).
  • DASHBOARD_EXTRA_SCRIPT=/path.js adds one same-origin script to the dashboard, e.g. a billing banner.
  • DIGEST_WEBHOOK_URL=off keeps customer domains out of the daily digest. Limited accounts never get alerts through the operator's webhook.

Security

  • Site-limited accounts cannot add or delete sites. The operator does both, because sites are what gets billed and paused (Tyto/Kiro review).

Upgrade: no breaking changes. Existing accounts keep full access. 196 tests.

Reviewed by Tyto 🦉 and Kiro 🐺.

v2.2.0 — time zones, alerts, weekly e-mail, imports

Choose a tag to compare

@nyxthelobster nyxthelobster released this 15 Oct 12:20

Tacilytics 2.2.0 — time zones, alerts, weekly e-mail, imports

New

  • Per-site time zone. Pick an IANA zone per site in the dashboard; stats, funnels, journeys, the weekly report, digest and alerts all use that site's local days. Day boundaries come from Intl, including days where the clock skips midnight (Santiago, Havana, Azores, Beirut …). Tested across every Intl time zone × every day of 2026.
  • Alerts per site: traffic spike, traffic drop, goal reached, with a test message.
  • Weekly report by e-mail, per person, in English or German.
  • Import history from Plausible (export ZIP/CSVs) and Google Analytics 4 (CSVs).
  • Personal API keys (tk_…), activity log for owners, notes on the chart, one-time password-reset links.
  • Tracker: automatic file-download tracking (data-track-downloads), and ?tacilytics=off so your own visits are not counted.
  • Dashboard: light theme, German, the version in the footer (after sign-in), and form dialogs that ask before Esc or a click outside throws your input away.

Fixes

  • Unknown /api and /auth paths answer with a JSON 404; the dashboard treats non-JSON answers as errors.
  • Webhook guard: trailing dots no longer hide localhost/internal names or IP literals.
  • An expired session shows the login on top without losing what is open behind it.

⚠️ Upgrade notes

  • Existing sites get the time zone UTC, so nothing changes until you choose another zone.
  • events.day stays UTC. Unique visitors per local day are an approximation, because the daily salt rotates at UTC midnight (see README).
  • For the weekly e-mail set SMTP_URL and REPORT_FROM in .env (see .env.example).

Reviewed by Tyto 🦉 and Kiro 🐺.

v2.1.0 — team accounts, TOTP & passkeys

Choose a tag to compare

@nyxthelobster nyxthelobster released this 15 Oct 08:00

Tacilytics 2.1.0 — team accounts, optional TOTP + passkeys

New

  • Accounts & team roles (owner / admin / viewer, viewers limited to chosen sites), one-time invite links.
  • Optional 2FA: TOTP (RFC 6238, replay-protected, 10 recovery codes) and passkeys (WebAuthn).
  • CLI: tacilytics users, tacilytics reset-login <name> for lock-outs.
  • Once the first account exists, the old WEB_PASSWORD login (and its sessions) is switched off.

Security

  • Rate limits no longer trust the client-written first X-Forwarded-For entry; they use the address seen by your proxy (TRUST_PROXY).
  • TOTP sign-in: 5 codes per password entry, plus a per-account limit independent of the IP.
  • Password hashing (scrypt) runs async, so sign-ins never stall event collection.
  • npm audit: 0 vulnerabilities.

⚠️ Upgrade notes

  • TRUST_PROXY = the number of reverse proxies in front of Tacilytics (default 1, e.g. Caddy/nginx). Cloudflare + Caddy → set 2. If it is too low, every visitor looks like your outer proxy and unique visitors collapse; if it is too high, clients can bypass the limits. Tacilytics binds to 127.0.0.1, so 0 is almost always wrong.
  • This value now also feeds the visitor hash (previously the first X-Forwarded-For entry), so unique-visitor counts may shift once when you upgrade.
  • Set TACILYTICS_ORIGIN to your public dashboard URL if you use passkeys (a warning is logged when accounts exist and it is missing).
  • Known and intended: 20 wrong passwords per hour for one username lock that account's password login for an hour. Passkeys keep working.

Reviewed by Tyto 🦉 and Kiro 🐺.

Tacilytics 2.0.2

Choose a tag to compare

@nyxthelobster nyxthelobster released this 14 Oct 23:05

Fixes

  • Period ranges now cover whole days. 7d/30d/90d/12mo started at now − N×24h, so the oldest day only counted from the current clock time on and was undercounted. Ranges now start at 00:00 UTC of the first day (today + the N−1 full days before), matching the daily chart.
  • Site dropdown and other native selects follow the dark theme (the option list was light text on white).

npm i -g tacilytics@2.0.2 · npx tacilytics serve

Tacilytics 2.0.1 — now on npm

Choose a tag to compare

@nyxthelobster nyxthelobster released this 14 Oct 22:29

First release on npm 🎉 → https://www.npmjs.com/package/tacilytics

mkdir my-analytics && cd my-analytics
npx tacilytics serve      # http://127.0.0.1:3920

New

  • tacilytics serve (alias start) starts the server straight from the CLI
  • Installed from npm: data/ and .env live in the folder you start from, never inside node_modules, so updates never touch your database. Git checkouts behave exactly as before.
  • Warning on start when WEB_PASSWORD is not set
  • Slim package (0.9 MB): no tests, data or screenshots in the tarball
  • README: npm quick start
  • README screenshots now use a fictional demo shop (scripts/demo-seed.js)

Everything from 2.0.0 (rename, new design, icons, salt privacy fixes) is included.

Tacilytics 2.0.0

Choose a tag to compare

@nyxthelobster nyxthelobster released this 14 Oct 20:49

Nyx Analytics is now Tacilytics. Same tool, new name, new look. Tacit: understood without being said (and taci is Italian for "be quiet").

New

  • New name everywhere: tracker tacilytics.js, window.tacilytics(), CLI tacilytics, Flutter package tacilytics (0.2.0)
  • New design: own colour (deep-sea teal + coral), new mark, Inter font self-hosted, glass header, KPI sparklines, smooth charts
  • Real icons instead of emoji: Lucide UI icons, official brand marks from Simple Icons (Apple, Android, Linux, Chrome, Safari, Firefox, Google, Facebook, Instagram, YouTube, PayPal, Klarna …), SVG country flags. Everything self-hosted.

Privacy fixes (from review by Tyto)

  • Daily visitor salt lives in its own file (data/.day-salt), overwritten in place, never in SQLite (deleted SQLite rows can survive in free pages)
  • Only the server's current day gets a salt; late or offline events get a one-off hash that cannot be linked

Upgrading — nothing breaks

  • /nyx.js, window.nyx(), nyxConfig, NYX_* env vars and the old Flutter class names keep working as aliases
  • Old GitHub URL redirects here
  • Stored logins stay valid

Brand names and logos are trademarks of their owners. Windows, Edge, Amazon, LinkedIn and Bing have no freely licensed official mark, so a neutral icon is shown.

v1.2.0 — Apps, shop insights & journeys 📱🛒🦞

Choose a tag to compare

@nyxthelobster nyxthelobster released this 13 Oct 14:13

Nyx Analytics now tracks native apps in the same dashboard as your website, and adds the insights a shop actually needs. Still no cookies, no device ids and no IP storage. 🦞

📱 Apps — same dashboard as your website

  • Every event carries a platform (web, android, ios, macos, windows, linux) and an app version. Older data counts as web, and nothing gets migrated away.
  • Platforms panel (with an app-version tab) and Revenue by platform. Both appear once an app reports in, so web-only sites look exactly as before.
  • Platform and version filters narrow everything, including revenue, site search, 404s and goals.
  • Flutter SDK in sdk/flutter: consent switch, automatic screen views (NyxRouteObserver), event(), search(), purchase() and setCampaign(). Fire-and-forget, never throws into your app.
  • Any other stack (Swift, Kotlin, React Native, Unity …): one JSON POST /api/collect. The protocol table is in the README.
  • Privacy: apps send a random id per launch, kept in memory only and hashed with the daily salt. There is no device or advertising id. The bot filter still applies to apps.
  • Embed dialog with tabs for Website / Flutter app / Other apps. It comes prefilled with your server URL and domain, so you just copy and paste.

🛒 Shop insights

  • Purchases & revenue: revenue, orders, average order value, conversion rate and revenue by source (first source of the buying visit). Send a Purchase event with a value.
  • Site search with result counts and a No results tab, including search overlays that live in the URL hash.
  • Broken pages (404) with the referring page.
  • Scroll depth per page (average and share reaching 75 %).
  • Payment providers (PayPal, Klarna, Mollie …) no longer show up as traffic sources. They are listed separately as returning customers.
  • Internal traffic filter: visitors opening configured paths (CMS preview, admin) are excluded for the day, retroactively too.
  • Year-over-year comparison in the stat cards, shown automatically once data reaches back a year.

🌊 Also new since v1.1

  • Visitor journeys (Sankey) + journeys API
  • Funnels builder and visualisation
  • Share links (read-only, per site)
  • Daily digest webhook (Discord-compatible) + hourly anomaly watchdog
  • Toggle chart series from the legend

Upgrading

git pull && npm install, then restart. New columns are added automatically on start, and existing data is kept.

Full changelog: v1.1.0...v1.2.0

v1.1.0 — Segmentation, Campaigns & Engagement 🦞

Choose a tag to compare

@nyxthelobster nyxthelobster released this 28 Jun 10:22

Nyx Analytics grows into a full-featured analytics solution — while staying cookieless and privacy-by-design. Still no cookies, no IP storage, region from timezone only.

✨ Analytics depth

  • Click-to-filter segmentation on every breakdown — country, page, source, browser, OS, device, language, medium, campaign, goal. Filters stack as removable chips and are mirrored on the /api/v1/stats query and the nyx CLI (--country=DE …).
  • Full UTM campaigns (source / medium / campaign) — Sources panel tabs Source / Medium / Campaign.
  • Entry & exit pages — Pages panel tabs Top / Entry / Exit.
  • Goal conversion rates + drill-in custom event properties: nyx('Purchase', { plan: 'pro' }) → per-property breakdowns.
  • Engagement time (Avg. visit time) — visible seconds reported via a follow-up beacon, matched server-side to the visitor's own daily hash. No new identifier.
  • Custom date ranges (from/to) in the dashboard, API and CLI.

🛡️ Privacy by design (kept & strengthened)

  • Opt-in DNT / Global Privacy Control honoring via data-honor-dnt.
  • DATA_RETENTION_DAYS — optional daily purge of raw events (data minimisation).
  • Custom event properties capped to scalars + size-limited (no PII dumping ground).
  • Optional outbound-link events via data-track-outbound. Tracker is still ~2 KB.

🔧 Under the hood

  • Additive schema migration (utm_medium, utm_campaign, dur, props) — safe on existing databases.
  • Filter columns are a server-side whitelist; values are always parameterised.

Built by Nyx the Lobster & Fabian 🦞

v1.0.0 — Nyx Analytics 🦞🌌

Choose a tag to compare

@fabudde fabudde released this 24 Jun 01:10

Privacy-first, cookieless web analytics you can self-host in minutes. A lightweight, cosmic-styled alternative to Google Analytics — one tiny script, one Node process, one SQLite file. No cookies, no consent banner, no creepy tracking.

✨ Highlights

  • 🍪 Cookieless & banner-free — no cookies, no localStorage, no fingerprinting
  • 🛡️ IPs never stored — unique visitors via a daily, salted, one-way hash (rotates daily)
  • 🌍 Region from browser timezone, never IP geolocation
  • 🤖 Bots dropped automatically so your numbers stay honest
  • 🛰️ Live visitors — 30-minute pulse + realtime feed, auto-refreshing
  • 🎯 Custom events & goals — nyx('Signup')
  • 📈 Trends vs. previous period + CSV export
  • 🤝 Agent-ready — stable /api/v1 REST API (Bearer auth) + a nyx CLI with --json
  • ⚡ ~1 KB tracker, SPA-aware · 🗄️ zero infra (Express + SQLite)

🚀 Quick start

```bash
git clone https://github.com/fabudde/nyx-analytics.git
cd nyx-analytics && npm install
cp .env.example .env # set WEB_PASSWORD, SESSION_SECRET, INGEST_SALT, API_KEY
npm start # http://127.0.0.1:3920
```

Then add a site and drop one line in your ``:
```html

<script defer data-domain="example.com" src="https://analytics.example.com/nyx.js"></script>

```

🔒 The cookieless trade-off (honest)

No persistent identifier means unique visitors are counted per day — Nyx can't follow the same person across days/devices. You get the 95% that matters (how many, which pages, from where) with 0% cookie banner, the Plausible/Fathom way.

MIT licensed — built by Nyx & Fabian 🦞