SH

Shynet

Modern, privacy-friendly, detailed web analytics

Web Analytics ★ 3.2k stars Easy setup Apache-2.0

Shynet is a modern, privacy-friendly, and detailed web analytics platform that works without cookies and even without JavaScript. It targets users wanting solid analytics with strong privacy. It is deployed via Docker.

Key features

  • Works without JavaScript or cookies
  • Detailed session insights
  • Multiple sites and users
  • Privacy-respecting

Pros & cons

Strengths

  • Strong privacy
  • Works without JS
  • Detailed sessions

Trade-offs

  • Smaller community
  • Fewer integrations

Shynet replaces

Last reviewed Sep 13, 2026 · 763 words

Shynet's reason to exist is a 1x1 pixel. Every other privacy analytics tool needs JavaScript to run in the visitor's browser; Shynet can count a hit from a plain <img> tag, which means it still sees the roughly 5 to 15 percent of visitors running script blockers, the text-only readers, and the people who open your feed in a client that renders images. If that population matters to you, Shynet is the only tool in this size band that counts it. If it does not, Umami or Plausible will give you a smoother ride.

The deployment is two containers and one command

Shynet is a Django application. The compose file from the repository is a Postgres container plus the app image, with the app listening on port 8080 inside:

services:
  shynet:
    image: milesmcc/shynet:latest
    restart: unless-stopped
    env_file: .env
    ports:
      - "8080:8080"
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    env_file: .env
    volumes:
      - ./pgdata:/var/lib/postgresql/data

The .env needs DJANGO_SECRET_KEY, ALLOWED_HOSTS (your analytics hostname, not ), and the DB_ values matching the Postgres container. The first admin is not created through the web; you run it once:

docker compose exec shynet ./manage.py registeradmin [email protected]

It prints a temporary password. From there, everything is in the UI: add a service, copy the snippet, done. The 512 MB minimum leaves headroom; a small site idles well under it.

One instance holds any number of services, and each service can be shared with other user accounts, so a single Shynet install can serve your own 3 sites plus a friend's blog with each person seeing only their own numbers. That is a quiet strength over the single-tenant tools at this size, and it is why I run one shared instance rather than one per project. Additional users are created the same way as the first admin, from the command line, or invited from the settings page once you are in.

Sessions, not just pageviews

The dashboard leans toward the session as its unit: each visit is a list of pages in order, with duration, referrer, device, and the load time the script measured. That is the "detailed" in the tagline, and it is more forensic than Plausible's aggregate charts. It also explains why Shynet fits a personal site or a small product better than a busy content site: a session list for 200 visits a day is readable, a session list for 50,000 is not, and the aggregate views above it are competent rather than deep.

Privacy is handled by not collecting: no cookies, IP storage is a per-service toggle you can leave off, and location is derived coarsely from a local GeoIP lookup. Whether that clears the consent-banner bar depends on your jurisdiction and your reading of it, same as every tool on the Google Analytics alternatives page.

The tracking snippet has two forms

The script version:

<script src="https://stats.example.com/ingress/<service-uuid>/script.js"></script>

The no-JavaScript version:

<noscript><img src="https://stats.example.com/ingress/<service-uuid>/pixel.gif"></noscript>

Use both, with the pixel inside <noscript>, and you count the whole audience without double counting. The pixel alone gives you page hits but no load time or session duration; that is the trade you accept for readers with scripts off. Both endpoints live under /ingress/, so if a blocker's filter list includes that path, expect some loss on the script side too.

The maintenance question is the real one

Shynet is a one-person project with a smaller community than its neighbours, and release cadence has been irregular. It is stable and the Django stack ages gracefully, but if you want a tool with a busy roadmap and a plugin ecosystem, the Plausible vs Umami comparison covers the two larger projects most people should default to. Choose Shynet for the pixel and the session detail, not for momentum.

What I'd do

For a personal site or a low-traffic product where you want to see individual visits and count the script-blocking readers, run Shynet as above behind a reverse proxy on a subdomain, add both snippet forms, and set ALLOWED_HOSTS properly. For anything with public traffic you will report on to other people, run Umami instead and accept losing the pixel. If you are leaving Google Analytics and undecided, my ditching Google Analytics writeup walks the migration and the decision.

Compare Shynet

19 head-to-head comparisons.

Similar web analytics apps