Self-hosted service
milesmcc/shynet avatar
milesmcc/shynet

Shynet: Cookie-Free Analytics You Host Yourself

Modern, privacy-friendly, and detailed web analytics that works without cookies or JS.

3,154 stars208 forksPythonApache-2.0

At a glance

What is it?
Shynet is a self-hosted Django analytics service that identifies sessions without cookies and degrades to a tracking pixel when JavaScript is unavailable. It fits small sites and personal projects; the README itself says it has not been tested at ultra-high traffic.
Who is it for?
Adopt Shynet if you run a personal project or a small to medium site and are willing to operate a Django deployment yourself. Skip it if you need a one-click hosted product, if you want a formal GDPR compliance guarantee (the README explicitly declines to give one), or if your traffic is high enough that you need the rollup aggregation that is still only on the roadmap.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Shynet is aimed at: analytics without the consent banner

Most hosted analytics products require you to send visitor data to a third party and to set cookies that persist across sessions. The README lists exactly these complaints as its motivation: handing visitor information to another company, cookie notices, closed source or expensive tooling, and interfaces that are hard to use. Shynet's answer is to remove the cookie entirely and let you run the server. Because there is no cookie, there is no cross-session identifier stored in the browser, and the README argues that means no intrusive cookie notice is needed. Whether that argument holds in your jurisdiction is a question the README refuses to answer: asked whether Shynet is GDPR compliant, it says only that compliance depends on how you use it and that you should talk to a lawyer. That is an unusually honest position for an analytics project, and it should be read as a boundary rather than a marketing gap. The intended audience is narrow and stated plainly: personal projects and small to medium websites, deployed by someone with the technical know-how to run a Django application.

How a session exists without a cookie

Shynet's data model has three objects named in the README. A service is a property you want to track, usually a site or a top-level domain, and each service gets its own tracking embed. A hit is a single page load on a service. A session is a collection of hits made by the same browser in a short period of time. Since no cookie is written, the server has to decide whether two hits belong to the same browser from the request itself. The README does not document the exact fingerprinting fields or the length of the session window, so treat that as something to read in the source before you rely on it. What the README does confirm is the input data: browser and operating system come from the user agent, device type (desktop, tablet, phone) also comes from the user agent, and geographic location and network come from the IP address. That is the whole collection surface, and it is why the metrics list stops where it does. There is no cross-site graph and no stored visitor profile beyond what a session needs. The trade-off is inherent: a cookie-free identifier is probabilistic, so two visitors behind the same NAT with identical user agents may be merged into one session, and one visitor who changes network mid-visit may be split into two.

The tracking script, the pixel fallback, and primary-key integration

The tracking script lives at shynet/analytics/templates/analytics/scripts/page.js and the README states it weighs less than a kilobyte. If JavaScript is unavailable, Shynet falls back to a 1x1 transparent tracking pixel, so the same hit is still recorded for visitors running NoScript or a text browser. The topic list includes noscript, which matches this design. The README also notes that because you host Shynet yourself, the script tends not to appear on ad block lists, which is a deployment property rather than a technical one, and it will stop being true if your domain ever gets classified. The feature the README calls primary-key integration lets you associate a visitor in Shynet with that person's account on your own site. That is the one path in the product that deliberately links analytics data to an identified individual, and it is opt-in. If your privacy position depends on Shynet being anonymous, this is the switch that changes it, so decide before you instrument anything. The metrics themselves are conventional: hits, sessions, page load time, bounce rate, duration, referrers, page popularity, OS, browser, approximate location, and device type.

Getting it running: Docker, docker-compose, Heroku, or Kubernetes

The README points to GUIDE.md for installation and states that Shynet supports deployment as a simple Docker container, with docker-compose, on Heroku, or on Kubernetes, with manifests in the kubernetes directory of the repository. The single-machine path is the one the README describes first: the project is small enough to run as one container on one small VPS. For higher traffic, the README describes a second topology with parallelized ingress nodes, Redis caching, and separate backend workers for database IO. Those two shapes are the real deployment decision, and they are not interchangeable: the distributed form adds Redis and worker processes you now have to monitor. Configuration is done through Django, which the README frames as an advantage because deploying, updating, and migrating are standard Django operations. Specific environment variable names are not listed in the README, so read GUIDE.md and the compose file before you plan a rollout. Accounts are handled by Django Allauth, and a single instance supports multiple users each tracking multiple services, with administrators able to share services with other users.

