StackPulse crawls a rolling sample of public JavaScript and TypeScript repositories on GitHub and tracks which frameworks, databases, ORMs, and tools are actually used together, and how that adoption shifts over time. Every number is generated by a daily pipeline and backed by an open dataset you can inspect yourself.
See the codeTHE JAVASCRIPT ECOSYSTEM | OBSERVED DAILY
StackPulse crawls a rolling sample of public JavaScript and TypeScript repositories on GitHub and tracks which frameworks, databases, ORMs, and tools are actually used together, and how that adoption shifts over time. Every number below is generated by a daily pipeline and backed by an open dataset you can inspect yourself.
| Technology | Adoption | Trend Score |
|---|---|---|
| TypeScript | 76.4% | ▲ +4.17 |
| React | 34.9% | ▲ +3.77 |
| Vitest | 24.1% | ▲ +3.80 |
| Vite | 19.7% | ▲ +3.79 |
| Jest | 18.0% | ▲ +3.13 |
| Tailwind CSS | 14.7% | ▲ +3.56 |
| Babel | 14.2% | ▲ +2.94 |
| rimraf | 14.1% | ▲ +2.95 |
| Mocha | 13.7% | ▲ +2.91 |
| Webpack | 12.8% | ▲ +2.90 |
Trend Score is a log-scaled growth index: (current adoption / prior adoption) × log10(current adoption + 10), weighted so both the rate of change and the technology's overall scale matter.
| Rank | Technology | Category | Weekly Change |
|---|---|---|---|
| 1 | Rspack | BuildTools | ▲ +16.7% |
| 2 | Kysely | ORMs | ▲ +16.7% |
| 3 | Drizzle ORM | ORMs | ▲ +9.3% |
| 4 | Better SQLite3 | Databases | ▲ +7.2% |
| 5 | Supabase | Databases | ▲ +7% |
| 6 | Fastify | Frameworks | ▲ +6.9% |
| 7 | Framer Motion | UILibraries | ▲ +6% |
| 8 | Zustand | StateManagement | ▲ +5.8% |
| 9 | SvelteKit | Frameworks | ▲ +5.6% |
| 10 | Clerk (Next.js) | Authentication | ▲ +5.6% |
| Name | 30-Day Trend |
|---|---|
| Parcel | -5.3% |
| Category | Top Technology |
|---|---|
| Authentication | CORS |
| BuildTools | TypeScript |
| Databases | Better SQLite3 |
| Frameworks | React |
| ORMs | Drizzle ORM |
| StateManagement | Zustand |
| Testing | Vitest |
| UILibraries | Tailwind CSS |
| Validation | Zod |
| Tech A | Tech B | Strength Score |
|---|---|---|
| cva | tailwind-merge | 0.76 |
| clsx | tailwind-merge | 0.75 |
| testing-library-react | testing-library-jest-dom | 0.66 |
| react-redux | redux | 0.65 |
| cva | clsx | 0.62 |
| cva | lucide-react | 0.57 |
| lucide-react | tailwind-merge | 0.57 |
| mobx | mobx-react | 0.55 |
| mui-material | emotion-react | 0.54 |
| lucide-react | clsx | 0.54 |
Strength Score measures the co-occurrence affinity between two technologies using the Jaccard similarity coefficient:
$$ \frac{|A \cap B|}{|A| + |B| - |A \cap B|} $$
The number of repositories containing both divided by the number of repositories containing either. Scores range from 0 to 1.
These are committed to the repo automatically by the GitHub Actions pipeline (see Daily Pipeline), so you can browse or consume the data directly from this repository without running the app or standing up a database.
License note: these datasets are licensed under CC-BY 4.0, separate from the MIT-licensed codebase. Attribution is required if you reuse them.
Note: cloning this repo gets you the code and the exported datasets. It does not give you a running instance of the website. The live app requires a deployed Next.js instance (Vercel) connected to a hosted PostgreSQL database. See Deployment.
Deliberately out of scope: full repository browsing/search. Technology pages include a read-only "top repositories" panel instead.
May be revisited later: knowledge graph visualization, migration detection, AI recommendations, multi-language ecosystem analysis, user accounts.
Repositories are discovered by scanning recently updated public JS/TS repositories that meet eligibility requirements, and the crawler maintains a rolling sample rather than attempting full ecosystem coverage. We process repository technology links over a 30-day rolling window to ensure that data remains relevant and representative of current usage.
repoCount indicates the number of active, eligible repositories where a technology is currently detected.
| Criterion | Requirement |
|---|---|
| Visibility | Public |
| Language | JavaScript or TypeScript (primary language) |
| Stars | > 10 |
| package.json | Present at root of default branch |
Excluded: forks, archived repositories, disabled repositories, empty repositories.
Pages are React Server Components that fetch from the API routes above rather than querying the database directly, so there's a single data-access path for both the UI and any external consumer of the API.
| Path | Description |
|---|---|
/ | Homepage: search bar, category grid, trending preview |
/search | Search results |
/trending | Full trending list |
/trending/weekly | Weekly breakout |
/technology/[slug] | Technology detail — adoption, trend chart, pairings, top repositories |
| Layer | Technology |
|---|---|
| Frontend | Next.js 15, React Server Components, TypeScript, Tailwind CSS |
| Backend | Next.js Route Handlers |
| Database | PostgreSQL 16+ |
| ORM | Prisma 5+ |
| Data Collection | GitHub GraphQL API v4 |
| Validation | Zod 3+ |
| Logging | Pino |
| Hosting | Vercel |
Target: a fully running local environment in under 15 minutes.
git clone https://github.com/FarazKelhini/stack-pulse
cd stack-pulse
npm install
Copy the example environment file:
Linux/macOS:
cp .env.example .env.local
Windows PowerShell:
Copy-Item .env.example .env.local
Then open .env.local and configure the required variables.
For the local PostgreSQL database created in the next step, use:
DATABASE_URL="postgresql://stackpulse:stackpulse@localhost:5432/stackpulse"
You'll also need to provide a GitHub token:
GITHUB_TOKEN="your_github_token"
The GitHub token is used by the crawler to access the GitHub API. Keep it private and never commit .env.local to Git.
The following Linux/macOS command creates a PostgreSQL 16 container named stackpulse-db:
docker run -d \
--name stackpulse-db \
-e POSTGRES_DB=stackpulse \
-e POSTGRES_USER=stackpulse \
-e POSTGRES_PASSWORD=stackpulse \
-p 5432:5432 \
postgres:16
Or use this one line command that works identically in both Linux Bash and Windows PowerShell:
docker run -d --name stackpulse-db -e POSTGRES_DB=stackpulse -e POSTGRES_USER=stackpulse -e POSTGRES_PASSWORD=stackpulse -p 5432:5432 postgres:16
The database will be available at localhost:5432 with:
| Setting | Value |
|---|---|
| Database | stackpulse |
| User | stackpulse |
| Password | stackpulse |
| Host | localhost |
| Port | 5432 |
Already have a
stackpulse-dbcontainer? You can start it again with:docker start stackpulse-db
npx prisma migrate dev
This creates/updates the local database schema.
npx prisma db seed
This populates the database with the initial technology dictionary.
To populate the application with a small amount of data, run a crawl with a batch size of 1.
Linux/macOS:
CRAWL_BATCH_SIZE=1 npm run crawl
Windows PowerShell:
$env:CRAWL_BATCH_SIZE="1"; npm run crawl
The crawler uses the GitHub API, so a valid
GITHUB_TOKENis required.
npm run dev
Then open the URL shown in the terminal, typically:
PostgreSQL connection error
Make sure the container is running:
docker ps
If it isn't running:
docker start stackpulse-db
Port 5432 is already in use
Another PostgreSQL instance may already be using port 5432. Either stop it or change the host-side port in the Docker command and update DATABASE_URL accordingly.
Port 3000 is already in use
The development server may choose another available port. Use the URL printed by npm run dev.
See .env.example for the full list. Required:
| Variable | Purpose |
|---|---|
GITHUB_TOKEN | GitHub GraphQL API access (read-only, public repos) |
DATABASE_URL | PostgreSQL connection string |
TEST_DATABASE_URL | Separate database for the integration test suite — never the same as DATABASE_URL |
Optional (sensible defaults shown):
| Variable | Default | Purpose |
|---|---|---|
CRAWL_BATCH_SIZE | 100 | Repositories per crawl batch |
CRAWL_TRANSACTION_TIMEOUT_MS | 60000 | Maximum duration for a crawl database transaction |
CRAWL_TRANSACTION_MAX_WAIT_MS | 10000 | Maximum wait to acquire a database transaction |
CRAWL_DB_SUB_BATCH_SIZE | 10 | Repositories written per transaction; does not affect GitHub API usage |
CRAWL_DELAY_MS | 500 | Delay between requests |
CRAWL_MAX_RETRIES | 3 | Max retries per repository before skipping |
CRAWL_MAX_DURATION_MS | 5400000 (90 min) | Wall-clock cap on one crawl run |
KV_REST_API_URL / KV_REST_API_TOKEN | — | Vercel KV / Upstash Redis for rate limiting; required in production, no-ops locally if unset |
npm run dev # Start the Next.js dev server
npm run crawl # Discover and ingest repositories
npm run refresh # Maintenance: refresh existing repo links
npm run aggregate # Compute technology pairings
npm run snapshot # Generate daily adoption snapshots
npm run trends # Compute trend scores
npm run export # Export datasets to public/datasets/
npm run validate-exports # Validate exported dataset schemas
npm run monitor # Integrity check: find stale tech links
npm run generate-network # Generate pairing network file
npm run test # Run the Vitest suite
A scheduled GitHub Actions workflow (.github/workflows/daily-pipeline.yml) runs once per day (02:00 UTC) and can also be triggered manually:
prisma migrate deploycrawl — Discovery-oriented repository traversal (crawl.ts)refresh — Maintenance-oriented repository refresh (refresh.ts). Updates technology links for existing repos to keep the 30-day rolling window accurate.aggregate — Compute technology pairings (aggregate.ts)snapshot — Generate daily snapshots (snapshot.ts)trends — Compute trend scores (trends.ts)export — Generate and commit datasets (export.ts)validate-exports — Validate exported dataset schemasmonitor — Non-blocking integrity check (monitor_stale.ts). Final step; failures do not halt the pipeline.network - Generate pairing network filecommit — Commit updated datasets back to the repoEvery step is idempotent and resumable. Crawl failures and DB connection failures are treated as critical and halt the pipeline; failures in other steps degrade gracefully so later steps still run with whatever data is available.
/api/search, /api/trending, /api/technology/[slug], export generationTEST_DATABASE_URL, with migrations applied before the suite runsThe app is designed for Vercel with a hosted PostgreSQL database. Deploying requires:
DATABASE_URLDATABASE_URL, GH_PAT) configured in the repo settingsWithout a deployment, the datasets in public/datasets/ are still browsable directly from GitHub even though the interactive site (search, trending, technology pages) isn't live.
Code is licensed under MIT; datasets in public/datasets/ are licensed under CC-BY 4.0.
TypeScript
70.8%
HTML
21.3%
JavaScript
7.5%
StackPulse crawls a rolling sample of public JavaScript and TypeScript repositories on GitHub and tracks which frameworks, databases, ORMs, and tools are actually used together, and how that adoption shifts over time. Every number is generated by a daily pipeline and backed by an open dataset you can inspect yourself.
See the codeTHE JAVASCRIPT ECOSYSTEM | OBSERVED DAILY
StackPulse crawls a rolling sample of public JavaScript and TypeScript repositories on GitHub and tracks which frameworks, databases, ORMs, and tools are actually used together, and how that adoption shifts over time. Every number below is generated by a daily pipeline and backed by an open dataset you can inspect yourself.
| Technology | Adoption | Trend Score |
|---|---|---|
| TypeScript | 76.4% | ▲ +4.17 |
| React | 34.9% | ▲ +3.77 |
| Vitest | 24.1% | ▲ +3.80 |
| Vite | 19.7% | ▲ +3.79 |
| Jest | 18.0% | ▲ +3.13 |
| Tailwind CSS | 14.7% | ▲ +3.56 |
| Babel | 14.2% | ▲ +2.94 |
| rimraf | 14.1% | ▲ +2.95 |
| Mocha | 13.7% | ▲ +2.91 |
| Webpack | 12.8% | ▲ +2.90 |
Trend Score is a log-scaled growth index: (current adoption / prior adoption) × log10(current adoption + 10), weighted so both the rate of change and the technology's overall scale matter.
| Rank | Technology | Category | Weekly Change |
|---|---|---|---|
| 1 | Rspack | BuildTools | ▲ +16.7% |
| 2 | Kysely | ORMs | ▲ +16.7% |
| 3 | Drizzle ORM | ORMs | ▲ +9.3% |
| 4 | Better SQLite3 | Databases | ▲ +7.2% |
| 5 | Supabase | Databases | ▲ +7% |
| 6 | Fastify | Frameworks | ▲ +6.9% |
| 7 | Framer Motion | UILibraries | ▲ +6% |
| 8 | Zustand | StateManagement | ▲ +5.8% |
| 9 | SvelteKit | Frameworks | ▲ +5.6% |
| 10 | Clerk (Next.js) | Authentication | ▲ +5.6% |
| Name | 30-Day Trend |
|---|---|
| Parcel | -5.3% |
| Category | Top Technology |
|---|---|
| Authentication | CORS |
| BuildTools | TypeScript |
| Databases | Better SQLite3 |
| Frameworks | React |
| ORMs | Drizzle ORM |
| StateManagement | Zustand |
| Testing | Vitest |
| UILibraries | Tailwind CSS |
| Validation | Zod |
| Tech A | Tech B | Strength Score |
|---|---|---|
| cva | tailwind-merge | 0.76 |
| clsx | tailwind-merge | 0.75 |
| testing-library-react | testing-library-jest-dom | 0.66 |
| react-redux | redux | 0.65 |
| cva | clsx | 0.62 |
| cva | lucide-react | 0.57 |
| lucide-react | tailwind-merge | 0.57 |
| mobx | mobx-react | 0.55 |
| mui-material | emotion-react | 0.54 |
| lucide-react | clsx | 0.54 |
Strength Score measures the co-occurrence affinity between two technologies using the Jaccard similarity coefficient:
$$ \frac{|A \cap B|}{|A| + |B| - |A \cap B|} $$
The number of repositories containing both divided by the number of repositories containing either. Scores range from 0 to 1.
These are committed to the repo automatically by the GitHub Actions pipeline (see Daily Pipeline), so you can browse or consume the data directly from this repository without running the app or standing up a database.
License note: these datasets are licensed under CC-BY 4.0, separate from the MIT-licensed codebase. Attribution is required if you reuse them.
Note: cloning this repo gets you the code and the exported datasets. It does not give you a running instance of the website. The live app requires a deployed Next.js instance (Vercel) connected to a hosted PostgreSQL database. See Deployment.
Deliberately out of scope: full repository browsing/search. Technology pages include a read-only "top repositories" panel instead.
May be revisited later: knowledge graph visualization, migration detection, AI recommendations, multi-language ecosystem analysis, user accounts.
Repositories are discovered by scanning recently updated public JS/TS repositories that meet eligibility requirements, and the crawler maintains a rolling sample rather than attempting full ecosystem coverage. We process repository technology links over a 30-day rolling window to ensure that data remains relevant and representative of current usage.
repoCount indicates the number of active, eligible repositories where a technology is currently detected.
| Criterion | Requirement |
|---|---|
| Visibility | Public |
| Language | JavaScript or TypeScript (primary language) |
| Stars | > 10 |
| package.json | Present at root of default branch |
Excluded: forks, archived repositories, disabled repositories, empty repositories.
Pages are React Server Components that fetch from the API routes above rather than querying the database directly, so there's a single data-access path for both the UI and any external consumer of the API.
| Path | Description |
|---|---|
/ | Homepage: search bar, category grid, trending preview |
/search | Search results |
/trending | Full trending list |
/trending/weekly | Weekly breakout |
/technology/[slug] | Technology detail — adoption, trend chart, pairings, top repositories |
| Layer | Technology |
|---|---|
| Frontend | Next.js 15, React Server Components, TypeScript, Tailwind CSS |
| Backend | Next.js Route Handlers |
| Database | PostgreSQL 16+ |
| ORM | Prisma 5+ |
| Data Collection | GitHub GraphQL API v4 |
| Validation | Zod 3+ |
| Logging | Pino |
| Hosting | Vercel |
Target: a fully running local environment in under 15 minutes.
git clone https://github.com/FarazKelhini/stack-pulse
cd stack-pulse
npm install
Copy the example environment file:
Linux/macOS:
cp .env.example .env.local
Windows PowerShell:
Copy-Item .env.example .env.local
Then open .env.local and configure the required variables.
For the local PostgreSQL database created in the next step, use:
DATABASE_URL="postgresql://stackpulse:stackpulse@localhost:5432/stackpulse"
You'll also need to provide a GitHub token:
GITHUB_TOKEN="your_github_token"
The GitHub token is used by the crawler to access the GitHub API. Keep it private and never commit .env.local to Git.
The following Linux/macOS command creates a PostgreSQL 16 container named stackpulse-db:
docker run -d \
--name stackpulse-db \
-e POSTGRES_DB=stackpulse \
-e POSTGRES_USER=stackpulse \
-e POSTGRES_PASSWORD=stackpulse \
-p 5432:5432 \
postgres:16
Or use this one line command that works identically in both Linux Bash and Windows PowerShell:
docker run -d --name stackpulse-db -e POSTGRES_DB=stackpulse -e POSTGRES_USER=stackpulse -e POSTGRES_PASSWORD=stackpulse -p 5432:5432 postgres:16
The database will be available at localhost:5432 with:
| Setting | Value |
|---|---|
| Database | stackpulse |
| User | stackpulse |
| Password | stackpulse |
| Host | localhost |
| Port | 5432 |
Already have a
stackpulse-dbcontainer? You can start it again with:docker start stackpulse-db
npx prisma migrate dev
This creates/updates the local database schema.
npx prisma db seed
This populates the database with the initial technology dictionary.
To populate the application with a small amount of data, run a crawl with a batch size of 1.
Linux/macOS:
CRAWL_BATCH_SIZE=1 npm run crawl
Windows PowerShell:
$env:CRAWL_BATCH_SIZE="1"; npm run crawl
The crawler uses the GitHub API, so a valid
GITHUB_TOKENis required.
npm run dev
Then open the URL shown in the terminal, typically:
PostgreSQL connection error
Make sure the container is running:
docker ps
If it isn't running:
docker start stackpulse-db
Port 5432 is already in use
Another PostgreSQL instance may already be using port 5432. Either stop it or change the host-side port in the Docker command and update DATABASE_URL accordingly.
Port 3000 is already in use
The development server may choose another available port. Use the URL printed by npm run dev.
See .env.example for the full list. Required:
| Variable | Purpose |
|---|---|
GITHUB_TOKEN | GitHub GraphQL API access (read-only, public repos) |
DATABASE_URL | PostgreSQL connection string |
TEST_DATABASE_URL | Separate database for the integration test suite — never the same as DATABASE_URL |
Optional (sensible defaults shown):
| Variable | Default | Purpose |
|---|---|---|
CRAWL_BATCH_SIZE | 100 | Repositories per crawl batch |
CRAWL_TRANSACTION_TIMEOUT_MS | 60000 | Maximum duration for a crawl database transaction |
CRAWL_TRANSACTION_MAX_WAIT_MS | 10000 | Maximum wait to acquire a database transaction |
CRAWL_DB_SUB_BATCH_SIZE | 10 | Repositories written per transaction; does not affect GitHub API usage |
CRAWL_DELAY_MS | 500 | Delay between requests |
CRAWL_MAX_RETRIES | 3 | Max retries per repository before skipping |
CRAWL_MAX_DURATION_MS | 5400000 (90 min) | Wall-clock cap on one crawl run |
KV_REST_API_URL / KV_REST_API_TOKEN | — | Vercel KV / Upstash Redis for rate limiting; required in production, no-ops locally if unset |
npm run dev # Start the Next.js dev server
npm run crawl # Discover and ingest repositories
npm run refresh # Maintenance: refresh existing repo links
npm run aggregate # Compute technology pairings
npm run snapshot # Generate daily adoption snapshots
npm run trends # Compute trend scores
npm run export # Export datasets to public/datasets/
npm run validate-exports # Validate exported dataset schemas
npm run monitor # Integrity check: find stale tech links
npm run generate-network # Generate pairing network file
npm run test # Run the Vitest suite
A scheduled GitHub Actions workflow (.github/workflows/daily-pipeline.yml) runs once per day (02:00 UTC) and can also be triggered manually:
prisma migrate deploycrawl — Discovery-oriented repository traversal (crawl.ts)refresh — Maintenance-oriented repository refresh (refresh.ts). Updates technology links for existing repos to keep the 30-day rolling window accurate.aggregate — Compute technology pairings (aggregate.ts)snapshot — Generate daily snapshots (snapshot.ts)trends — Compute trend scores (trends.ts)export — Generate and commit datasets (export.ts)validate-exports — Validate exported dataset schemasmonitor — Non-blocking integrity check (monitor_stale.ts). Final step; failures do not halt the pipeline.network - Generate pairing network filecommit — Commit updated datasets back to the repoEvery step is idempotent and resumable. Crawl failures and DB connection failures are treated as critical and halt the pipeline; failures in other steps degrade gracefully so later steps still run with whatever data is available.
/api/search, /api/trending, /api/technology/[slug], export generationTEST_DATABASE_URL, with migrations applied before the suite runsThe app is designed for Vercel with a hosted PostgreSQL database. Deploying requires:
DATABASE_URLDATABASE_URL, GH_PAT) configured in the repo settingsWithout a deployment, the datasets in public/datasets/ are still browsable directly from GitHub even though the interactive site (search, trending, technology pages) isn't live.
Code is licensed under MIT; datasets in public/datasets/ are licensed under CC-BY 4.0.
TypeScript
70.8%
HTML
21.3%
JavaScript
7.5%