neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
GitAll lets you see GitHub, GitLab, Bitbucket, and Gitea/Forgejo contribution graphs in one unified heatmap. Supports 4 platforms. Free, no login required.
Developer toolsTypeScript · HTMLGitHub @Toastbyte-StudiosOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Contribution heatmaps from GitHub, GitLab, Bitbucket, and Gitea/Forgejo in one view — plus embeddable SVGs for your README.
Taken from the repository README
Loading the full README.
Read the full README ↗One contribution graph for every account you code under.
GitAll reads contribution calendars from GitHub, GitLab, Bitbucket, and Gitea/Forgejo and shows them side by side — or merged into a single heatmap.
gitall.app · Embeds · Self-hosting · API
If your work is split across a day-job GitLab, a personal GitHub, a client's Bitbucket, and a Codeberg mirror, no single profile page tells the truth about what you actually shipped. GitAll puts those calendars in one place without asking you to move anything.
No account is required. Type in usernames and look.
| Platform | Source | Auth required |
|---|---|---|
| GitHub | GraphQL contributionsCollection | Server-side token (see Configuration) |
| GitLab | Public REST calendar endpoint | No |
| Bitbucket | Public REST API, aggregated | No |
| Gitea / Forgejo | /api/v1/users/{username}/heatmap | No |
Gitea/Forgejo defaults to Codeberg, with gitea.com as a second preset and any self-hosted instance URL accepted.
[!NOTE] GitLab's public calendar endpoint only exposes roughly the last 12 months, so longer or older custom ranges will be truncated on the GitLab side.
?period=, ?from=, ?to=)./u/{handle} once you've verified an account.Any heatmap can be served as a standalone SVG, sized to fit a README:

With no query parameters, the path segment is treated as a GitHub username. To merge several platforms, pass them explicitly:

