RX Portfolio
Config-driven dev project dashboard. Aggregates public signals from GitHub, npm, Docker Hub, and Chrome Web Store into an impact dashboard. Built with Astro 6, deployed to GitHub Pages. Clone-and-use.
About
Sourced from arikw/live-dev-portfolio README
A self-updating portfolio for developers who ship across more than one platform.
Drop in your handles. Get a dashboard with live stats from every platform your projects live on — refreshed automatically, deployed free on GitHub Pages, no backend.
Live demo: https://wzmn.net/projects · diff-layer preview
Why this exists
When you ship across more than one platform, no single page tells the whole story. Your GitHub profile only shows your repos. Your Chrome Web Store listing only shows one extension. Your npm page only shows your packages. None of them update themselves when the numbers shift.
This pulls every project — wherever it lives — onto one page that updates itself, so the impact numbers stay honest without you having to maintain anything.
Features
- ✅ All your projects in one place — live, retired, paid closed-source, and Wayback-archived entries for projects you've sold
- ✅ Live numbers — stars, downloads, weekly active users, install counts, ratings, refreshed nightly by a GitHub Actions cron
- ✅ Real banner art — actual icons, screenshots, and marquees from each project's store listing
- ✅ Filterable gallery — filter by source, tag, content language, status (Live / Retired / Updated since last visit); sort by Featured / Popularity / Year
- ✅ Deep-linkable filter state —
#source=chrome&tag=blocker&sort=yearis shareable and survives a refresh - ✅ "Since last visit" diff layer — NEW ribbons, per-card stat-move chips (
▲ +250 downloads), hero summary, one-click hide. State inlocalStorage, no backend - ✅ Profile cards — GitHub (public repos · ★ total · followers) and Stack Overflow (reputation · 🥇🥈🥉 badges)
- ✅ Hero stat tiles — sublabels enumerate only the sources that actually contributed (
cumulative install events across npm and Docker) - ✅ Stats as JSON —
/stats.jsonexposes the hero numbers (exactvalue+ ready-to-showdisplaylike1.2M+) for embedding on another site - ✅ Reviews carousel — auto-rotating testimonials from CWS, AppBrain, and manual entries
- ✅ Mobile-first responsive — tooltips clamp to viewport, dark + light mode (system + manual toggle), sticky scroll-aware header
- ✅ PWA-installable — sitemap, robots.txt, manifest, service worker
- ✅ Built-in media cache — every banner / icon / MP4 downloaded at build time so your dashboard survives upstream link rot
- ✅ Resilient — connectors degrade gracefully; a hiccup on one source never blanks the dashboard;
/status.jsonsurfaces what's broken - ✅ Auto-detected retirement — Play Store 404s and Chrome Web Store
isDeletedflags surface as retired-project state automatically
Setup (no terminal needed)
Everything below happens in the browser. No local clone, no Node, no terminal.
Fork — click Fork at the top of this page. GitHub creates a copy of the repo under your account.
Enable Actions on your fork — GitHub disables Actions on forks by default. On your fork, open the Actions tab and click "I understand my workflows, go ahead and enable them".
Run the Setup workflow — Actions → Setup (in the left sidebar) → Run workflow (button on the right). A form appears with optional fields:
- Site title — what shows in the browser tab / hero
- Tagline — short kicker above the hero
- About — longer intro paragraph (markdown OK)
- npm / Docker / Stack Overflow handles — your public usernames / numeric SO id
- Chrome extension ids — 32-char ids from
chromewebstore.google.com/detail/<id>URLs, comma-separated - Google Play packages —
com.you.app-style package names, comma-separated - GNOME extension ids — numeric ids from
extensions.gnome.org/extension/<id>/URLs, comma-separated - Default language —
en/he/ blank for "All" - Favicon shape —
auto/rounded/square
Fill what's relevant, leave the rest empty, click Run workflow.
Done. The Setup workflow generates
projects.config.local.tsfor you, enables GitHub Pages withbuild_type=workflow, and commits the result. The regular Deploy workflow fires automatically on that commit and publishes your site tohttps://<your-user>.github.io/<your-fork>/within ~1 minute.
To re-configure later (new handles, more sources): Actions → Setup → Run workflow with the new values. Each run overwrites projects.config.local.ts cleanly, so it's safe to use as a regenerator.
Custom domain or sub-path? Edit deployment.site and deployment.base in the generated projects.config.local.ts from the GitHub web editor (press . on the file, or click the pencil) — the base prefix carries through every internal link and canonical tag, so you can also proxy GitHub Pages from a sub-path on an existing site.
Setup (locally, optional)
If you'd rather work locally — to tweak styles, write detail pages, add a new connector, etc.:
git clone https://github.com/<your-user>/<your-fork>.git
cd <your-fork>
npm install
npm run init # auto-detects your GitHub handle from your git remote
npm run dev # → http://localhost:4321/
init reads your git remote and pre-fills projects.config.local.ts with sensible defaults. The first dev view is empty by design — drop your real handles (npm, Docker, Chrome extension IDs, Play package names) into the generated file and refresh. The first full build with real handles takes a few minutes (every connector fetches fresh + every banner/icon gets cached); subsequent builds reuse the on-disk cache and run in seconds.
Built-in sources
| Origin platform | Mirror sources | Adds to |
|---|---|---|
| GitHub | (self) | stars, forks, archived flag, repo metadata, Pages favicon, profile card (public repos · followers · ★ total) |
| npm | (self) | weekly + lifetime downloads, README, version |
| Docker Hub | (self) | pulls, stars |
| Chrome Web Store | chromestats, extpose |
banner / icon, weekly active users, rating, reviews, delisted detection |
| Google Play | appbrain, apkpure |
install tier, rating + histogram, banner / screenshots, 404-detected retirement |
| GNOME Extensions | (self) | downloads, version compatibility |
| Stack Overflow | (self) | profile card (reputation · 🥇🥈🥉 badges) |
Each source with a mirror has a fallback chain, so an API hiccup or an anti-bot gate on one source never blanks the dashboard. A manual connector handles closed-source projects, retired listings, Wayback snapshots, and authoritative overrides — see docs/skills/add-manual-entry.md.
Want to add a new source? Connectors auto-discover — one new folder under src/connectors/ is all it takes. See docs/connectors.md for the manifest pattern.
Customising
projects.config.ts— committed defaults. Edit when changes should ship to upstream cloners.projects.config.local.ts— your private overrides (real handles, manual entries, featured pins, language preference). Shallow-merged over the base config at build time. Not in the committed.gitignore, so you can choose to commit yours or keep it untracked via.git/info/exclude.src/themes/<name>/— your own look. Setui: { theme: '<name>' }and the folder'stheme.css,Header.astro,Head.astroandFooter.astroreplace the default theme's; anything missing falls back tosrc/themes/default/. Seesrc/themes/README.md.src/content/projects/<slug>.mdx— optional rich detail page per project. Slug matches the project id. A "Details →" link surfaces on the matching card.thumbFit: 'contain'+thumbBg: '<colour>'on a manual entry letterboxes screenshots that don't crop nicely (J2ME phone art, retro-resolution captures, anything with built-in padding).- Media cache is on by default — every banner, icon and MP4 a connector references is downloaded into
public/_cache/<connector>/<hash>.<ext>so the deployed dashboard survives upstream link rot. Toggle off viamedia: { cache: false }.
Health check
npm run status
Hits your deployed /status.json and prints a human-readable summary. Exit 0 when clean, exit 1 when something needs attention — usable in CI / pre-deploy hooks.
Example output when something's off:
✗ Status: NEEDS ATTENTION https://yoursite.example/status.json
↳ Partial coverage (1):
• chromestats: 4/6 extension ids missing
↳ Hidden projects (1):
• jdmiahadpnljimfcnfaebjggbfkjkgan
no friendly title — connector enrichment data missing
Fix: npm run seed
When it flags trouble, one command takes care of it:
npm run seed
Builds locally (residential IPs aren't gated the way some hosted CI runners are), commits the refreshed caches, pushes, and dispatches the deploy. Falls back to printed manual instructions when gh isn't installed or authenticated.
FAQ
What if I don't have projects on a particular platform?
Leave it empty. Connectors with no configured input return nothing and just don't contribute to the dashboard — no errors, no broken UI. A platform with no projects gets no chip, no badge, no source filter entry.
Can I add my own data source?
Yes. Create a new folder under src/connectors/<your-key>/ with an index.ts that export default defineConnector(…). The registry auto-discovers it at build time — no central list to update. See docs/connectors.md for the manifest pattern.
Why is my deploy showing partial data?
Some sources (chrome-stats.com, AppBrain) sit behind Cloudflare and gate datacenter IPs (which includes GitHub Actions runners). Run npm run status from anywhere to diagnose. If it reports partial coverage, run npm run seed from your own machine — residential IPs pass cleanly, the populated cache gets committed, and the next deploy serves the fresh data.
How do I add a project I've sold or that's been retired?
Use a manual entry in projects.config.local.ts. For retired projects, you can point the entry at a Wayback snapshot of the original listing — see docs/skills/add-manual-entry.md. The dashboard preserves historical numbers (peak users, lifetime downloads, ratings) and surfaces them in the Retired filter with a clock+user icon for the past-users badge.
Does it work with a custom domain?
Yes. Set deployment.site to your custom domain and deployment.base to your sub-path (or /). The base carries through every internal link and canonical tag, so you can also proxy GitHub Pages from a sub-path on an existing site (e.g. https://yourdomain.com/projects/).
Can I use this commercially?
No, not under the bundled license. PolyForm Noncommercial 1.0.0 covers personal projects, learning, and evaluation — anything noncommercial. Commercial use (selling, hosted services, paid products, for-profit internal tooling) requires a separate license. Open an issue to discuss.
What's the difference between projects.config.ts and projects.config.local.ts?
projects.config.ts ships the committed defaults — what every cloner sees. projects.config.local.ts shallow-merges your private overrides on top of it at build time (your real handles, manual entries, featured pins, language preference). The local file is excluded from your clone via .git/info/exclude so it stays untracked without polluting the committed .gitignore.
AI-friendly by design
The docs/skills/ folder ships short, agent-readable walkthroughs (each with YAML frontmatter) — a prompt like "add my new Chrome extension as a manual entry" drops the assistant straight into the right file.
Docs
docs/connectors.md— adding a new connectordocs/skills/add-manual-entry.md— manual entry shapes (ManualProject,ManualOrigin)docs/skills/cache-media.md— build-time media cache, URL map shape, YouTube→MP4 transcoding
Architecture
Astro 6 static site generator. Connectors live in src/connectors/<key>/index.ts, each export default defineConnector(…). Auto-discovered by the registry at build time — no central list to update. Connectors fetch in parallel, normalise into ConnectorResults, then src/lib/build-projects.ts merges + dedupes + reconciles them into final Projects (origin-wins → freshest-asOf → greatest-magnitude). Render is pure SSR; the only client-side JS is filter wiring + the "since last visit" diff layer (localStorage-backed, no backend).
Higher GitHub API rate limit (optional)
The workflow uses the auto-injected GITHUB_TOKEN by default — 1,000 requests/hour, enough for typical accounts. If you have a large account or hit rate limits, create a personal access token with public_repo read access and add it as a repo secret named GH_API_TOKEN. The workflow prefers it over the auto-injected token when present (bumps to 5,000 req/hr).
Rebuild another site after each deploy (optional)
If another site pulls this dashboard in at its own build time (e.g. a Cloudflare Pages or Netlify site that clones this repo into a sub-path), add that site's deploy-hook URL as a repo secret named POST_DEPLOY_HOOK. After every deploy — pushes and the daily refresh — the workflow POSTs to it, so the other site rebuilds with the latest data right away. Unset, the step is skipped.
Commands
npm run dev # local dev server → http://localhost:4321/
npm run build # → dist/ + generated/snapshot.json
npm run preview # serve dist/ locally
npm run init # scaffold projects.config.local.ts from your git remote
npm run status # health-check the deployed dashboard
npm run seed # local-scrape → commit caches → push → dispatch deploy
Credits
Built with Astro. Stat icons are Material Icons. Brand marks (Chrome / npm / Docker / GitHub / GNOME / Stack Overflow / Play / AppBrain) are the trademarks of their respective owners.
License
PolyForm Noncommercial 1.0.0 — free for personal projects, learning, evaluation, and any other noncommercial purpose. Commercial use (selling, hosted services, paid products, for-profit internal tooling) requires a separate license — open an issue to discuss. Forks must keep the LICENSE file and the Required Notice: Copyright Arik W. line intact.
More projects
See all →2020
Extension Page Context Runner
Run functions in page context directly from a browser extension content script
27
2020
Outlook Duplicated Items Remover
A VBA script that finds and moves duplicated items in selected outlook folders
21
2023
RX Input Layout Switcher
Alt+Shift keyboard layout switcher GNOME Shell Extension
16 9.6K
2025
Podman OpenRC Restart Policy Manager
This OpenRC init script manages the automatic startup and shutdown of Podman containers with the `restart-policy=always` on system boot or shutdown
5
2022
Express Response Hooks
Extends Express.js with response hooks
4 149.3K 5.5K/mo
2021
Kids Keyboard Game
Kids Keyboard Game
3