Open-source, serverless, privacy-safe profile view counter with glass-style SVG badges. Runs entirely on Deno Deploy — no servers, no databases, no cost.
The point of this project is that you deploy your own instance. Don't embed someone else's URL in your README — the counter would be tracking you through their service. In 5 minutes you get your own https://<your-project>.deno.net and you own the data.
- Total views, unique visitors, and daily stats
- Glass-style SVG badges with gradient shimmer
- Path-based routing — clean URLs like
/badge/octocat - Bot filtering (heuristic-based)
- Rate limiting (5 increments per IP per user per hour)
- Hashed IPs, no cookies, GDPR-friendly
- Named sub-counters for per-repo tracking
- Zero dependencies beyond the Deno standard runtime
git clone https://github.com/Vermaarp/profile-views
cd profile-viewscurl -fsSL https://deno.land/install.sh | shdeno task dev
# → http://localhost:8000- Push your fork to GitHub.
- Go to dash.deno.com → New Project.
- Connect your GitHub repo, pick
main.tsas the entrypoint. - Done. You get
https://<your-project>.deno.net.
If the first deploy fails with
Deno.openKv is not a function, open your project's Settings → KV Database on Deno Deploy and provision a KV instance, then redeploy.
Replace <your-project> with your actual Deno Deploy subdomain, and <your-username> with any GitHub username.






Or a custom hex: ?color=ff6b6b.
<!-- Unique visitors -->

<!-- Today's views, full number -->

<!-- Per-repo counter -->
| Endpoint | Description |
|---|---|
GET /badge/:user |
SVG badge |
GET /api/views/:user |
Current counts as JSON |
GET /api/stats/:user?days=7 |
Daily history (up to 30 days) |
GET /health |
Health check |
GET / |
Endpoint index |
| Param | Default | Options |
|---|---|---|
label |
Profile Views |
any string |
color |
blue |
blue green purple orange teal pink red or hex |
format |
short |
short (1.2K) or full (1,234) |
type |
total |
total unique daily |
counter |
(none) | any string — creates a separate sub-counter |
- No cookies. Ever.
- Hashed IPs — SHA-256 with a salt, truncated, never stored raw.
- Short TTLs — unique-visit markers expire after 24h, daily counters after 7 days, rate-limit windows after 1h.
- No personal data — nothing that could identify a visitor is persisted.
| Key | TTL | Value |
|---|---|---|
["views", scope] |
permanent | total view count |
["unique", scope] |
permanent | unique visitor count |
["daily", scope, "YYYY-MM-DD"] |
7 days | daily view count |
["uniq", scope, hashedIP] |
24h | unique-visit marker |
["rl", scope, hashedIP] |
1h | rate-limit counter |
scope is username by default, or username:counter when the counter param is set.
MIT