[!IMPORTANT] As soon as any platform parameter is present, the path segment becomes a cosmetic slug only — it no longer implies a GitHub lookup. Pass
?github=explicitly if you want GitHub included.
| Parameter | Description |
|---|---|
github | GitHub username |
gitlab | GitLab username |
bitbucket | Bitbucket username |
gitea | Gitea/Forgejo username |
instance | Gitea/Forgejo instance URL (defaults to https://codeberg.org) |
theme | auto (default), light, or dark |
auto ships both palettes inside one SVG and switches between them with a prefers-color-scheme media query, so the same URL reads correctly on a white page and a dark one. Leaving the parameter off is the same as auto.
One caveat worth knowing before you pin anything: this follows the reader's operating system, not the theme of the page doing the embedding. GitHub's theme is an account setting, so somebody browsing GitHub in light mode on a dark-mode machine will still get the dark palette. theme=light and theme=dark exist for exactly that case.
The .svg extension is optional. The image covers the last 12 months, is cached at the edge for 24 hours, and serves stale content for up to an hour while revalidating. If one platform is slow or unreachable it is dropped from the merge rather than holding up the response — GitHub's image proxy gives up quickly.
Signing in creates a profile at gitall.app/u/{handle} that renders your verified accounts together. Handles are derived from your provider username on first sign-in and can be changed once every seven days. They are 2–32 characters of a-z, 0-9, and -, with no leading, trailing, or repeated dashes.
Profiles require Cloudflare D1. On a self-hosted deployment without a D1 binding, profile reads and writes are skipped and the rest of the app works normally.
Signing in is optional and unlocks three things: time-range filters, a public profile, and — for GitHub — lookups against your own API rate limit that include your private contributions when you look yourself up.
GitHub, GitLab, and Bitbucket can all be connected to the same session, so one profile can span all three.
On session storage: OAuth is implemented directly rather than through a library. Session metadata and access tokens are AES-GCM encrypted into separate httpOnly cookies, so they are never readable from client-side JavaScript. Tokens live in their own per-provider cookie to stay under the 4 KB per-cookie limit. If your threat model includes cookie theft, swap this for an opaque session ID with server-side token storage.
Requires Node.js 20.9 or newer.
git clone https://github.com/Toastbyte-Studios/git-all.git
cd git-all
npm install
cp .env.example .env.local
Add a GITHUB_TOKEN to .env.local, then:
npm run dev
Open http://localhost:3000.
A GitHub personal access token is the only hard requirement — GitHub's GraphQL API rejects unauthenticated requests even for public data. A classic token with no scopes selected is enough. The other three platforms need nothing.
All of these live in .env.local for local development. In production they are Worker secrets (wrangler secret put <NAME>).
| Variable | Required | Purpose |
|---|---|---|
GITHUB_TOKEN | Yes | GitHub GraphQL access. No scopes needed. |
SESSION_SECRET | For sign-in | 32+ random bytes; encrypts session cookies. |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | For sign-in | GitHub OAuth App. |
GITLAB_CLIENT_ID / GITLAB_CLIENT_SECRET | For sign-in | GitLab application, read_user scope. |
BITBUCKET_CLIENT_KEY / BITBUCKET_CLIENT_SECRET | For sign-in | Bitbucket OAuth consumer, account scope. |
NEXT_PUBLIC_CF_WEB_ANALYTICS_TOKEN | No | Cloudflare Web Analytics beacon. |
ANALYTICS_GA4_MEASUREMENT_ID / ANALYTICS_GA4_API_SECRET | No | GA4 Measurement Protocol for server-side events. |
NEXT_PUBLIC_ANALYTICS_REQUIRE_CONSENT | No | Set to 1 to gate client-side events on consent. |
Register these with each provider, substituting your own origin in production:
| Provider | Callback URL | Scope |
|---|---|---|
| GitHub | http://localhost:3000/api/auth/callback/github | — |
| GitLab | http://localhost:3000/api/auth/callback/gitlab | read_user |
| Bitbucket | http://localhost:3000/api/auth/callback/bitbucket | account |
Profiles are stored in D1. It is only bound under wrangler dev or in a deployed Worker — plain next dev runs without it and logs a warning instead of failing.
wrangler d1 create gitall # then paste database_id into wrangler.jsonc
npm run db:migrate:local # local
npm run db:migrate:remote # production
npm run db:reset:local # wipe and re-apply locally
All optional, and the app runs fine with none of it configured. Cloudflare Web Analytics provides a cookieless baseline. Product events go through Zaraz when available and fall back to a first-party POST /api/analytics/event when it is blocked; a few high-value events are sent server-side via the GA4 Measurement Protocol, with the client ID derived from a hash of IP, user agent, and language rather than a cookie.
Embed impressions with a same-host referer are not counted — those come from the preview in the embed generator rather than a real embed.
If you set NEXT_PUBLIC_CF_WEB_ANALYTICS_TOKEN, allow https://static.cloudflareinsights.com in your script-src CSP directive.
Each platform has a route that normalises its upstream response to a shared shape.
GET /api/github?username=octocat&from=2025-01-01&to=2025-12-31
GET /api/gitlab?username=octocat
GET /api/bitbucket?username=octocat
GET /api/gitea?username=octocat&instanceUrl=https://codeberg.org
from and to are optional and default to the last 12 months. GitHub lookups can span at most one year. Adding refresh=true bypasses the cache.
{
"platform": "github",
"username": "octocat",
"totalContributions": 1234,
"dateRange": { "from": "2025-01-01", "to": "2025-12-31" },
"calendar": [{ "date": "2025-01-01", "count": 3, "level": 1 }]
}
level is a 0–4 intensity bucket. GitHub responses carry an X-Cache header of HIT, MISS, or BYPASS.
npm run dev # dev server on :3000
npm run build # production build
npm run test # Vitest, single run
npm run test:watch # Vitest, watch mode
npm run test:coverage # coverage report
npm run lint # ESLint
npm run format # Prettier
npm run cleanup # format + lint + test
Run one test file with npx vitest run src/lib/__tests__/auth-session.test.ts.
The app is a Next.js 15 App Router project built for Cloudflare Workers through @opennextjs/cloudflare.
npm run cf:build # build the Worker bundle
npm run cf:preview # build, then run locally under wrangler
npm run cf:deploy # build and deploy
main deploys automatically via the Deploy workflow.
[!WARNING] Cloudflare Bot Fight Mode must stay off on any zone serving
/embed/*. GitHub's camo image proxy cannot run JavaScript and so cannot pass the challenge, which silently breaks every embedded heatmap already in the wild. Rate limiting rules scoped to/embed/*are the supported alternative.
src/
app/
api/{github,gitlab,bitbucket,gitea}/ contribution routes
api/auth/ OAuth, session, connections
api/profile/ handle management
embed/[slug]/ SVG heatmap endpoint
u/[handle]/ public profiles
whoami/ your connected identities
components/ UI
lib/ data fetching, session, SVG, types
migrations/ D1 schema
The @ import alias maps to src/.
Issues and pull requests are welcome. Two things to know before you open a PR:
npm run cleanup — CI runs the same checks.version in package.json following semver. A workflow fails the PR if the version matches main.GNU Affero General Public License v3.0 — Copyright © 2026 Toastbyte Studios.
Use it, modify it, self-host it. The one condition worth knowing up front: if you run a modified version as a network service, section 13 requires you to offer your users the source of that modified version.