{"id":48976636,"url":"https://github.com/rajnishkmehta/gh-perma","last_synced_at":"2026-04-18T09:08:58.004Z","repository":{"id":333425766,"uuid":"1137257856","full_name":"RajnishKMehta/gh-perma","owner":"RajnishKMehta","description":"Permanent GitHub URLs powered by immutable user IDs. gh-perma generates stable links for GitHub profiles and repositories that continue to work even if usernames change. A lightweight, client-side GitHub ID resolver built for developers.","archived":false,"fork":false,"pushed_at":"2026-01-25T05:27:57.000Z","size":11,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-27T18:57:11.886Z","etag":null,"topics":["cloudflare-pages","developer-tools","gh-profile","github","github-api","infrastructure","permanent-links","permanent-profile-link","profile-link","url-resolver","vanilla-javascript"],"latest_commit_sha":null,"homepage":"https://gh-perma.pages.dev/dash","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RajnishKMehta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-19T06:11:18.000Z","updated_at":"2026-01-25T05:28:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/RajnishKMehta/gh-perma","commit_stats":null,"previous_names":["knarlix/gh-perma","rajnishkmehta/gh-perma"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/RajnishKMehta/gh-perma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RajnishKMehta%2Fgh-perma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RajnishKMehta%2Fgh-perma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RajnishKMehta%2Fgh-perma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RajnishKMehta%2Fgh-perma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RajnishKMehta","download_url":"https://codeload.github.com/RajnishKMehta/gh-perma/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RajnishKMehta%2Fgh-perma/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31962903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-pages","developer-tools","gh-profile","github","github-api","infrastructure","permanent-links","permanent-profile-link","profile-link","url-resolver","vanilla-javascript"],"created_at":"2026-04-18T09:08:41.662Z","updated_at":"2026-04-18T09:08:57.998Z","avatar_url":"https://github.com/RajnishKMehta.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gh-perma\n\nPermanent GitHub URLs powered by immutable user IDs.\n\n`gh-perma` solves a simple but real problem:  \nGitHub profile and repository URLs break when usernames change.  \nThis project provides a stable, ID-based resolver that always redirects to the current GitHub username.\n\n---\n\n## Why gh-perma?\n\nGitHub usernames are mutable.  \nGitHub user IDs are not.\n\n`gh-perma` uses this fact to generate **permanent GitHub links** that continue to work even if a user renames their account.\n\n---\n\n## Live instance\n\n**Dashboard:**  \nhttps://gh-perma.pages.dev/dash\n\n**Resolver:**  \nhttps://gh-perma.pages.dev\n\n---\n\n## How it works\n\n1. You enter a GitHub username or GitHub URL\n2. `gh-perma` fetches the immutable GitHub user ID\n3. A permanent URL is generated using that ID\n4. When opened, the resolver:\n   - Fetches the current username via GitHub API\n   - Redirects to the correct GitHub profile or repository path\n\nNo database.  \nNo authentication.  \nPure client-side + GitHub API.\n\n---\n\n## URL format\n\n### Profile\n`https://gh-perma.pages.dev?id=USER_ID`\n\n### Repository / path\n`https://gh-perma.pages.dev?id=USER_ID\u0026path=repo/tree/main`\n### Examples\n- [https://gh-perma.pages.dev?id=172272341](https://gh-perma.pages.dev?id=172272341)\n- [https://gh-perma.pages.dev?id=172272341\u0026path=Discord-Auth/tree/main](https://gh-perma.pages.dev?id=172272341\u0026path=Discord-Auth/tree/main)\n\n---\n\n## Dashboard usage\n\nYou can generate permanent URLs from the dashboard:\n\n- Username:\nknarliX\n- Username with path:\nknarliX/repo/blob/main/README.md\n- Full GitHub URL:\nhttps://github.com/KnarliX/repo\nAll formats are supported.\n\n---\n\n## Error handling\n\n- Invalid ID → shown immediately\n- User not found → clear error dialog\n- GitHub API rate limit → explicit warning\n- Network failure → graceful fallback\n\n---\n\n## Tech stack\n\n- HTML / CSS / Vanilla JavaScript\n- GitHub REST API\n- Cloudflare Pages\n\nNo frameworks.  \nNo build step.  \nMinimal surface area.\n\n---\n\n## Limitations\n\n- Depends on GitHub API availability\n- Subject to GitHub API rate limits (unauthenticated)\n- Not intended to be a canonical SEO URL\n\nThis is a **resolver**, not a replacement for GitHub URLs.\n\n---\n\n## Roadmap (optional, non-binding)\n\n- Clean path-based routing (`/{id}/{path}`)\n- Cloudflare pages\n\n---\n\n## License\n\nMIT License  \nYou are free to use, modify, and self-host.\n\n---\n\n## Author\n\nBuilt by **[Rajnish Mehta](https://gh-perma.pages.dev?id=172272341)**  \nFor developers who care about stable links.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frajnishkmehta%2Fgh-perma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frajnishkmehta%2Fgh-perma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frajnishkmehta%2Fgh-perma/lists"}