Do Not Track is a per-service setting, and the default is to collect nothing

The FAQ answers the DNT question directly. There is no standardized way to handle Do Not Track, so Shynet lets you choose per service whether to collect any data from users who send the signal, and the default is not to collect from them. That default matters more than it looks. It means a visitor with DNT enabled is invisible to your dashboards, and if a meaningful share of your audience enables it, your session and hit counts will read low with no warning in the interface. The per-service scope is the right granularity, because a marketing site and an internal tool may warrant different answers, but it also means the setting can drift across services if nobody records what was chosen. The README does not describe an audit view for those settings, so the practical approach is to keep the DNT choice in whatever configuration management you already use for the deployment. Nothing in the supplied material states how Shynet detects the signal or whether the choice is exposed in the management UI.

Where Shynet is the wrong tool

The README's own Recommendations section is the most useful part of the document. Shynet is not for everyone: it is described as great for personal projects and small to medium websites, and explicitly not tested with ultra-high traffic sites. It also requires a fair amount of technical know-how to deploy and maintain, and the README tells anyone who needs a one-click solution to use other tools. Take that at face value. If you do not want to run a database, a Django process, and possibly Redis and workers, Shynet is not a lighter alternative to a hosted product, it is a second application you now operate. The roadmap reinforces the ceiling: data aggregation through rollups, anomaly detection, detailed data exports, two-factor authentication, and a data deletion tool are all listed as upcoming rather than shipped. Until rollups arrive, long-range queries run against raw hit rows, which is exactly the shape of workload that becomes painful as history accumulates. And the cookie-free session model has an accuracy cost that no amount of tuning removes, because it is a design choice rather than a bug.

The alternative: Plausible, and what actually differs

The obvious comparison is Plausible Analytics, another self-hostable, privacy-oriented web analytics tool written in a different stack. The difference that matters is not the feature list but the session model and the operational surface. Plausible's documented approach is built around a script that sends pageviews and custom events, and its self-hosted edition is distributed as a Docker Compose deployment with its own database and configuration; Shynet instead leans on Django's deployment, migration, and account machinery, which is an advantage if your team already runs Django and a cost if it does not. The second difference is fallback behaviour: Shynet records a hit through a 1x1 pixel when JavaScript is absent, while a script-only collector sees nothing from those visitors. If your audience includes people who block or disable JavaScript, that gap is the deciding factor. The third difference is scope. Shynet's stated ambition is modest and its roadmap is public; if you need exports, rollups, or two-factor authentication today, you should check whether the tool you are comparing against already ships them rather than waiting on Shynet's project board.

Maintenance cost, release cadence, and the Apache-2.0 licence

The release history in the repository tells you what to expect operationally. v0.13.0 landed in July 2023, v0.13.1 followed later that month to fix Cython and crypto build issues, and v0.14.0 arrived in March 2026 as a security and dependency update. That is a long quiet stretch between 2023 and 2026, so plan for a project that moves in bursts rather than on a schedule, and expect dependency and security bumps to be the main reason to upgrade. The practical consequence is that you own the upgrade path: because Shynet is Django, updating and migrating are standard Django operations, but you still have to run the migrations and confirm the build works, which is precisely the class of problem v0.13.1 was released to fix. The licence is Apache-2.0, a permissive licence that allows commercial use and modification and includes an explicit patent grant, with the usual obligations to retain notices and state significant changes. It does not settle the privacy question, and the README says as much. If your deployment stores IP-derived location data, the licence gives you no cover for how you handle it; that is a policy and legal matter you have to resolve separately.

Editorial conclusion

Adopt Shynet if you run a personal project or a small to medium site and are willing to operate a Django deployment yourself. Skip it if you need a one-click hosted product, if you want a formal GDPR compliance guarantee (the README explicitly declines to give one), or if your traffic is high enough that you need the rollup aggregation that is still only on the roadmap. Before committing, verify three things: that the fingerprinting window and DNT default match your privacy policy, that you can run the docker-compose or Kubernetes deployment described in GUIDE.md, and that Apache-2.0 plus your jurisdiction's rules on IP-derived location data are acceptable to whoever signs off on privacy at your organisation.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. milesmcc/shynet on GitHub
  4. README
  5. Releases
Community notes

Community notes