Created
April 8, 2026 15:45
-
-
Save felipefdl/391ad66d0830eb9bf2e21fef88dc9b43 to your computer and use it in GitHub Desktop.
Astro build benchmark: Node vs Deno vs Bun
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Astro production build benchmark across Node, Deno, and Bun. | |
| # Creates git worktrees for isolation, runs builds sequentially to avoid resource contention. | |
| # | |
| # Requirements: git, node (via fnm), deno, bun, python3 | |
| # Usage: cd into your Astro project root, then run this script. | |
| set -euo pipefail | |
| RUNS=3 | |
| PROJECT_ROOT=$(git rev-parse --show-toplevel) | |
| RESULTS_FILE="/tmp/bench-results.txt" | |
| > "$RESULTS_FILE" | |
| eval "$(fnm env)" | |
| log() { | |
| echo "[$(date +%H:%M:%S)] $1" | |
| echo "$1" >> "$RESULTS_FILE" | |
| } | |
| cleanup() { | |
| log "Cleaning up worktrees..." | |
| for rt in node deno bun; do | |
| git worktree remove "/tmp/bench-$rt" --force 2>/dev/null || true | |
| git branch -D "bench-${rt}-build" 2>/dev/null || true | |
| done | |
| } | |
| trap cleanup EXIT | |
| time_build() { | |
| local runtime="$1" | |
| local dir="$2" | |
| local cmd="$3" | |
| local times=() | |
| log "=== $runtime ===" | |
| for i in $(seq 1 $RUNS); do | |
| rm -rf "$dir/dist" | |
| log " Run $i/$RUNS..." | |
| local start=$(python3 -c 'import time; print(time.time())') | |
| eval "$cmd" > "/tmp/bench-${runtime}-run${i}.log" 2>&1 | |
| local exit_code=$? | |
| local end=$(python3 -c 'import time; print(time.time())') | |
| local elapsed=$(python3 -c "print(f'{$end - $start:.2f}')") | |
| if [ $exit_code -ne 0 ]; then | |
| log " Run $i FAILED (exit $exit_code)" | |
| tail -20 "/tmp/bench-${runtime}-run${i}.log" | |
| times+=("FAIL") | |
| else | |
| log " Run $i: ${elapsed}s" | |
| times+=("$elapsed") | |
| fi | |
| done | |
| local valid_times=() | |
| for t in "${times[@]}"; do | |
| [ "$t" != "FAIL" ] && valid_times+=("$t") | |
| done | |
| if [ ${#valid_times[@]} -gt 0 ]; then | |
| local csv=$(IFS=,; echo "${valid_times[*]}") | |
| python3 -c " | |
| times = [$csv] | |
| avg = sum(times) / len(times) | |
| mn = min(times) | |
| mx = max(times) | |
| print(f' RESULT: min={mn:.2f}s max={mx:.2f}s avg={avg:.2f}s ({len(times)}/$RUNS ok)') | |
| " | tee -a "$RESULTS_FILE" | |
| else | |
| log " ALL RUNS FAILED" | |
| fi | |
| log "" | |
| } | |
| # Header | |
| log "Astro Production Build Benchmark" | |
| log "================================" | |
| log "Date: $(date)" | |
| if [[ "$(uname)" == "Darwin" ]]; then | |
| log "Machine: $(sysctl -n machdep.cpu.brand_string)" | |
| log "Cores: $(sysctl -n hw.ncpu) / RAM: $(sysctl -n hw.memsize | awk '{printf "%.0f GB", $1/1073741824}')" | |
| else | |
| log "Machine: $(cat /proc/cpuinfo | grep 'model name' | head -1 | cut -d: -f2 | xargs)" | |
| log "Cores: $(nproc) / RAM: $(free -h | awk '/Mem:/{print $2}')" | |
| fi | |
| log "" | |
| # Create worktrees | |
| for rt in node deno bun; do | |
| git worktree remove "/tmp/bench-$rt" --force 2>/dev/null || true | |
| git branch -D "bench-${rt}-build" 2>/dev/null || true | |
| git worktree add "/tmp/bench-$rt" -b "bench-${rt}-build" HEAD | |
| done | |
| # Install deps (npm for all three, since Deno's own installer has Vite resolution issues) | |
| log "Installing dependencies..." | |
| for rt in node deno bun; do | |
| (cd "/tmp/bench-$rt" && npm install --silent 2>&1) | tail -1 | |
| done | |
| log "" | |
| # Node | |
| NODE_VERSION=$(node --version) | |
| log "Runtime: Node $NODE_VERSION" | |
| time_build "node" "/tmp/bench-node" "cd /tmp/bench-node && node ./node_modules/.bin/astro build" | |
| # Deno (npm-installed node_modules, deno as the JS runtime) | |
| DENO_VERSION=$(deno --version | head -1 | awk '{print $2}') | |
| log "Runtime: Deno $DENO_VERSION" | |
| time_build "deno" "/tmp/bench-deno" "cd /tmp/bench-deno && deno run -A ./node_modules/.bin/astro build" | |
| # Bun | |
| BUN_VERSION=$(bun --version) | |
| log "Runtime: Bun $BUN_VERSION" | |
| time_build "bun" "/tmp/bench-bun" "cd /tmp/bench-bun && bun ./node_modules/.bin/astro build" | |
| log "================================" | |
| log "Full results saved to $RESULTS_FILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment