{"id":24404129,"url":"https://github.com/bjornmelin/stardex","last_synced_at":"2026-04-28T12:38:50.318Z","repository":{"id":272530645,"uuid":"916908682","full_name":"BjornMelin/stardex","owner":"BjornMelin","description":"🌟 Stardex: Explore GitHub Stars Intelligently. Stardex is a powerful web app that lets you search, filter, and cluster any GitHub user's starred repositories. Discover hidden patterns and find your next favorite project with intelligent, AI-powered exploration.","archived":false,"fork":false,"pushed_at":"2025-01-26T02:26:59.000Z","size":248,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-26T02:28:04.303Z","etag":null,"topics":["clustering","ml","nextjs","search-engine","shadcn-ui","starred-repositories","tailwindcss","tensorflow"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/BjornMelin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2025-01-15T01:34:45.000Z","updated_at":"2025-01-26T02:18:29.000Z","dependencies_parsed_at":"2025-01-15T03:14:58.733Z","dependency_job_id":"157e7ad4-e1b0-4018-8c89-e3e3cdf8d710","html_url":"https://github.com/BjornMelin/stardex","commit_stats":null,"previous_names":["bjornmelin/stardex"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BjornMelin%2Fstardex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BjornMelin%2Fstardex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BjornMelin%2Fstardex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BjornMelin%2Fstardex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BjornMelin","download_url":"https://codeload.github.com/BjornMelin/stardex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243364868,"owners_count":20279211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["clustering","ml","nextjs","search-engine","shadcn-ui","starred-repositories","tailwindcss","tensorflow"],"created_at":"2025-01-20T03:59:47.844Z","updated_at":"2026-04-28T12:38:50.313Z","avatar_url":"https://github.com/BjornMelin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⭐ Stardex - Explore GitHub Stars Intelligently\n\nUnderstand your GitHub stars faster: fetch stars from one or more users, filter what you care about, then cluster repos by description similarity.\n\n[![Next.js](https://img.shields.io/badge/Next.js-16.1-black?style=flat-square\u0026logo=next.js)](https://nextjs.org/)\n[![FastAPI](https://img.shields.io/badge/FastAPI-0.128-009688?style=flat-square\u0026logo=fastapi)](https://fastapi.tiangolo.com/)\n[![scikit-learn](https://img.shields.io/badge/scikit--learn-1.8-F7931E?style=flat-square\u0026logo=scikit-learn)](https://scikit-learn.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat-square\u0026logo=typescript)](https://www.typescriptlang.org/)\n[![Python](https://img.shields.io/badge/Python-3.13-3776AB?style=flat-square\u0026logo=python)](https://www.python.org/)\n[![TailwindCSS](https://img.shields.io/badge/Tailwind-4.1-38B2AC?logo=tailwind-css)](https://tailwindcss.com)\n[![GitHub](https://img.shields.io/badge/GitHub-BjornMelin-181717?logo=github)](https://github.com/BjornMelin)\n[![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/)\n[![React](https://img.shields.io/badge/React-19.2-blue?logo=react)](https://react.dev)\n\n## Table of Contents\n\n- [Features](#features)\n- [Technology Stack](#technology-stack)\n- [How It Works](#how-it-works)\n- [Architecture](#architecture)\n- [Getting Started](#getting-started)\n- [Configuration](#configuration)\n- [API Reference](#api-reference)\n- [Development](#development)\n- [Author](#author)\n- [How to Cite](#how-to-cite)\n- [License](#license)\n\n## Features\n\n- Search GitHub users and pull their starred repositories (supports multiple users).\n- Explore in a list view with search, language filtering, topic filtering, minimum stars, and sorting.\n- Cluster repositories by description similarity using K-means, hierarchical clustering, or PCA + hierarchical clustering.\n- Tune clustering parameters from the UI and switch between algorithms.\n- Strong input validation in the backend (clear errors and safe limits).\n\n## Technology Stack\n\n- **Frontend**\n  - Next.js (App Router) + React + TypeScript\n  - TanStack Query for data fetching/caching\n  - Zustand for client state\n  - shadcn/ui-style components (Radix primitives + Tailwind)\n  - Tailwind CSS\n  - Zod for client-side validation\n\n- **Backend**\n  - FastAPI + Pydantic (Python 3.11+)\n  - scikit-learn (TF-IDF, K-means, PCA)\n  - SciPy hierarchical clustering (scikit-learn uses SciPy for hierarchical clustering)\n  - uv for dependency management\n  - Ruff + Pyright + pytest for quality gates\n\n## How It Works\n\n1. The frontend calls the GitHub REST API to fetch starred repositories for selected users.\n2. The frontend sends repository metadata to the backend clustering API.\n3. The backend vectorizes repository text (description/name) using TF-IDF and runs one or more clustering algorithms.\n4. The frontend renders clusters and lets you filter/search within the results.\n\n## Architecture\n\nThis repo is a monorepo with two services:\n\n- `frontend/`: Next.js app (App Router).\n- `backend/`: FastAPI service exposing the clustering API.\n\nData flow:\n\n- Browser -\u003e GitHub REST API (`/search/users`, `/users/:user/starred`)\n- Browser -\u003e Backend (`POST /clustering`)\n\n## Getting Started\n\n### Prerequisites\n\n- Node.js (LTS) + `pnpm`\n- Python 3.11+ + `uv`\n\n### Install\n\n```bash\npnpm install\n(cd backend \u0026\u0026 uv sync)\n```\n\n### Run (recommended)\n\n```bash\npnpm dev\n```\n\n### Run services separately\n\n```bash\npnpm dev:frontend\npnpm dev:backend\n```\n\nOpen the app at `http://localhost:3000`.\n\n## Configuration\n\n### Frontend\n\nCreate `frontend/.env.local`:\n\n```bash\nNEXT_PUBLIC_API_URL=http://localhost:8000\n```\n\n### Backend\n\n- `CORS_ORIGINS`: comma-separated list of allowed origins. Default: `http://localhost:3000`.\n- `UVICORN_HOST`: default `127.0.0.1` (only used when running `python app/main.py` directly).\n- `UVICORN_PORT`: default `8000` (only used when running `python app/main.py` directly).\n\n## API Reference\n\n### POST /clustering\n\nRuns clustering algorithms over repository descriptions/names. The backend validates and enforces limits:\n\n- `repositories`: 2..250 items\n- `kmeans_clusters`: 2..20 (and must be \u003c= number of repos)\n- `hierarchical_threshold`: (0, 10]\n- `pca_components`: 2..50 (and must be \u003c= number of repos and TF-IDF dimensions)\n\n\u003cdetails\u003e\n\u003csummary\u003eRequest Body\u003c/summary\u003e\n\n```json\n{\n  \"repositories\": [\n    {\n      \"id\": number,\n      \"name\": string,\n      \"full_name\": string,\n      \"description\": string | null,\n      \"html_url\": string,\n      \"stargazers_count\": number,\n      \"forks_count\": number,\n      \"open_issues_count\": number,\n      \"size\": number,\n      \"watchers_count\": number,\n      \"language\": string | null,\n      \"topics\": string[],\n      \"owner\": {\n        \"login\": string,\n        \"avatar_url\": string\n      },\n      \"updated_at\": string\n    }\n  ],\n  \"kmeans_clusters\": number,\n  \"hierarchical_threshold\": number,\n  \"pca_components\": number\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eResponse\u003c/summary\u003e\n\n```json\n{\n  \"status\": \"success\",\n  \"kmeans_clusters\": {\n    \"algorithm\": \"kmeans\",\n    \"clusters\": { \"0\": [0, 2, 4], \"1\": [1, 3, 5] },\n    \"parameters\": { \"num_clusters\": 2 },\n    \"processing_time_ms\": 150.5\n  },\n  \"hierarchical_clusters\": {\n    \"algorithm\": \"hierarchical\",\n    \"clusters\": { \"1\": [0, 2], \"2\": [1, 3], \"3\": [4, 5] },\n    \"parameters\": { \"distance_threshold\": 1.5 },\n    \"processing_time_ms\": 200.3\n  },\n  \"pca_hierarchical_clusters\": {\n    \"algorithm\": \"pca_hierarchical\",\n    \"clusters\": { \"1\": [0, 2, 4], \"2\": [1, 3, 5] },\n    \"parameters\": { \"n_components\": 10, \"distance_threshold\": 1.5 },\n    \"processing_time_ms\": 180.7\n  },\n  \"total_processing_time_ms\": 531.5\n}\n```\n\n\u003c/details\u003e\n\n### GET /health\n\nHealth check endpoint.\n\n```json\n{\n  \"status\": \"healthy\",\n  \"timestamp\": 1730000000.0,\n  \"clustering_service\": \"available\"\n}\n```\n\n## Development\n\nRun from repo root:\n\n```bash\npnpm lint\npnpm biome\npnpm typecheck\npnpm test\npnpm build\n```\n\nBackend-only (from `backend/`):\n\n```bash\nuv run ruff format\nuv run ruff check\nuv run pyright\nuv run python -m pytest\n```\n\nNotes:\n\n- The frontend uses the public GitHub API from the browser. If you hit rate limits, wait for the reset time and retry.\n\n## Author\n\n### Bjorn Melin\n\n- GitHub: [@BjornMelin](https://github.com/BjornMelin)\n- Website: [bjornmelin.io](https://bjornmelin.io)\n- LinkedIn: [@bjorn-melin](https://www.linkedin.com/in/bjorn-melin/)\n\n## How to Cite\n\nIf you use Stardex in your research or project, please cite it as follows:\n\n```bibtex\n@software{melin2024stardex,\n  author = {Melin, Bjorn},\n  title = {Stardex: GitHub Stars Explorer},\n  year = {2025},\n  publisher = {GitHub},\n  url = {https://github.com/BjornMelin/stardex},\n  version = {0.1.0},\n  description = {Explore and cluster GitHub starred repositories using a Next.js UI and a FastAPI clustering service}\n}\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n---\n\n\u003cp align=\"center\"\u003e\nBuilt by [Bjorn Melin](https://bjornmelin.io)\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjornmelin%2Fstardex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbjornmelin%2Fstardex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjornmelin%2Fstardex/lists"}