Flow: When adding or updating version sources for a stack:
- First try GitHub – Check if the project has GitHub Releases. Prefer Releases over tags. Use
githubRepoandversionRepowhen the version comes from GitHub. - If no GitHub Releases – Search for official version info on the web (e.g. endoflife.date, project websites, package registries). Add a custom
versionSourcefetcher infetchVersion.tsand setversionUrlto the official version/release page.
Version link icon: Use TagIcon in icons.tsx for the version link on stack cards. Same icon for all (GitHub Releases, endoflife.date, etc.).
Helpers in fetchVersion.ts:
fetchNpmVersion(packageName)– for npm packages (e.g. @builder.io/qwik)fetchWithCorsProxy(url, parse)– when CORS blocks direct fetch (e.g. endoflife.date, adoptium.net)fetchVersionFromTags(owner, repo)– when a repo uses tags only, not Releases
CORS: Some APIs (endoflife.date, adoptium) block browser requests. Use fetchWithCorsProxy with fallback proxies.
Protocols & Standards: The protocols category (HTTP, TLS, OAuth/OpenID Connect, JSON Schema) uses custom fetchers. Some return static versions (HTTP→3, TLS→1.3, OAuth→2.1) when no public API exists; JSON Schema uses fetchNpmVersion('json-schema').
- Use React 19 with functional components and hooks (e.g.
useState). - Prefer
rem,em, or viewport units (vw,vh,vmin,vmax) for measurements; usepxonly as a last resort. - Use Tailwind CSS for layout and utilities; keep custom CSS in
src/App.cssandsrc/index.csswhere needed. - Use custom SVG icons in
src/components/icons.tsx(GitHubIcon, SunIcon, MoonIcon, TagIcon, StarIcon). - Stack logos: use
iconSlugfor Simple Icons CDN (cdn.jsdelivr.net/npm/simple-icons). - Prefer small, focused components and small diffs.
- Reuse existing patterns (e.g. section config in
App.tsx, hooks insrc/hooks/).
- Do not hard-code colors; use Tailwind tokens (e.g.
slate-900,amber-500) or CSS variables already used in the app. - Do not add new heavy dependencies without approval.
- Do not introduce class components; keep everything function components with hooks.
# development
npm run dev
# build
npm run build
# lint
npm run lint
# preview (production build locally)
npm run previewDeploy: GitHub Actions deploys to GitHub Pages on push to main (.github/workflows/deploy.yml). Requires VITE_GITHUB_TOKEN secret for higher GitHub API rate limits.
Allowed without prompt:
- Read files, list files.
- Run build, run lint.
- Edit existing files and add new files in
src/andpublic/. - Fetch data from the web
Ask first:
npm install/ adding or changing dependencies.git push,npm run deploy.- Deleting files, changing permissions.
- Large refactors or changing project structure.
- Entry:
index.html→ loadssrc/main.tsx→ mountsAppinto#root - Main UI:
src/App.tsx– stack version dashboard with category sections, favorites, theme toggle - Components:
src/components/– StackCard, StackSection, icons - Data:
src/data/stacks.ts– STACK_DEFINITIONS, CATEGORY_ORDER, CATEGORY_LABELS, CATEGORY_COLORS (categories include language, frontend, backend, protocols, etc.) - Version fetching:
src/lib/fetchVersion.ts(fetchers),src/lib/fetchVersions.ts(orchestration, VERSION_FETCHERS map) - Hooks:
src/hooks/– useTheme, useFavorites, useInitialVisibleCount - Types:
src/types/stack.ts– Stack, StackCategory - Styles:
src/App.css,src/index.css(Tailwind in index.css) - Assets:
public/lightning.svg,index.htmlat repo root
Data flow:
STACK_DEFINITIONS (stacks.ts)
↓
App.tsx: fetchVersionsForStacks() per category (sequential) → versions Map<id, version>
↓
stacks = STACK_DEFINITIONS + latestVersion + isFavorite
↓
stacksByCategory (grouped by category) + favoriteStacks
↓
StackSection (per category) → StackCard (per stack)
Component hierarchy:
App
├── header (title, GitHub link, theme toggle)
├── main
│ ├── [Expand all] [Clear favorites] (conditional)
│ ├── StackSection (favorites) – if any favorites
│ └── StackSection (per category) – language, frontend, backend, etc.
│ └── StackCard (per stack)
│ ├── stretched link → stack.url
│ ├── logo/initial + name + version
│ ├── TagIcon link → version page (versionUrl or github releases)
│ └── StarIcon → toggle favorite
└── footer
Version fetching flow:
getInitialVersionState()– sync: reads localStorage cache for instant display- Categories fetched sequentially in CATEGORY_ORDER; each category shows "Loading..." while fetching
fetchVersionsForStacks(stacks)– fetches for a subset; merge into versions; save cache- Per stack:
versionSource→VERSION_FETCHERS[versionSource](); elsegithubRepo/versionRepo→fetchVersion()(GitHub Releases)
Adding a new stack:
- Add entry to
STACK_DEFINITIONSinstacks.ts(id, name, category, url, iconSlug, githubRepo/versionSource/versionUrl) - If custom version source: add fetcher in
fetchVersion.tsand entry inVERSION_FETCHERSinfetchVersions.ts+ add toversionSourceunion instack.ts - For protocols/standards with no public API: fetcher can return a static version (e.g.
return '1.3'for TLS)
StackCarduses stretched-link pattern: anchor covers whole card; content haspointer-events-none; tag icon and star havepointer-events-autoso they stay clickable.logoon Stack is deprecated; useiconSlugfor Simple Icons CDN. Fallback: first letter of name.
- Good: Functional component with hooks like
App.tsx(e.g.useStatefor versions,expandAll). - Bad: Class components, inline styles for colors that could use Tailwind or existing CSS variables.
- Icons: Use SVG components from
icons.tsx; avoid adding new icon libraries.
- Lint and build pass (
npm run lint,npm run build). - Add or update tests for new behaviour where relevant.
- Keep the diff small with a short summary.
- Ask a clarifying question, propose a short plan, or open a draft PR with notes.
- For new features, write or update tests first, then implement until tests pass.