stats.store proxies Sparkle appcast requests and presents the attached update statistics in a dashboard for macOS app maintainers. The hosted service is free for open-source apps, and the project can also be self-hosted with Supabase and Vercel.
<key>SUFeedURL</key>
<string>https://stats.store/api/v1/appcast/appcast.xml</string>The proxy returns the app's registered upstream feed and records the profile fields Sparkle sends with the update check.
The hosted service at stats.store does not require an installation. Email Peter with the app's display name, bundle identifier, and current appcast URL to register an open-source app.
For your own deployment, use Node.js 24 or newer and pnpm 12.4.1 or newer, then follow the deployment guide to configure Supabase, apply the database migrations, and deploy the Next.js app.
After the app is registered, replace its existing SUFeedURL value with the stats.store proxy URL:
<key>SUFeedURL</key>
<string>https://stats.store/api/v1/appcast/appcast.xml</string>Sparkle continues to check for updates through the same appcast. Once update checks arrive, open stats.store to inspect daily users, app-version adoption, macOS versions, CPU architectures, hardware models, languages, memory, and core counts.
Prerelease channels can use https://stats.store/api/v1/appcast/appcast-prerelease.xml. The registered upstream feed must expose the corresponding appcast; see the appcast proxy guide for URL mapping and troubleshooting.
- Sparkle requests the proxy URL and identifies the app by bundle identifier, app name, or its user-agent.
- stats.store hashes the request IP with the current UTC date and records the Sparkle fields that are present.
- The proxy fetches the app's registered upstream appcast and returns it to Sparkle.
- The dashboard reads aggregate data from Supabase and updates through Supabase Realtime.
For apps that send telemetry directly, the project also exposes POST /api/v1/ingest; its payload and responses are documented in the Sparkle integration guide.
The service stores a daily SHA-256 digest derived from the request IP, never the raw IP. Including the date makes the digest useful for counting daily unique clients without creating a stable identifier across days.
When Sparkle supplies them, stats.store records the app version, macOS version, CPU type and core count, language, hardware model, and memory. It does not receive in-app behavior events through the appcast proxy. Vercel Web Analytics is disabled unless a self-hosted deployment explicitly sets NEXT_PUBLIC_ENABLE_VERCEL_ANALYTICS=1.
The architecture notes describe the data flow, schema, endpoints, and aggregation model. The project story explains the motivation behind the hosted service.
Self-hosting requires a Supabase project and the environment values listed in .env.example. Apply every numbered SQL file currently present in scripts/ in numeric order, then apply the managed migrations in supabase/migrations/ as described in the deployment guide.
With the database and .env.local ready:
pnpm install
pnpm devThe local dashboard runs at http://localhost:3000. See the registration guide to add an app and the real-time setup guide to enable live dashboard updates.
pnpm lint
pnpm typecheck
pnpm test
SKIP_ENV_VALIDATION=true pnpm buildTests cover the API routes, dashboard components, hooks, and data formatting. See tests/README.md for focused commands and CONTRIBUTING.md for the contribution workflow.
Use GitHub Issues for bugs and feature discussions. You can also reach Peter Steinberger or follow @steipete.
Built by Peter Steinberger for the Mac developer community.
No license file is currently included in this repository.
