From f44491814e09c3d4967ef6de05ee981f0ae5b333 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 14 Jan 2026 21:26:16 +0800 Subject: [PATCH 1/5] test --- .github/workflows/test-install-times.yml | 82 ++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 .github/workflows/test-install-times.yml diff --git a/.github/workflows/test-install-times.yml b/.github/workflows/test-install-times.yml new file mode 100644 index 0000000..3023d9c --- /dev/null +++ b/.github/workflows/test-install-times.yml @@ -0,0 +1,82 @@ +name: Test Install Times + +on: + pull_request: + branches: [main] + paths: + - '.github/workflows/test-install-times.yml' + +jobs: + test-install-times: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Measure Next.js install time + id: next + run: | + cp -r packages/starter-next-js /tmp/next-test + cd /tmp/next-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "Next.js install time: ${ELAPSED}ms" + + - name: Measure React Router install time + id: react_router + run: | + cp -r packages/starter-react-router /tmp/react-router-test + cd /tmp/react-router-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "React Router install time: ${ELAPSED}ms" + + - name: Measure TanStack Start install time + id: tanstack + run: | + cp -r packages/starter-tanstack-start-react /tmp/tanstack-test + cd /tmp/tanstack-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "TanStack Start install time: ${ELAPSED}ms" + + - name: Measure Nuxt install time + id: nuxt + run: | + cp -r packages/starter-nuxt /tmp/nuxt-test + cd /tmp/nuxt-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "Nuxt install time: ${ELAPSED}ms" + + - name: Summary + run: | + echo "## Install Time Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Framework | Install Time |" >> $GITHUB_STEP_SUMMARY + echo "|-----------|-------------|" >> $GITHUB_STEP_SUMMARY + echo "| Next.js | ${{ steps.next.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| React Router | ${{ steps.react_router.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| TanStack Start | ${{ steps.tanstack.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| Nuxt | ${{ steps.nuxt.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY From e87812cbbccfa65cacce312c7bed63fa7ba2f422 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 14 Jan 2026 21:33:42 +0800 Subject: [PATCH 2/5] Clear run --- .github/workflows/test-install-times.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/test-install-times.yml b/.github/workflows/test-install-times.yml index 3023d9c..843e6ec 100644 --- a/.github/workflows/test-install-times.yml +++ b/.github/workflows/test-install-times.yml @@ -25,6 +25,10 @@ jobs: - name: Measure Next.js install time id: next run: | + # Clear pnpm store for fair measurement + rm -rf ~/.local/share/pnpm/store + pnpm store prune || true + cp -r packages/starter-next-js /tmp/next-test cd /tmp/next-test START=$(date +%s%N) @@ -37,6 +41,10 @@ jobs: - name: Measure React Router install time id: react_router run: | + # Clear pnpm store for fair measurement + rm -rf ~/.local/share/pnpm/store + pnpm store prune || true + cp -r packages/starter-react-router /tmp/react-router-test cd /tmp/react-router-test START=$(date +%s%N) @@ -49,6 +57,10 @@ jobs: - name: Measure TanStack Start install time id: tanstack run: | + # Clear pnpm store for fair measurement + rm -rf ~/.local/share/pnpm/store + pnpm store prune || true + cp -r packages/starter-tanstack-start-react /tmp/tanstack-test cd /tmp/tanstack-test START=$(date +%s%N) @@ -61,6 +73,10 @@ jobs: - name: Measure Nuxt install time id: nuxt run: | + # Clear pnpm store for fair measurement + rm -rf ~/.local/share/pnpm/store + pnpm store prune || true + cp -r packages/starter-nuxt /tmp/nuxt-test cd /tmp/nuxt-test START=$(date +%s%N) From c444e99ecd9536cd5356bf31e119577587a2d8a7 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 14 Jan 2026 21:37:26 +0800 Subject: [PATCH 3/5] One more test --- .github/workflows/test-install-times.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test-install-times.yml b/.github/workflows/test-install-times.yml index 843e6ec..6def14f 100644 --- a/.github/workflows/test-install-times.yml +++ b/.github/workflows/test-install-times.yml @@ -26,8 +26,10 @@ jobs: id: next run: | # Clear pnpm store for fair measurement - rm -rf ~/.local/share/pnpm/store - pnpm store prune || true + STORE_PATH=$(pnpm store path) + rm -rf "$STORE_PATH" + rm -rf ~/.local/share/pnpm + rm -rf /tmp/next-test cp -r packages/starter-next-js /tmp/next-test cd /tmp/next-test @@ -42,8 +44,10 @@ jobs: id: react_router run: | # Clear pnpm store for fair measurement - rm -rf ~/.local/share/pnpm/store - pnpm store prune || true + STORE_PATH=$(pnpm store path) + rm -rf "$STORE_PATH" + rm -rf ~/.local/share/pnpm + rm -rf /tmp/react-router-test cp -r packages/starter-react-router /tmp/react-router-test cd /tmp/react-router-test @@ -58,8 +62,10 @@ jobs: id: tanstack run: | # Clear pnpm store for fair measurement - rm -rf ~/.local/share/pnpm/store - pnpm store prune || true + STORE_PATH=$(pnpm store path) + rm -rf "$STORE_PATH" + rm -rf ~/.local/share/pnpm + rm -rf /tmp/tanstack-test cp -r packages/starter-tanstack-start-react /tmp/tanstack-test cd /tmp/tanstack-test @@ -74,8 +80,10 @@ jobs: id: nuxt run: | # Clear pnpm store for fair measurement - rm -rf ~/.local/share/pnpm/store - pnpm store prune || true + STORE_PATH=$(pnpm store path) + rm -rf "$STORE_PATH" + rm -rf ~/.local/share/pnpm + rm -rf /tmp/nuxt-test cp -r packages/starter-nuxt /tmp/nuxt-test cd /tmp/nuxt-test From fcfb9f40d8de3a897f2ef9c9aa9f191dabca2aa2 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 14 Jan 2026 21:38:21 +0800 Subject: [PATCH 4/5] Move to multi jobs --- .github/workflows/test-install-times.yml | 99 ++++++++++++++++-------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/.github/workflows/test-install-times.yml b/.github/workflows/test-install-times.yml index 6def14f..8e433c5 100644 --- a/.github/workflows/test-install-times.yml +++ b/.github/workflows/test-install-times.yml @@ -7,9 +7,10 @@ on: - '.github/workflows/test-install-times.yml' jobs: - test-install-times: + next-install: runs-on: ubuntu-latest - + outputs: + time: ${{ steps.measure.outputs.time }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -23,14 +24,8 @@ jobs: node-version: '24' - name: Measure Next.js install time - id: next + id: measure run: | - # Clear pnpm store for fair measurement - STORE_PATH=$(pnpm store path) - rm -rf "$STORE_PATH" - rm -rf ~/.local/share/pnpm - rm -rf /tmp/next-test - cp -r packages/starter-next-js /tmp/next-test cd /tmp/next-test START=$(date +%s%N) @@ -40,15 +35,25 @@ jobs: echo "time=$ELAPSED" >> $GITHUB_OUTPUT echo "Next.js install time: ${ELAPSED}ms" + react-router-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + - name: Measure React Router install time - id: react_router + id: measure run: | - # Clear pnpm store for fair measurement - STORE_PATH=$(pnpm store path) - rm -rf "$STORE_PATH" - rm -rf ~/.local/share/pnpm - rm -rf /tmp/react-router-test - cp -r packages/starter-react-router /tmp/react-router-test cd /tmp/react-router-test START=$(date +%s%N) @@ -58,15 +63,25 @@ jobs: echo "time=$ELAPSED" >> $GITHUB_OUTPUT echo "React Router install time: ${ELAPSED}ms" + tanstack-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + - name: Measure TanStack Start install time - id: tanstack + id: measure run: | - # Clear pnpm store for fair measurement - STORE_PATH=$(pnpm store path) - rm -rf "$STORE_PATH" - rm -rf ~/.local/share/pnpm - rm -rf /tmp/tanstack-test - cp -r packages/starter-tanstack-start-react /tmp/tanstack-test cd /tmp/tanstack-test START=$(date +%s%N) @@ -76,15 +91,25 @@ jobs: echo "time=$ELAPSED" >> $GITHUB_OUTPUT echo "TanStack Start install time: ${ELAPSED}ms" + nuxt-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + - name: Measure Nuxt install time - id: nuxt + id: measure run: | - # Clear pnpm store for fair measurement - STORE_PATH=$(pnpm store path) - rm -rf "$STORE_PATH" - rm -rf ~/.local/share/pnpm - rm -rf /tmp/nuxt-test - cp -r packages/starter-nuxt /tmp/nuxt-test cd /tmp/nuxt-test START=$(date +%s%N) @@ -94,13 +119,19 @@ jobs: echo "time=$ELAPSED" >> $GITHUB_OUTPUT echo "Nuxt install time: ${ELAPSED}ms" + summary: + runs-on: ubuntu-latest + needs: [next-install, react-router-install, tanstack-install, nuxt-install] + steps: - name: Summary run: | echo "## Install Time Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY + echo "Each framework was installed on a fresh runner for fair comparison." >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY echo "| Framework | Install Time |" >> $GITHUB_STEP_SUMMARY echo "|-----------|-------------|" >> $GITHUB_STEP_SUMMARY - echo "| Next.js | ${{ steps.next.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| React Router | ${{ steps.react_router.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| TanStack Start | ${{ steps.tanstack.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| Nuxt | ${{ steps.nuxt.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| Next.js | ${{ needs.next-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| React Router | ${{ needs.react-router-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| TanStack Start | ${{ needs.tanstack-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY + echo "| Nuxt | ${{ needs.nuxt-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY From 09dc2dba43a9d93f8476e6b0a9fd98d5cc9060e8 Mon Sep 17 00:00:00 2001 From: Alexander Karan Date: Wed, 14 Jan 2026 21:43:58 +0800 Subject: [PATCH 5/5] Added new install times to CI pipeline --- .github/workflows/generate-stats.yml | 135 +++++++++++++++++++--- .github/workflows/test-install-times.yml | 137 ----------------------- 2 files changed, 121 insertions(+), 151 deletions(-) delete mode 100644 .github/workflows/test-install-times.yml diff --git a/.github/workflows/generate-stats.yml b/.github/workflows/generate-stats.yml index e4de16b..8de592d 100644 --- a/.github/workflows/generate-stats.yml +++ b/.github/workflows/generate-stats.yml @@ -10,13 +10,67 @@ on: - 'package.json' jobs: - generate-stats: + # Install time measurements run in parallel on fresh runners for fair comparison + next-install: runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 - permissions: - contents: write - pull-requests: write + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Measure Next.js install time + id: measure + run: | + cp -r packages/starter-next-js /tmp/next-test + cd /tmp/next-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "Next.js install time: ${ELAPSED}ms" + react-router-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Measure React Router install time + id: measure + run: | + cp -r packages/starter-react-router /tmp/react-router-test + cd /tmp/react-router-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "React Router install time: ${ELAPSED}ms" + + tanstack-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -24,21 +78,74 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 - - name: Setup Node.js (no cache for clean measurements) + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '24' - # No cache - we want clean measurements - - name: Measure install time (clean, no cache) - id: install + - name: Measure TanStack Start install time + id: measure run: | + cp -r packages/starter-tanstack-start-react /tmp/tanstack-test + cd /tmp/tanstack-test START=$(date +%s%N) - pnpm install --frozen-lockfile + pnpm install END=$(date +%s%N) ELAPSED=$((($END - $START) / 1000000)) echo "time=$ELAPSED" >> $GITHUB_OUTPUT - echo "Install time: ${ELAPSED}ms" + echo "TanStack Start install time: ${ELAPSED}ms" + + nuxt-install: + runs-on: ubuntu-latest + outputs: + time: ${{ steps.measure.outputs.time }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Measure Nuxt install time + id: measure + run: | + cp -r packages/starter-nuxt /tmp/nuxt-test + cd /tmp/nuxt-test + START=$(date +%s%N) + pnpm install + END=$(date +%s%N) + ELAPSED=$((($END - $START) / 1000000)) + echo "time=$ELAPSED" >> $GITHUB_OUTPUT + echo "Nuxt install time: ${ELAPSED}ms" + + # Main job that measures builds and generates stats + generate-stats: + runs-on: ubuntu-latest + needs: [next-install, react-router-install, tanstack-install, nuxt-install] + + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Install dependencies + run: pnpm install --frozen-lockfile - name: Measure Next.js builds id: next @@ -123,7 +230,7 @@ jobs: # Save Next.js stats mkdir -p packages/starter-next-js echo '{ - "installTimeMs": ${{ steps.install.outputs.time }}, + "installTimeMs": ${{ needs.next-install.outputs.time }}, "coldBuildTimeMs": ${{ steps.next.outputs.cold }}, "warmBuildTimeMs": ${{ steps.next.outputs.warm }}, "timingMeasuredAt": "'$TIMESTAMP'", @@ -133,7 +240,7 @@ jobs: # Save React Router stats mkdir -p packages/starter-react-router echo '{ - "installTimeMs": ${{ steps.install.outputs.time }}, + "installTimeMs": ${{ needs.react-router-install.outputs.time }}, "coldBuildTimeMs": ${{ steps.react_router.outputs.cold }}, "warmBuildTimeMs": ${{ steps.react_router.outputs.warm }}, "timingMeasuredAt": "'$TIMESTAMP'", @@ -143,7 +250,7 @@ jobs: # Save TanStack Start stats mkdir -p packages/starter-tanstack-start-react echo '{ - "installTimeMs": ${{ steps.install.outputs.time }}, + "installTimeMs": ${{ needs.tanstack-install.outputs.time }}, "coldBuildTimeMs": ${{ steps.tanstack.outputs.cold }}, "warmBuildTimeMs": ${{ steps.tanstack.outputs.warm }}, "timingMeasuredAt": "'$TIMESTAMP'", @@ -153,7 +260,7 @@ jobs: # Save Nuxt stats mkdir -p packages/starter-nuxt echo '{ - "installTimeMs": ${{ steps.install.outputs.time }}, + "installTimeMs": ${{ needs.nuxt-install.outputs.time }}, "coldBuildTimeMs": ${{ steps.nuxt.outputs.cold }}, "warmBuildTimeMs": ${{ steps.nuxt.outputs.warm }}, "timingMeasuredAt": "'$TIMESTAMP'", diff --git a/.github/workflows/test-install-times.yml b/.github/workflows/test-install-times.yml deleted file mode 100644 index 8e433c5..0000000 --- a/.github/workflows/test-install-times.yml +++ /dev/null @@ -1,137 +0,0 @@ -name: Test Install Times - -on: - pull_request: - branches: [main] - paths: - - '.github/workflows/test-install-times.yml' - -jobs: - next-install: - runs-on: ubuntu-latest - outputs: - time: ${{ steps.measure.outputs.time }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - - name: Measure Next.js install time - id: measure - run: | - cp -r packages/starter-next-js /tmp/next-test - cd /tmp/next-test - START=$(date +%s%N) - pnpm install - END=$(date +%s%N) - ELAPSED=$((($END - $START) / 1000000)) - echo "time=$ELAPSED" >> $GITHUB_OUTPUT - echo "Next.js install time: ${ELAPSED}ms" - - react-router-install: - runs-on: ubuntu-latest - outputs: - time: ${{ steps.measure.outputs.time }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - - name: Measure React Router install time - id: measure - run: | - cp -r packages/starter-react-router /tmp/react-router-test - cd /tmp/react-router-test - START=$(date +%s%N) - pnpm install - END=$(date +%s%N) - ELAPSED=$((($END - $START) / 1000000)) - echo "time=$ELAPSED" >> $GITHUB_OUTPUT - echo "React Router install time: ${ELAPSED}ms" - - tanstack-install: - runs-on: ubuntu-latest - outputs: - time: ${{ steps.measure.outputs.time }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - - name: Measure TanStack Start install time - id: measure - run: | - cp -r packages/starter-tanstack-start-react /tmp/tanstack-test - cd /tmp/tanstack-test - START=$(date +%s%N) - pnpm install - END=$(date +%s%N) - ELAPSED=$((($END - $START) / 1000000)) - echo "time=$ELAPSED" >> $GITHUB_OUTPUT - echo "TanStack Start install time: ${ELAPSED}ms" - - nuxt-install: - runs-on: ubuntu-latest - outputs: - time: ${{ steps.measure.outputs.time }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - - name: Measure Nuxt install time - id: measure - run: | - cp -r packages/starter-nuxt /tmp/nuxt-test - cd /tmp/nuxt-test - START=$(date +%s%N) - pnpm install - END=$(date +%s%N) - ELAPSED=$((($END - $START) / 1000000)) - echo "time=$ELAPSED" >> $GITHUB_OUTPUT - echo "Nuxt install time: ${ELAPSED}ms" - - summary: - runs-on: ubuntu-latest - needs: [next-install, react-router-install, tanstack-install, nuxt-install] - steps: - - name: Summary - run: | - echo "## Install Time Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Each framework was installed on a fresh runner for fair comparison." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Framework | Install Time |" >> $GITHUB_STEP_SUMMARY - echo "|-----------|-------------|" >> $GITHUB_STEP_SUMMARY - echo "| Next.js | ${{ needs.next-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| React Router | ${{ needs.react-router-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| TanStack Start | ${{ needs.tanstack-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY - echo "| Nuxt | ${{ needs.nuxt-install.outputs.time }}ms |" >> $GITHUB_STEP_SUMMARY