Every analytics tool eventually becomes the thing it replaced. Features pile up, dashboards multiply, and you end up opening a "simple analytics" product without knowing what your users did. This documents the trade-offs we chose on purpose.
We built Janus for ourselves first. Side projects, personal tools, things where "set up analytics" sat at the bottom of the todo list because every option felt like homework. GA required learning a vocabulary we didn’t need. Plausible didn’t answer the questions we actually had. PostHog assumed we had a product team.
Janus exists because we kept reaching for a tool that wasn’t there: something a single developer could open, understand in three seconds, and close. Not a platform. Not a product you need training for. A dashboard that answers "is anyone using the thing I built yesterday?" and gets out of the way.
This article documents the opinions baked into the product. Not marketing. A record of trade-offs chosen on purpose, and why. This is also not a comparison. Other tools solve different problems for different users. Janus solves a specific one: giving one developer a clear view of what happened on their site, with the least possible overhead.
The failure mode isn’t complexity. It’s irrelevance. You open GA, see a dashboard full of reports, and none of them answer the one question you came with: is anyone using the thing I built yesterday?
Plausible solved the privacy problem but kept the same mental model: aggregate traffic stats on a single-page dashboard. That works for content sites where the question is "which posts get read." But if you’re building a product, pageview counts don’t tell you whether people completed onboarding, hit a paywall, or bounced on the signup form.
The gap we saw was structural, not cosmetic. Every analytics tool we tried organized around pageviews. Janus organizes around events. Page views are one event type among many. Signups, purchases, feature activations, and errors are others. You name your events, attach whatever properties matter to your product, and the dashboard reflects what people did — not just where they went.
As of June 2026, Janus tracks three kinds of data: page views (automatic), custom events (you define them via Janus.track()), and context (collected by the SDK without configuration: referrer, device, country, UTM parameters). The dashboard is structured around those inputs. No audience segments. No campaign manager. No conversion goals with multi-touch attribution models.
This event-first model means you name things in your own language. checkout_started, api_key_generated, guide_read. Not "Goal 3" in a configuration panel. When you query your data — through the dashboard, the HTTP API, or an AI coding agent — the results read like a log of your product, not a report from someone else’s framework.
This is the most visible design decision in the product, and it comes from Edward Tufte’s principle of data-ink ratio: every pixel on screen should either be data or whitespace that makes data readable. Card borders, drop shadows, decorative containers, gradient fills on chart segments — these compete with the numbers for your attention without adding information.
Charts are good at one thing: showing change over time. A line chart reveals trends, seasonality, and anomalies that a table of daily numbers would bury. Janus uses charts for exactly that. The Trajectory section on the dashboard is a time-series area chart showing event volume over your selected period. For everything else — referrer rankings, top pages, country breakdowns, browser distributions — tables win.
The analytics industry defaults to charts because they screenshot well. A pie chart says "we have data." A table says "here’s what the data is." Demos favor the first. Daily use rewards the second.
This isn’t minimalism as aesthetic. It’s minimalism as reading speed. The faster you can scan the dashboard and get your answer, the sooner you’re back to building. A developer checking traffic between deploys doesn’t want to hover over chart segments to read tooltips. They want a sorted list they can scan in three seconds.
The same principle extends to page layout. No card chrome on data sections. No borders, shadows, or rounded containers around metrics. Typography creates hierarchy: large numbers for hero metrics, bold headers for sections, small-caps labels for categories. The data sits in open space. If you’ve used the dashboard, you’ve noticed the absence of visual containers. That absence is the design. Read more on the about page.
These are decisions with reasons, not gaps in the roadmap.
Funnel analysis is a paid feature. Journeys are available on Pro because building useful funnels requires enough event volume that you’ve outgrown the "just checking in" phase. The free tier covers 10,000 events per month, 3 API keys, and 3 months of data retention. Funnels come with Pro.
type + payload + automatic context. You name your events. You decide what data to attach. No predefined taxonomy of goals, conversions, and audiences that forces your product into someone else’s categories.The SDK batches events, queues when offline, and retries with exponential backoff. As of June 2026, the loader is approximately 400 bytes. It has zero measurable impact on Core Web Vitals. The full API surface covers initialization, page tracking, custom events, user identification, and error callbacks with seven distinct error types.
Framework-specific setup is documented for Next.js, Nuxt, Remix, Astro, and SvelteKit in the framework guides. Each guide covers the specific integration pattern for that framework’s routing model.
The MCP server extends this to AI coding agents. Ask Claude Code or Cursor "what were the top events last week" and get a table in your terminal. Six read-only tools cover dashboard stats, event queries, usage data, journey results, and API key listings. This is the logical conclusion of developer-first: the data meets you in the tool you’re already using.
Developer-first is not a positioning statement. It’s a design constraint. If a feature would require leaving the code editor to configure something in a web UI, we look for a way to make it work from the editor instead.
The primary value is clarity. Privacy is a constraint we build within, not a feature we sell.
The technical specifics: distinctId is a random string generated in the browser and stored in localStorage. It contains no personal information and is scoped to your domain. Other websites cannot read it. sessionId lives in sessionStorage and expires when the tab closes. IP addresses are used transiently for country-level GeoIP lookup and then discarded. They are never written to the database. Full details are in the privacy policy.
No cookies means no consent banner. According to the ePrivacy Directive, cookie consent is required for cookies and similar tracking technologies. localStorage is first-party storage that doesn’t enable cross-site tracking and falls outside the directive’s scope. GDPR still applies to the processing of personal data, but a random anonymous ID does not identify a natural person under GDPR’s definition.
We chose not to make privacy the brand because "privacy-first" frames every product decision as a privacy trade-off. We’d rather frame decisions around "does this help you understand what your users did" and implement them in a way that doesn’t require surveillance. Privacy isn’t the feature. It’s the constraint that keeps the feature set honest.
The practical result: you add Janus to a side project without adding a cookie banner. You don’t need a privacy policy update to cover third-party data sharing because there is none. You don’t need to evaluate GDPR compliance for your analytics provider because the architecture was designed around the constraint from the start.
Janus is opinionated because unopinionated tools end up serving everyone poorly. We’d rather be exactly right for one kind of user — someone building something, shipping it, checking if it works — than vaguely useful for all of them. As of June 2026:
The features we shipped are the ones we kept reaching for ourselves. The features we skipped are the ones we never opened twice. If a decision we made doesn’t serve you, the feedback button is in the app. Or connect your AI coding agent and let it check the data for you.
Janus is a lightweight, privacy-first web analytics tool built for developers and indie builders. It tracks page views automatically and custom events via a JavaScript SDK under 1 KB. There are no cookies, no fingerprinting, and no consent banners required. Data shows up on a minimal dashboard organized around tables, not charts. The free tier includes 10,000 events per month with 3 months of data retention.
Tables communicate more data per pixel than charts. A ranked table shows every data point with its count and rank in a single scan. A chart typically shows only the top items and uses most of its space on axes, labels, and padding. Janus follows Edward Tufte’s data-ink ratio principle: every pixel should be data or whitespace that makes data readable. Charts are reserved for time-series trends where they reveal shape that tables cannot.
No. Bounce rate is the most-checked, least-actionable metric in analytics. A 70% bounce rate tells you people left but not why or what to change. Janus tracks sessions and page depth instead, which let you derive engagement from actual user behavior rather than a single percentage.
Google Analytics is built for marketing teams and organizes around pageviews, audience segments, and campaign attribution. Janus is built for solo developers and organizes around events. You name your own events, attach your own properties, and see what users did on a minimal dashboard. Janus uses no cookies, requires no consent banner, and the SDK is under 1 KB compared to roughly 80 KB for gtag.js.
The Janus MCP server is open source and published on GitHub at github.com/janus-analytics/mcp-server. The main Janus platform including the backend, frontend, and SDK is a hosted service. There is nothing to deploy or maintain. You sign up, add a script tag, and start tracking.
The Janus MCP server lets AI coding agents like Claude Code, Cursor, and Windsurf query your analytics data directly. It provides six read-only tools covering dashboard stats, event queries, usage data, journey listings, journey results, and API key listings. Install it via npm and connect it with your Janus API key. Your agent can then answer questions like "what were my top events last week" without you opening the dashboard.
Janus is built for solo developers, indie hackers, and side project builders who want to understand what their users do without configuring a marketing-grade analytics platform. If you want to ship a project, drop in a script tag, check whether anyone is using it, and get back to building, Janus is designed for that workflow.
Free tier. No credit card. No consent banner. No forty-report dashboard.
Get started with Janus