Skip to content

Conversation

@AbanoubGhadban
Copy link
Collaborator

@AbanoubGhadban AbanoubGhadban commented Nov 30, 2025

Summary

  • Add bundle size monitoring CI using size-limit
  • Automatically posts size comparison comments on PRs
  • Fails CI if bundle size exceeds defined limits

What's Tracked

Package Current Size Limit
react-on-rails (full) 14.86 kB 20 kB
react-on-rails (client) 203 B 1 kB
react-on-rails-pro (full) 33.99 kB 45 kB
react-on-rails-pro (client) 503 B 2 kB
react-on-rails-pro-node-renderer 7.8 kB 15 kB

Local Commands

  • pnpm run size - Check bundle sizes
  • pnpm run size:json - Get JSON output

Test plan

  • Verified size-limit detects size increases locally
  • Verified size-limit fails when limits exceeded
  • YAML syntax validated
  • CI workflow runs successfully on this PR

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Added automated bundle-size monitoring to CI that runs size checks on pull requests.
    • Introduced size-limit configuration with per-package gzip-only size budgets.
    • Added size-limit tooling as dev dependencies and new scripts to run size checks locally and during install/build workflows.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 30, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds bundle-size monitoring: a new GitHub Actions workflow that runs size checks on PRs, a .size-limit.json with three gzip-only bundle entries, and package.json changes adding size-limit tooling and scripts to produce JSON size reports.

Changes

Cohort / File(s) Summary
GitHub Actions workflow
\.github/workflows/bundle-size.yml
New workflow triggered on pull_request for changes under packages/**, package.json, pnpm-lock.yaml, .size-limit.json, and the workflow file; job size runs on ubuntu-22.04, sets CI_JOB_NUMBER, grants contents: read and pull-requests: write, installs Node 22 and pnpm 9, checks out base and PR branches, installs deps, builds, runs size-limit to JSON, adjusts limits from base + 0.5KB, and runs andresz1/size-limit-action with GITHUB_TOKEN.
Bundle size configuration
.size-limit.json
Replaced configuration with three entries (gzip-only) targeting built lib/*.js for react-on-rails, react-on-rails-pro, and react-on-rails-pro-node-renderer.
Package metadata & scripts
package.json
Added devDependencies size-limit and @size-limit/file, adjusted globals entries (removed in one place, re-added elsewhere), added size and size:json scripts, and wired size scripts into postinstall/script flows to run size checks and produce JSON reports.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer (push/PR)
    participant GH as GitHub Actions
    participant Runner as Actions Runner (ubuntu-22.04)
    participant PNPM as pnpm store/cache
    participant SL as size-limit Action
    participant API as GitHub API

    Dev->>GH: open PR (paths match)
    GH->>Runner: start "Bundle Size" job
    Runner->>Runner: setup Node 22, pnpm 9
    Runner->>Runner: checkout base branch & install deps
    Runner->>SL: run build & size-limit (base) -> produce JSON
    Runner->>Runner: checkout PR branch & install deps
    Runner->>Runner: adjust .size-limit.json limits (base + 0.5KB)
    Runner->>SL: run build & size-limit (PR) with pnpm
    SL->>API: report results/comments using GITHUB_TOKEN
    API-->>Dev: update PR with size results
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

  • Review workflow triggers/permissions and environment variable usage in .github/workflows/bundle-size.yml.
  • Verify pnpm cache key and restore/save logic.
  • Confirm .size-limit.json paths match built artifacts and size:json output expectations.
  • Check package.json script wiring and devDependency changes.

Suggested labels

full-ci

Suggested reviewers

  • Judahmeek

Poem

🐇 I hopped into CI with cheer,
I counted bytes both far and near,
Base builds, PRs, and caches clear,
Tiny bundles I hold dear —
Crunching sizes, nibble and cheer. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding bundle size CI checks via size-limit.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Thanks for adding bundle size monitoring! This is a valuable addition to prevent performance regressions. Here's my review:

Strengths

  1. Good tooling choice: size-limit is a well-maintained tool with GitHub Actions integration
  2. Appropriate limits: The defined limits seem reasonable based on current package sizes
  3. Good granularity: Tracking both full and client bundles separately helps identify specific regressions
  4. Proper permissions: The workflow correctly requests pull-requests: write for PR comments

⚠️ Critical Issues

1. Missing dependency installation step

The workflow uses andresz1/size-limit-action@v1 which expects dependencies to already be installed. You need to add a step to install dependencies BEFORE running the size check:

- name: Install dependencies
  run: pnpm install --frozen-lockfile

- name: Check bundle size
  uses: andresz1/size-limit-action@v1
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    package_manager: pnpm
    build_script: build

Why this matters: The build_script: build parameter tells the action to run pnpm build, but this will fail if dependencies aren't installed first. The action doesn't install dependencies automatically.

2. Path verification needed

According to CLAUDE.md's "Managing File Paths in Configuration Files" section, you should verify paths exist:

# Verify all paths in .size-limit.json exist after build
ls -lh packages/react-on-rails/lib/*.js
ls -lh packages/react-on-rails-pro/lib/*.js
ls -lh packages/react-on-rails-pro-node-renderer/lib/*.js

Action required: Run pnpm build locally and verify all paths in .size-limit.json match actual build outputs.

🔍 Suggestions

3. Consider adding detect-changes integration

Other workflows in this repo use a detect-changes job to skip unnecessary runs. Consider:

  • Skipping on docs-only changes
  • Running on master push with docs-only guard
  • Supporting full-ci label

Example from lint-js-and-ruby.yml shows this pattern.

4. Workflow consistency

For consistency with other workflows:

  • Consider adding a comment explaining why CI_JOB_NUMBER is set (other workflows document this)
  • Consider using ./.github/actions/setup-node-with-retry instead of direct actions/setup-node@v4 (used in other workflows for reliability)

5. Minor: Package.json alphabetization

The diff shows globals was moved in the dependencies list. While this doesn't affect functionality, it suggests an unrelated formatting change was included.

📋 Testing Checklist (from CLAUDE.md)

Before merging, ensure you've tested:

# 1. Test clean install (CRITICAL per CLAUDE.md)
rm -rf node_modules
pnpm install --frozen-lockfile

# 2. Test build scripts
pnpm run build

# 3. Test size-limit locally
pnpm run size

# 4. Verify output paths exist
ls -la packages/*/lib/*.js

# 5. Test that size-limit fails when limits exceeded (already done ✓)

🎯 Required Changes

  1. Add dependency installation step to the workflow (before size check)
  2. Verify all paths in .size-limit.json match actual build artifacts
  3. Test the workflow end-to-end on this PR to confirm it works

📚 Optional Improvements

  1. Add detect-changes integration for consistency
  2. Use setup-node-with-retry action for reliability
  3. Remove unrelated package.json formatting change (globals reordering)

Note: The workflow won't run successfully until issue #1 (missing dependency installation) is fixed. The action will fail because pnpm build requires node_modules to exist first.

Let me know if you need help implementing any of these changes!

@AbanoubGhadban
Copy link
Collaborator Author

⚠️ Expected CI Failure (Bootstrap Issue)

The Bundle Size CI check fails on this initial PR because:

  1. The size-limit-action compares bundle sizes between the PR branch and master
  2. master doesn't have size-limit installed yet
  3. When the action checks out master and tries to run size-limit, it fails

This is expected and only affects this first PR. Once merged, all subsequent PRs will work correctly because master will have size-limit installed.

Evidence the PR branch works correctly:

From CI logs, the PR branch successfully measured all bundles:

react-on-rails (full): 14863 bytes (passed ✅)
react-on-rails (client): 203 bytes (passed ✅)
react-on-rails-pro (full): 33987 bytes (passed ✅)
react-on-rails-pro (client): 503 bytes (passed ✅)
react-on-rails-pro-node-renderer: 7800 bytes (passed ✅)

The failure only occurred when trying to compare with master (which doesn't have size-limit yet).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

1-118: Add trailing newline to match coding guidelines.

Per the coding guidelines, all files must end with a newline character.

Apply this diff to the end of the file:

    }
  }
-}
+}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a411917 and 554273d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • .github/workflows/bundle-size.yml (1 hunks)
  • .size-limit.json (1 hunks)
  • package.json (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

ALWAYS ensure files end with a newline character before committing/pushing

Files:

  • package.json
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to /CHANGELOG.md : Update `/CHANGELOG.md` for user-visible changes (features, bug fixes, breaking changes, deprecations, performance improvements) to the open-source React on Rails gem and npm package
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to /CHANGELOG.md : Update `/CHANGELOG.md` for user-visible changes (features, bug fixes, breaking changes, deprecations, performance improvements) to the open-source React on Rails gem and npm package

Applied to files:

  • .size-limit.json
  • package.json
📚 Learning: 2025-09-16T08:01:11.146Z
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.

Applied to files:

  • .size-limit.json
  • package.json
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to lib/react_on_rails/*.rb : Create RBS signature files for new Ruby files in `lib/react_on_rails/` by adding corresponding `.rbs` file in `sig/react_on_rails/`, adding to Steepfile, and validating before committing

Applied to files:

  • .size-limit.json
📚 Learning: 2025-02-12T16:38:06.537Z
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.

Applied to files:

  • .size-limit.json
  • package.json
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: The `react_on_rails_pro/` directory has its own Prettier/ESLint configuration and must be linted separately

Applied to files:

  • .size-limit.json
  • package.json
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Exclude `/coverage`, `/tmp`, `/gen-examples`, `/packages/react-on-rails/lib`, `/node_modules`, `/spec/dummy/node_modules`, `/spec/dummy/tmp`, `/spec/dummy/app/assets/webpack`, `/spec/dummy/log`, `/spec/dummy/e2e/playwright-report`, `/spec/dummy/test-results` from IDE indexing

Applied to files:

  • .size-limit.json
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • .size-limit.json
  • package.json
📚 Learning: 2025-11-25T08:05:17.804Z
Learnt from: CR
Repo: shakacode/react_on_rails PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T08:05:17.804Z
Learning: Applies to sig/react_on_rails/**/*.rbs : In RBS type signature files, define type signatures that correspond to Ruby files in `lib/react_on_rails/`

Applied to files:

  • .size-limit.json
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • .size-limit.json
📚 Learning: 2025-07-08T05:57:29.630Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1745
File: node_package/src/RSCRequestTracker.ts:8-14
Timestamp: 2025-07-08T05:57:29.630Z
Learning: The global `generateRSCPayload` function in React on Rails Pro (RORP) is provided by the framework during rendering requests, not implemented in application code. The `declare global` statements are used to document the expected interface that RORP will inject at runtime.

Applied to files:

  • .size-limit.json
📚 Learning: 2025-01-23T18:20:45.824Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1687
File: spec/dummy/package.json:0-0
Timestamp: 2025-01-23T18:20:45.824Z
Learning: When adding or updating dependencies in spec/dummy/package.json, maintain version consistency with other package.json files in the codebase to avoid potential version conflicts.

Applied to files:

  • package.json
📚 Learning: 2025-09-25T17:44:48.481Z
Learnt from: ihabadham
Repo: shakacode/react_on_rails PR: 1825
File: package.json:74-75
Timestamp: 2025-09-25T17:44:48.481Z
Learning: stylelint-config-standard-scss automatically includes stylelint-scss as a transitive dependency through stylelint-config-recommended-scss, so there's no need to add stylelint-scss explicitly to devDependencies when using stylelint-config-standard-scss.

Applied to files:

  • package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: examples (3.4, latest)
  • GitHub Check: rspec-package-tests (3.4, latest)
  • GitHub Check: build-dummy-app-webpack-test-bundles (3.4, 22, latest)
  • GitHub Check: build
  • GitHub Check: pro-lint-js-and-ruby
  • GitHub Check: build-dummy-app-webpack-test-bundles
  • GitHub Check: build-dummy-app-webpack-test-bundles
  • GitHub Check: claude-review
🔇 Additional comments (6)
package.json (2)

89-90: Size-limit scripts added correctly.

The "size" and "size:json" scripts are properly configured and align with the workflow's invocation. The scripts will leverage the .size-limit.json configuration.


24-24: Size-limit and GitHub Actions configuration is compatible.

The workflow properly configures andresz1/size-limit-action@v1 with size-limit v12.0.0: Node 22 is pinned (exceeds v12's Node 20+ requirement), pnpm is explicitly set as the package_manager parameter, and the action supports this configuration. No version updates needed.

.github/workflows/bundle-size.yml (4)

3-21: Workflow triggers and path filtering look appropriate.

The pull_request and push triggers on the master branch with filtered paths (packages/**, package.json, pnpm-lock.yaml, .size-limit.json, and the workflow file) ensure the workflow runs only when relevant bundle or configuration changes occur.


26-28: Permissions are correctly scoped.

The workflow properly requests read access to contents and write access to pull-requests, enabling the size-limit action to post comments on PRs.


37-56: Setup and caching strategy follows best practices.

Node setup, pnpm installation, and pnpm store caching with hash-based key are well-configured and will optimize build times on repeated runs.


57-62: Verify that the "build" script generates all required artifacts at the paths specified in .size-limit.json.

The workflow invokes the "build" script (which runs workspace builds for react-on-rails, react-on-rails-pro, and react-on-rails-pro-node-renderer). Ensure:

  • The build script generates .js files in each lib/ directory matching the glob patterns and specific paths in .size-limit.json
  • No additional build steps are needed before the size-limit action runs
  • The build script is deterministic and produces consistent output

Run the verification script provided in the .size-limit.json review to confirm build output locations.

Comment on lines 1 to 107
[
{
"name": "react-on-rails (full)",
"path": "packages/react-on-rails/lib/*.js",
"gzip": true,
"limit": "20 kB"
},
{
"name": "react-on-rails (client)",
"path": "packages/react-on-rails/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "1 kB"
},
{
"name": "react-on-rails-pro (full)",
"path": "packages/react-on-rails-pro/lib/*.js",
"gzip": true,
"limit": "45 kB"
},
{
"name": "react-on-rails-pro (client)",
"path": "packages/react-on-rails-pro/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "2 kB"
},
{
"name": "react-on-rails-pro-node-renderer",
"path": "packages/react-on-rails-pro-node-renderer/lib/*.js",
"gzip": true,
"limit": "15 kB"
}
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add trailing newline to match coding guidelines.

Per the coding guidelines, all files must end with a newline character. The file currently ends at the closing bracket on line 32.

Apply this diff:

  {
    "name": "react-on-rails-pro-node-renderer",
    "path": "packages/react-on-rails-pro-node-renderer/lib/*.js",
    "gzip": true,
    "limit": "15 kB"
  }
-]
+]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[
{
"name": "react-on-rails (full)",
"path": "packages/react-on-rails/lib/*.js",
"gzip": true,
"limit": "20 kB"
},
{
"name": "react-on-rails (client)",
"path": "packages/react-on-rails/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "1 kB"
},
{
"name": "react-on-rails-pro (full)",
"path": "packages/react-on-rails-pro/lib/*.js",
"gzip": true,
"limit": "45 kB"
},
{
"name": "react-on-rails-pro (client)",
"path": "packages/react-on-rails-pro/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "2 kB"
},
{
"name": "react-on-rails-pro-node-renderer",
"path": "packages/react-on-rails-pro-node-renderer/lib/*.js",
"gzip": true,
"limit": "15 kB"
}
]
[
{
"name": "react-on-rails (full)",
"path": "packages/react-on-rails/lib/*.js",
"gzip": true,
"limit": "20 kB"
},
{
"name": "react-on-rails (client)",
"path": "packages/react-on-rails/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "1 kB"
},
{
"name": "react-on-rails-pro (full)",
"path": "packages/react-on-rails-pro/lib/*.js",
"gzip": true,
"limit": "45 kB"
},
{
"name": "react-on-rails-pro (client)",
"path": "packages/react-on-rails-pro/lib/ReactOnRails.client.js",
"gzip": true,
"limit": "2 kB"
},
{
"name": "react-on-rails-pro-node-renderer",
"path": "packages/react-on-rails-pro-node-renderer/lib/*.js",
"gzip": true,
"limit": "15 kB"
}
]
🤖 Prompt for AI Agents
.size-limit.json lines 1 to 32: the file is missing a trailing newline at EOF;
to fix, open .size-limit.json and add a single newline character after the final
closing bracket on line 32 so the file ends with a newline, then save the file.

[
{
"name": "react-on-rails (full)",
"path": "packages/react-on-rails/lib/*.js",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .size-limit.json

Repository: shakacode/react_on_rails

Length of output: 1042


🏁 Script executed:

# Check current state of lib directories
echo "=== Current lib directory contents ==="
for dir in packages/react-on-rails/lib packages/react-on-rails-pro/lib packages/react-on-rails-pro-node-renderer/lib; do
  echo "Directory: $dir"
  if [ -d "$dir" ]; then
    ls -la "$dir" 2>/dev/null || echo "Directory exists but empty or no read permission"
  else
    echo "Directory does not exist (likely needs build)"
  fi
  echo ""
done

# Check the build scripts
echo "=== Checking package.json build scripts ==="
fd package.json | head -5 | xargs -I {} sh -c 'echo "File: {}"; head -30 {}'

Repository: shakacode/react_on_rails

Length of output: 5177


🏁 Script executed:

# Check tsconfig.json files to understand build output
for file in packages/react-on-rails/tsconfig.json packages/react-on-rails-pro/tsconfig.json packages/react-on-rails-pro-node-renderer/tsconfig.json; do
  echo "=== $file ==="
  if [ -f "$file" ]; then
    cat "$file"
  else
    echo "File not found"
  fi
  echo ""
done

Repository: shakacode/react_on_rails

Length of output: 477


🏁 Script executed:

# List source files for each package
echo "=== packages/react-on-rails/src ==="
if [ -d "packages/react-on-rails/src" ]; then
  find packages/react-on-rails/src -type f \( -name "*.ts" -o -name "*.tsx" \) | sort
else
  echo "Directory not found"
fi

echo ""
echo "=== packages/react-on-rails-pro/src ==="
if [ -d "packages/react-on-rails-pro/src" ]; then
  find packages/react-on-rails-pro/src -type f \( -name "*.ts" -o -name "*.tsx" \) | sort
else
  echo "Directory not found"
fi

echo ""
echo "=== packages/react-on-rails-pro-node-renderer/src ==="
if [ -d "packages/react-on-rails-pro-node-renderer/src" ]; then
  find packages/react-on-rails-pro-node-renderer/src -type f \( -name "*.ts" -o -name "*.tsx" \) | sort
else
  echo "Directory not found"
fi

Repository: shakacode/react_on_rails

Length of output: 5131


🏁 Script executed:

# Check size-limit documentation or look at similar projects
# Also check if there's any build bundling happening (webpack, vite, etc.)

echo "=== Checking for build config files ==="
find packages/react-on-rails -maxdepth 2 -type f \( -name "webpack.config.*" -o -name "vite.config.*" -o -name "rollup.config.*" \) 2>/dev/null

echo ""
echo "=== Checking size-limit package ==="
rg -A 5 "size-limit" package.json | head -20

echo ""
echo "=== Checking if lib entries are meant to be entry point files ==="
grep -r "outFile\|bundle" packages/react-on-rails/tsconfig.json packages/react-on-rails-pro/tsconfig.json 2>/dev/null || echo "No bundling config found"

echo ""
echo "=== How TypeScript compiles multiple files ==="
echo "TypeScript with outDir compiles each .ts file to a separate .js file"
echo "The glob '*.js' will match ALL .js files in the directory, not just entry points"

Repository: shakacode/react_on_rails

Length of output: 154


Replace glob patterns with specific entry point file names to ensure accurate size measurements.

The TypeScript configuration outputs all files from src/**/* to separate .js files in lib/. The glob patterns *.js (lines 4, 16, 28) will match not only the entry point files (ReactOnRails.full.js, ReactOnRails.client.js) but also all internal module files (e.g., Authenticity.js, ClientRenderer.js, ComponentRegistry.js). This causes size-limit to measure the sum of all .js files rather than just the intended entry points.

Change the glob patterns to specific file names:

  • Line 4: "packages/react-on-rails/lib/ReactOnRails.full.js"
  • Line 16: "packages/react-on-rails-pro/lib/ReactOnRails.full.js"
  • Line 28: "packages/react-on-rails-pro-node-renderer/lib/ReactOnRailsProNodeRenderer.js"
🤖 Prompt for AI Agents
In .size-limit.json around line 4 (and similarly adjust lines 16 and 28), the
glob "packages/react-on-rails/lib/*.js" causes size-limit to pick up all
compiled module files instead of the intended entry points; replace the glob
with the explicit entry path "packages/react-on-rails/lib/ReactOnRails.full.js"
(and likewise set line 16 to
"packages/react-on-rails-pro/lib/ReactOnRails.full.js" and line 28 to
"packages/react-on-rails-pro-node-renderer/lib/ReactOnRailsProNodeRenderer.js")
so size-limit measures only the intended bundle files.

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Thank you for implementing bundle size monitoring! This is a valuable addition. Here's my review:

Critical Issues That Must Be Fixed

1. Missing pnpm install step

The workflow sets up pnpm caching but never runs pnpm install --frozen-lockfile. The build will fail without dependencies installed. Add this step after the cache setup (see lint-js-and-ruby.yml:120-123 for reference).

2. Inconsistent Node setup pattern

This repo uses a custom .github/actions/setup-node-with-retry action in all other workflows to handle V8 bytecode crashes (see analysis/v8-crash-retry-solution.md). This workflow should use it too, with node-version pinned to '22.11.0' like other workflows.

3. Duplicate build execution

The workflow runs build twice: once via build_script: build parameter, and again in the size npm script. This wastes CI time. Either remove build_script from the action config, or add skip_step: build if building explicitly beforehand.

Important Concerns

4. Verify paths locally

Per CLAUDE.md testing requirements, please verify locally before merging:

pnpm run build
pnpm run size  # Should show 5 entries

The test plan shows "CI workflow runs successfully on this PR" is still unchecked.

5. Consider SHA pinning

Using andresz1/size-limit-action@v1 is a floating tag. Consider pinning to a specific SHA for supply chain security (though I notice other workflows also use tags).

Minor Suggestions

  • Consider adding this workflow to required status checks once proven stable
  • Document in CLAUDE.md when/how to update size limits
  • The globals package moved in dependencies - was this intentional reordering?

Summary

Must fix: Add pnpm install step, use setup-node-with-retry action, fix duplicate build
Should verify: Test locally and wait for CI to pass before merging
Overall: Good feature with solid config, but needs workflow fixes to work correctly

Let me know if you'd like help with these fixes!

@claude
Copy link

claude bot commented Nov 30, 2025

PR Review: Bundle Size CI Check

Thanks for adding bundle size monitoring! This is a valuable addition to the CI pipeline. Here's my detailed review:

✅ Strengths

  1. Good automation choice: Using size-limit with GitHub Actions integration provides automated PR comments showing size deltas
  2. Comprehensive coverage: Tracking all three packages (react-on-rails, react-on-rails-pro, react-on-rails-pro-node-renderer)
  3. Multiple compression formats: Tracking raw, gzip, and brotli sizes gives a complete picture
  4. Proper path filtering: The workflow only runs when relevant files change
  5. Follows project conventions: Uses pnpm, ubuntu-22.04, and proper caching setup

🔍 Issues & Recommendations

1. CRITICAL: Package.json Scripts Don't Build First

In the final version, the package.json scripts are:

"size": "size-limit",
"size:json": "size-limit --json"

But the PR description says:

Local Commands

  • pnpm run size - Check bundle sizes

Problem: Running pnpm run size locally will fail if packages aren't already built, because size-limit needs the lib/*.js files to exist.

Evidence from commit history: One commit message says "Ensure size scripts build packages first", but the final code doesn't include the build step.

Fix needed: Update package.json scripts to:

"size": "pnpm run build && size-limit",
"size:json": "pnpm run build && size-limit --json"

Or document that users must run pnpm run build first before pnpm run size.

2. Workflow Action Version Pinning ⚠️

The workflow uses:

uses: andresz1/size-limit-action@v1

Recommendation: Pin to a specific commit SHA or full version for security and reproducibility:

uses: andresz1/[email protected]  # or @SHA

This follows GitHub Actions security best practices and prevents unexpected breaking changes.

3. Missing CHANGELOG Entry ⚠️

According to CLAUDE.md:

Update CHANGELOG.md for user-visible changes only

Bundle size monitoring is a developer-facing feature (not user-visible), so this likely doesn't need a changelog entry. But if you want users to know about bundle size guarantees, consider adding a brief note.

4. Path Glob Pattern Potential Issue 🤔

The config uses:

"path": "packages/react-on-rails/lib/*.js"

Question: Does this intentionally include ALL .js files in lib/, or should it target specific bundles?

For example, if there are multiple files:

  • ReactOnRails.full.js
  • ReactOnRails.client.js
  • ReactOnRails.server.js
  • Helper files

The *.js glob will sum ALL of them together. Is this intentional?

Suggestion: Be explicit about which files to measure:

{
  "name": "react-on-rails (full bundle)",
  "path": "packages/react-on-rails/lib/ReactOnRails.full.js",
  "gzip": true,
  "limit": "20 kB"
}

This makes it clearer what's being measured and prevents helper files from affecting the total.

5. Limits Seem Arbitrary 📊

The PR description shows current sizes (e.g., "14.86 kB") but sets limits with significant headroom (e.g., "20 kB" = 35% buffer).

Questions:

  • Are these limits based on actual current sizes?
  • What's the reasoning for the buffer amounts?
  • Should limits be tighter to catch creep earlier?

Suggestion: Document the methodology in a comment or README:

[
  {
    "name": "react-on-rails (gzip)",
    "path": "packages/react-on-rails/lib/*.js",
    "gzip": true,
    "limit": "20 kB"  // Current: 14.86 kB, 35% buffer for growth
  }
]

🔧 Testing Recommendations

Per CLAUDE.md's "CRITICAL LOCAL TESTING REQUIREMENTS":

Before merging, verify:

# 1. Test clean install (most critical)
rm -rf node_modules
pnpm install --frozen-lockfile

# 2. Test build scripts
pnpm run build

# 3. Test size scripts work
pnpm run size

# 4. Verify limits are accurate
# Check that current sizes are well under limits
pnpm run size:json

# 5. Test local development scenario
# Make a small change to a package, rebuild, check size
echo "// test comment" >> packages/react-on-rails/src/ReactOnRails.ts
pnpm run size
git checkout packages/react-on-rails/src/ReactOnRails.ts

📝 Minor: Code Quality

package.json formatting: The change moved globals package - was this intentional or an auto-sort? If intentional, consider mentioning why in the commit message.

🎯 Summary

Must fix before merge:

  1. ✅ Add build step to size scripts OR document the requirement

Should consider:
2. Pin workflow action version
3. Clarify path glob intentions
4. Document limit methodology

Nice to have:
5. Test all scenarios listed above

Overall, this is a solid addition to the CI pipeline! The main concern is ensuring developers can run size checks locally without confusion.


Review based on project's CLAUDE.md guidelines and CI best practices

@coderabbitai coderabbitai bot added the full-ci label Nov 30, 2025
@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Thank you for adding bundle size monitoring! This is a valuable addition to prevent unexpected size regressions. Here's my detailed review:


✅ Strengths

  1. Smart dynamic limits approach: Comparing against base branch + 0.5KB threshold is more practical than static limits
  2. Proper permissions: contents: read and pull-requests: write follows least-privilege principle
  3. Path-based triggering: Only runs when relevant files change
  4. Good package coverage: Tracks all three packages (OS + Pro)
  5. Local testing commands: pnpm run size makes it easy for developers to check locally

🔴 Critical Issues

1. Missing checkout before Node/pnpm setup

Issue: Steps 21-29 set up Node and pnpm BEFORE checking out any code. This will fail because:

  • actions/setup-node@v4 and pnpm/action-setup@v4 run with no repository checked out
  • They can't access .nvmrc, package.json, or any project files

Fix: Move checkout BEFORE setup steps

@claude
Copy link

claude bot commented Nov 30, 2025

Critical Issue #2: Build runs twice

The workflow runs pnpm run build manually on line 42, then size-limit-action runs it again via build_script: build on line 90. This adds 2-3 minutes to CI time.

Fix: Either remove the manual build on line 42, or change the build_script parameter if you need the manual build for base branch measurement.

Critical Issue #3: No pnpm caching

Installing dependencies twice (base + PR branch) without caching adds 1-2 minutes to CI. See other workflows like .github/workflows/lint-js-and-ruby.yml for pnpm caching patterns.

@AbanoubGhadban AbanoubGhadban changed the base branch from master to feature/bundle-size-ci-base November 30, 2025 16:03
@claude
Copy link

claude bot commented Nov 30, 2025

⚠️ Medium Priority Issues

4. Inconsistent naming in .size-limit.json vs PR description

PR description says:

  • "react-on-rails (full)" - 14.86 kB
  • "react-on-rails (client)" - 203 B

Config has only:

  • "react-on-rails (gzip)"

The glob pattern packages/react-on-rails/lib/*.js will match ALL js files. If there are multiple bundles per package, use specific paths instead of globs.

5. No error handling in Node script

The inline Node.js script (lines 56-82) has no error handling. What if /tmp/base-sizes.json is malformed or file write fails? Add try-catch and process.exit(1) on errors.

6. Workflow doesn't run on push to master

Consider running on push to master branch to catch regressions and build historical data.

@claude
Copy link

claude bot commented Nov 30, 2025

📋 Testing Recommendations

According to CLAUDE.md guidelines, before merging you MUST:

  1. Test the workflow runs successfully on this PR (currently marked as [ ] in test plan)

    • Push a commit and verify the workflow runs
    • Check that it posts a comment to the PR
  2. Test failure scenario

    • Temporarily lower a limit to trigger failure
    • Verify CI fails with clear error message
  3. Test with actual size increase

    • Make a change that increases bundle size by 0.3KB → verify workflow passes
    • Make a change that increases by 0.7KB → verify workflow fails
  4. Test local commands

    • Run pnpm run size locally
    • Run pnpm run size:json locally
    • Verify output matches CI

From CLAUDE.md:

CRITICAL - LOCAL TESTING REQUIREMENTS:

  1. NEVER claim a test is "fixed" without running it locally first

@claude
Copy link

claude bot commented Nov 30, 2025

Summary

This is a solid foundation for bundle size monitoring! 🎉

Priority fixes before merge:

  1. Fix checkout order (Critical - will fail immediately)
  2. ⚠️ Remove duplicate build or clarify why it's needed (Medium - wastes 2-3 min)
  3. ⚠️ Add pnpm caching (Medium - saves 1-2 min)
  4. Test the workflow runs successfully (Critical - not yet verified)

Nice-to-haves for follow-up:

  • Clarify which bundles are measured (glob vs specific files)
  • Add error handling to Node script
  • Run on master branch for historical data
  • Add workflow status badge to README
  • Make 0.5KB threshold configurable via workflow input

🔒 Security & Performance

Security: Good use of GITHUB_TOKEN, proper permissions
📊 Performance: Estimated 5-8 minutes, could save ~3 minutes with caching


Great work on implementing this feature! The main blocker is Issue #1 (checkout order). Looking forward to seeing this merged!

Review performed by Claude Code following project guidelines in CLAUDE.md

@github-actions
Copy link
Contributor

github-actions bot commented Nov 30, 2025

size-limit report 📦

Path Size
react-on-rails (raw) 40.67 KB (0%)
react-on-rails (gzip) 14.51 KB (0%)
react-on-rails (brotli) 12.16 KB (0%)
react-on-rails-pro (raw) 91.75 KB (0%)
react-on-rails-pro (gzip) 33.19 KB (0%)
react-on-rails-pro (brotli) 27.23 KB (0%)
react-on-rails-pro-node-renderer (raw) 24.64 KB (0%)
react-on-rails-pro-node-renderer (gzip) 7.62 KB (0%)
react-on-rails-pro-node-renderer (brotli) 6.52 KB (0%)

@claude
Copy link

claude bot commented Nov 30, 2025

Bundle Size CI Check - Code Review

Thank you for implementing bundle size monitoring! This is a valuable addition to the CI pipeline. Here's my detailed feedback:

✅ Strengths

  1. Smart Dynamic Limits: The approach of using base branch sizes + 0.5KB threshold is excellent - it prevents accidental bloat while avoiding brittle fixed limits
  2. Comprehensive Coverage: Tracking all three packages (react-on-rails, react-on-rails-pro, react-on-rails-pro-node-renderer) ensures complete monitoring
  3. Clear Documentation: The PR description clearly shows what's being tracked and current sizes
  4. Good Path Filtering: Only triggers on relevant file changes

🔍 Issues & Concerns

1. Dependencies ✅

The workflow uses size-limit and @size-limit/file:

  • Line 63: "size-limit": "^12.0.0" ✅ Present in package.json
  • Line 24: "@size-limit/file": "^12.0.0" ✅ Present in package.json

Status: Dependencies are correctly included. Good!

2. Missing Error Handling in Node Script ⚠️

Lines 54-82 in bundle-size.yml: The Node.js script that sets dynamic limits has no error handling.

Risk: If /tmp/base-sizes.json is malformed or missing, the workflow will fail with unclear errors.

Recommendation: Add error handling or wrap in try/catch for better error messages.

3. .size-limit.json Configuration Issue 🚨

CRITICAL: The .size-limit.json file is missing the limit property entirely!

Current:

[
  {
    "name": "react-on-rails (gzip)",
    "path": "packages/react-on-rails/lib/*.js",
    "gzip": true
  }
]

This means the workflow depends entirely on the dynamic limit-setting script. If that script fails, you get no protection.

Recommendation: Add fallback static limits based on your PR description:

[
  {
    "name": "react-on-rails (gzip)",
    "path": "packages/react-on-rails/lib/*.js",
    "gzip": true,
    "limit": "20 KB"
  },
  {
    "name": "react-on-rails-pro (gzip)",
    "path": "packages/react-on-rails-pro/lib/*.js",
    "gzip": true,
    "limit": "45 KB"
  },
  {
    "name": "react-on-rails-pro-node-renderer (gzip)",
    "path": "packages/react-on-rails-pro-node-renderer/lib/*.js",
    "gzip": true,
    "limit": "15 KB"
  }
]

4. Testing per CLAUDE.md

Your test plan shows good local testing! The remaining item is verifying the CI workflow runs on this PR and posts a comment.

📝 Code Style Suggestions

Extract inline Node.js: The inline Node script (lines 56-82) could be extracted to .github/scripts/set-size-limits.js for better:

  • Maintainability
  • Error handling
  • Testing
  • Readability

🎯 Summary

Must Fix Before Merge:

  1. ❗ Add fallback limit values to .size-limit.json
  2. ❗ Add error handling to the Node.js script
  3. ❗ Verify the workflow runs on this PR

Should Fix (can be follow-up):

  1. Extract inline Node.js to separate script file
  2. Add verification step showing updated limits
  3. Add docs to CLAUDE.md about bundle size monitoring

Nice to Have:

  1. Make 0.5KB threshold configurable
  2. More granular per-file tracking

Great work overall! The dynamic limits approach is very smart. 🎉

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Hi @AbanoubGhadban! Thanks for adding bundle size monitoring. This is a valuable addition to prevent bundle size regressions. Here's my review:

✅ Positive Aspects

  1. Correct Change: Switching from npx size-limit to pnpm exec size-limit is the right approach for this monorepo

    • Ensures the locally installed version is used (from pnpm workspace)
    • Consistent with the project's pnpm-first approach (see CLAUDE.md: "Only use pnpm as the JS package manager")
    • Avoids potential version mismatches with npx
  2. Good Implementation: The workflow design is solid:

    • Dynamic limits (base + 0.5KB) prevent flaky failures from minor variations
    • Separate base/PR checkouts ensure accurate comparisons
    • Proper use of --frozen-lockfile for reproducible builds
  3. Well Documented: Clear PR description with current sizes and limits

🔍 Observations & Suggestions

1. Consistency Check (Minor)

Line 86 uses andresz1/size-limit-action with package_manager: pnpm. Verify this action properly handles pnpm workspaces. If there are any issues, you might need to use pnpm exec size-limit directly instead of relying on the action's built-in execution.

2. Error Handling (Enhancement)

Consider adding error handling if /tmp/base-sizes.json is empty or malformed:

- name: Build and measure base branch
  run: |
    pnpm run build
    pnpm exec size-limit --json > /tmp/base-sizes.json
    echo "Base branch sizes:"
    cat /tmp/base-sizes.json
    # Verify the file is valid JSON
    node -e "JSON.parse(require('fs').readFileSync('/tmp/base-sizes.json', 'utf8'))"

This would catch build failures early rather than failing in the dynamic limits step.

3. Testing Verification (Critical per CLAUDE.md)

Your test plan shows:

  • Verified locally
  • CI workflow runs successfully on this PR

Per the project's CRITICAL REQUIREMENTS in CLAUDE.md:

NEVER claim a test is "fixed" without running it locally first

I see the CI is currently IN_PROGRESS. Make sure to:

  • Wait for the CI to complete successfully
  • Verify the size-limit-action posts a comment with size comparison
  • Test that exceeding limits actually fails the check (you can temporarily lower limits to verify)

4. Configuration Completeness

The .size-limit.json file looks good, but it's missing limit fields (which are set dynamically). Consider documenting in a comment or README why limits aren't in the config file:

[
  {
    "name": "react-on-rails (gzip)",
    "path": "packages/react-on-rails/lib/*.js",
    "gzip": true
    // Note: limits are set dynamically in CI (base + 0.5KB)
  }
]

5. Missing CHANGELOG Entry?

This is a user-visible addition (new CI check, new npm scripts). Per CLAUDE.md:

Update CHANGELOG.md for user-visible changes only (features, bug fixes, breaking changes, deprecations, performance improvements)

Consider adding an entry under a "Developer Experience" or "Chores" section in the next release section of CHANGELOG.md.

🎯 Action Items

Before merging:

  1. ✅ Ensure CI passes completely (currently in progress)
  2. ✅ Verify the size-limit-action posts a comparison comment
  3. ⚠️ Consider adding error handling for malformed base-sizes.json
  4. 📝 Consider adding a CHANGELOG entry (optional - this might be internal-only)

🚀 Overall Assessment

This is a clean, focused PR that improves the project's CI infrastructure. The change from npx to pnpm exec is correct and follows project conventions. Once CI passes and you've verified the workflow behaves as expected, this should be good to merge!


Security: ✅ No security concerns
Performance: ✅ Minimal CI overhead (only runs on package changes)
Best Practices: ✅ Follows project conventions
Test Coverage: ⏳ Waiting for CI to complete

Great work! 🎉

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Thank you for adding bundle size monitoring! This is a valuable addition to catch performance regressions. Here's my review:


✅ What's Good

  1. Smart dynamic threshold approach: The workflow calculates limits as base + 0.5KB rather than hardcoded values. This prevents false positives from legitimate optimizations while still catching bloat.

  2. Proper workflow trigger paths: Correctly triggers on relevant file changes (packages/**, package.json, pnpm-lock.yaml, etc.).

  3. Using pnpm exec instead of npx: The change from npx size-limit to pnpm exec size-limit is correct for this pnpm-based monorepo (line 43).

  4. Appropriate permissions: contents: read and pull-requests: write follows the principle of least privilege.


🚨 Critical Issue: Test File Left in Source Code

The bloat.ts file should NOT be committed to the repository.

Location: packages/react-on-rails/src/bloat.ts

Problem:

  • This file contains ~550 bytes of dummy string data meant to test if the CI catches bundle size increases
  • It's currently in the source directory and will be included in production builds
  • It's not imported anywhere, making it dead code that still affects bundle size
  • The file's comment says "Test file to verify bundle size CI catches increases"

Evidence it's a test artifact:

// Test file to verify bundle size CI catches increases
export const BLOAT_DATA_1 = 'xyzabc123456789!@#$%^&*()_+QWERTYUIOPASDFGHJKLZXCVBNM';
// ... 9 more similar exports

Required action: This file must be deleted before merging. The CI workflow has already been tested (it correctly failed when bloat was added), so the test succeeded.


📋 Recommendations

1. Remove the Test File

git rm packages/react-on-rails/src/bloat.ts
git commit --amend --no-edit
git push --force-with-lease

2. Consider Tree-Shaking Verification

The current .size-limit.json uses glob patterns (lib/*.js) which measures ALL built files. Consider:

  • Adding specific entry point checks (e.g., just ReactOnRails.full.js)
  • Verifying that unused exports are properly tree-shaken
  • Testing that the bloat.ts exports (if accidentally added) wouldn't affect the bundle if not imported

3. Documentation

Consider adding to the README or CLAUDE.md:

  • How to run size checks locally (pnpm run size)
  • What to do when CI fails (investigate what changed, optimize, or update limits)
  • The 0.5KB threshold rationale

4. CI Failure Handling

The PR description shows:

  • [ ] CI workflow runs successfully on this PR

This is expected to fail because bloat.ts was added intentionally to test detection. Once removed, this should pass.


🔍 Minor Observations

Workflow Design Question

The workflow checks out the base branch first, measures it, then checks out PR branch. This is clever but means:

  • Two full pnpm install operations per PR (slower CI)
  • Potential for base branch measurement to fail if dependencies changed

Alternative approach to consider (for future iteration):

  • Cache base branch measurements in a GitHub artifact or comment
  • Only re-measure base when package.json/pnpm-lock.yaml changes

Size Threshold Value

The 0.5KB threshold is reasonable for catching regressions, but:

  • A single new feature could legitimately add >0.5KB
  • Consider if different thresholds for different packages make sense (e.g., core vs. pro)

✅ After Fixing

Once bloat.ts is removed:

  1. The bundle size check should pass
  2. The PR will have successfully added bundle monitoring
  3. Future PRs will be protected against accidental bundle bloat

Summary

Must fix before merge:

  • ❌ Remove packages/react-on-rails/src/bloat.ts (test artifact in production code)

Good to have:

  • 📚 Add documentation about using the size checks
  • 🎯 Consider more granular entry point checking

Overall: Excellent addition to the CI pipeline! Just needs the test file cleaned up.


Review performed by Claude Code following project conventions from CLAUDE.md

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review

✅ Overall Assessment

This is a minimal, focused fix that improves consistency by using pnpm exec instead of npx. The change is sound and aligns with the project's standardization on pnpm.


📋 Review Details

Code Quality: Excellent

  • ✅ The change from npx size-limit to pnpm exec size-limit is correct
  • ✅ Consistent with project's package manager choice (pnpm, not npm)
  • ✅ Aligns with other pnpm commands in the workflow (e.g., pnpm install, pnpm run build)
  • ✅ The CI check passed successfully (size job: SUCCESS)

Best Practices: Good

  • ✅ Using pnpm exec ensures the command runs from the local node_modules/.bin managed by pnpm
  • ✅ Avoids potential version conflicts or unexpected behavior from npx's package resolution
  • ✅ Matches the project's documented standard: "Never run npm commands, only equivalent pnpm ones" (CLAUDE.md:89)

Potential Issues: None Found

  • No bugs detected
  • No security concerns
  • No performance regressions

Testing: Verified

  • ✅ The workflow ran successfully with this change
  • ✅ The change is extremely low-risk (just command wrapper)
  • Note: The test plan shows "CI workflow runs successfully on this PR" is still unchecked, but I can see the size job completed with SUCCESS

💡 Suggestions

1. Complete Test Plan Checklist

The PR body shows:

- [ ] CI workflow runs successfully on this PR

Since the CI has now run and passed, consider updating this to:

- [x] CI workflow runs successfully on this PR

2. Consider Consistency Check Across Workflows

While this change is correct, you might want to verify other workflow files don't have similar npx usage that should be pnpm exec:

grep -r "npx" .github/workflows/ --exclude-dir=node_modules

If found, those could be addressed in a follow-up PR for consistency.


🎯 Recommendation

APPROVE - This is a clean, minimal fix that improves tooling consistency. The change is:

  • Low risk
  • Well-tested (CI passed)
  • Aligned with project standards
  • Ready to merge

Great work keeping the project's tooling consistent! 🚀

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review Feedback

Thanks for implementing bundle size monitoring! This is a valuable addition to the CI pipeline. Here's my review:

✅ Strengths

  1. Good tooling choice: Using size-limit is a solid choice - it's well-maintained and widely used
  2. Dynamic limits approach: The dynamic limit calculation (base + 0.5KB) is smart - it prevents accidental size increases while being flexible
  3. Comprehensive tracking: Tracking raw, gzip, and brotli sizes gives good visibility into compression effectiveness
  4. Correct package manager usage: Good fix using pnpm exec instead of npx (line 43 of workflow)

🔍 Issues & Suggestions

1. Missing size limits (Potential CI failure)

Your .size-limit.json is missing limit fields. According to the PR description, you have defined limits, but they're not in the configuration file:

{
  "name": "react-on-rails (gzip)",
  "path": "packages/react-on-rails/lib/*.js",
  "gzip": true,
  "limit": "20 kB"  // ⚠️ Missing in actual file
}

Why this matters: While the workflow sets dynamic limits at runtime, the local pnpm run size command will have no baseline to compare against. Also, if the dynamic limit calculation fails, there's no fallback.

Recommendation: Add static limits as a fallback safety net, even though they'll be overridden by the workflow.

2. Triple measurement may be excessive

You're measuring raw, gzip, AND brotli for each package (9 total measurements for 3 packages).

Why this matters:

  • Most users care about gzip size (universal web standard)
  • Brotli is great but not as universally supported
  • Raw size is less meaningful for web assets
  • More measurements = slower CI, noisier PR comments

Recommendation: Consider tracking only gzip (or gzip + brotli) unless there's a specific reason to track raw sizes.

3. Workflow order could be optimized

The workflow checks out the base branch first, then the PR branch. This works but means any workflow changes in the PR won't be used when measuring the base.

Why this matters: If you update the workflow in the same PR (like you did here), the base measurement uses the old workflow logic.

Recommendation: This is actually fine for your use case since you want consistency. Just noting it for awareness.

4. Missing validation step

The PR description shows checklist item [ ] CI workflow runs successfully on this PR is unchecked.

Critical per CLAUDE.md: The project guidelines emphasize NEVER claiming something is fixed without local verification, and avoiding CI iteration cycles.

Recommendation:

  • Test locally: pnpm run size and verify output makes sense
  • Verify the workflow completes successfully before merging
  • Per the guidelines: Don't merge with unchecked test plan items

5. No documentation update

Users may not know about the new pnpm run size commands.

Recommendation: Consider adding a brief mention in the main README or developer docs about bundle size monitoring.

🧪 Testing Recommendations

Per CLAUDE.md's local testing requirements:

# 1. Test size commands work
pnpm run size
pnpm run size:json

# 2. Verify paths are correct
ls -la packages/react-on-rails/lib/*.js
ls -la packages/react-on-rails-pro/lib/*.js
ls -la packages/react-on-rails-pro-node-renderer/lib/*.js

# 3. Test that limits work (if you add them back)
# Temporarily set a very low limit and verify it fails

# 4. Verify workflow YAML syntax
gh workflow view "Bundle Size" --yaml

📋 Security & Performance

  • ✅ No security concerns
  • ✅ Workflow permissions are correctly scoped (contents: read, pull-requests: write)
  • ✅ Using --frozen-lockfile for reproducibility
  • ⚠️ CI will be slower with 9 measurements (see suggestion Make work with turbolinks and better helper #2)

🎯 Action Items Before Merge

  1. HIGH: Verify CI workflow completes successfully on this PR
  2. MEDIUM: Consider reducing measurements from 9 to 3-6 (drop raw or brotli)
  3. LOW: Add static limit fields to .size-limit.json as fallback
  4. LOW: Update test plan checkbox when CI passes

Overall Assessment

This is a solid implementation of bundle size monitoring! The dynamic limit approach is elegant. Main concerns are around completeness (missing limits, unchecked test plan) and potential noise from too many measurements. Once CI passes and you verify it works as expected, this will be a valuable addition to the project.

Great work! 🚀

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Great work on adding bundle size monitoring! This is a valuable addition to the CI pipeline. Here's my detailed review:


✅ Strengths

  1. Smart Dynamic Limits: The approach of setting dynamic limits based on base branch + 0.5KB is excellent. This prevents both false positives and drift over time.

  2. Comprehensive Tracking: Monitoring raw, gzip, and brotli sizes for all three packages provides good visibility into bundle size impact across compression methods.

  3. Good CI Integration: The workflow correctly runs only on relevant file changes, reducing unnecessary CI runs.

  4. Clean Script Design: The bin/compare-bundle-sizes script has good error handling with cleanup traps and clear output formatting.

  5. Developer Tooling: Providing local commands (pnpm run size) is great for developers to check before pushing.


🐛 Critical Issue: Missing Execute Permission

File: bin/compare-bundle-sizes

The script is missing executable permissions. Without this, users will get Permission denied when trying to run it.

Fix: Run chmod +x bin/compare-bundle-sizes and commit the change.


⚠️ Potential Issues

1. Security: Command Injection Risk

File: bin/compare-bundle-sizes (lines 77-133)

The script injects JSON data directly into a Node.js command which could be vulnerable if size-limit output ever contains special characters. Consider writing to temp files instead of string interpolation.

2. Error Handling: Missing Validation

File: bin/compare-bundle-sizes (lines 59, 68)

The script doesn't validate that size-limit succeeded before using the output. Add checks to ensure BASE_SIZES and CURRENT_SIZES are not empty.

3. Edge Case: Empty currentSizes Array

File: bin/compare-bundle-sizes (line 96)

If currentSizes is empty, Math.max() returns -Infinity, causing formatting issues. Add a length check with a sensible default.

4. Documentation: THRESHOLD Value

The 512-byte (0.5KB) threshold appears in two places. Consider documenting why this value was chosen to help future maintainers.


🎯 Overall Assessment

Quality: Good ⭐⭐⭐⭐
Security: Minor concerns ⚠️
Performance: Excellent ✅
Test Coverage: CI validated ✅

Recommendation: Approve with requested changes

  1. Fix executable permission (critical)
  2. Consider security improvements (recommended)
  3. Add error handling (recommended)

Great contribution! The dynamic threshold approach is particularly clever.

🤖 Review generated with Claude Code

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review: Bundle Size CI Check

Thank you for this PR! Adding automated bundle size monitoring is a valuable addition.

Strengths

  1. Good architecture - Clean separation between CI workflow, configuration, and utility scripts
  2. Useful local tooling - The bin/compare-bundle-sizes and bin/skip-bundle-size-check scripts provide great DX
  3. Well-documented - Clear comments in scripts and the skip-branch file
  4. Smart threshold approach - Dynamic limits (base + 0.5KB) prevent false positives
  5. Comprehensive tracking - Monitoring raw, gzip, and brotli sizes for all packages

Critical Issues

1. Shell scripts missing executable permissions

The bin scripts are not executable. Fix with:

  • chmod +x bin/compare-bundle-sizes bin/skip-bundle-size-check
  • git add bin/compare-bundle-sizes bin/skip-bundle-size-check

This is critical - users won't be able to run these scripts directly.

2. Path references need verification

The .size-limit.json references paths like packages/react-on-rails/lib/*.js. Per CLAUDE.md guidelines on managing file paths, these MUST be verified after build. If the directory structure changes in the future, this could silently break.

Important Issues

3. CI workflow skip-check logic - The tr -d removes ALL whitespace. Using xargs for trimming would be safer.

4. Missing validation in skip-bundle-size-check script - Should verify the branch hasn't already been skipped.

5. Inconsistent error handling - Line 91 in scripts/bundle-size.mjs has unnecessary return before process.exit(1).

6. Magic numbers - The calculation maxNameLen + 2 + 12 + 12 + 20 + 12 is fragile. Consider named constants.

7. Hardcoded ANSI colors - Consider using chalk library for better cross-platform compatibility.

8. No automated tests - Missing unit/integration tests for the utility scripts.

9. Missing documentation - Should add bundle size monitoring section to CLAUDE.md.

10. Command injection risk - compare-bundle-sizes accepts user input without validation.

Action Items

Must fix before merge:

  1. Add executable permissions to bin scripts
  2. Verify paths in .size-limit.json exist after build
  3. Improve skip-check logic in CI workflow

Should fix:
4. Remove unnecessary return before process.exit(1)
5. Add documentation to CLAUDE.md
6. Add basic error handling tests

Overall Assessment

This is a solid PR! The implementation is generally clean and well-thought-out. Main issues are missing executable permissions (critical) and path verification needed (per project guidelines).

Once the critical issues are addressed, this will be a great addition to the CI pipeline. The local tooling especially is excellent for developers.

Recommendation: Request changes for items 1-3, then approve after fixes.

@claude
Copy link

claude bot commented Nov 30, 2025

Code Review - Bundle Size CI Check

Thank you for implementing bundle size monitoring! This is a valuable addition to prevent performance regressions. Here's my detailed review:

✅ Strengths

  1. Excellent approach: Dynamic limits (base + threshold) is much better than hardcoded limits
  2. Well-structured code: Clean separation of concerns with the scripts/bundle-size.mjs utility
  3. Comprehensive coverage: Tracks raw, gzip, and brotli sizes for all packages
  4. Good UX: Skip mechanism for intentional size increases is pragmatic
  5. Proper tooling: Local comparison script (bin/compare-bundle-sizes) is helpful for developers

🐛 Critical Issues

1. Missing Error Handling in Workflow (bundle-size.yml:67,79)

The workflow assumes pnpm exec size-limit --json will succeed, but if the build fails or size-limit errors, it will create invalid JSON files that break downstream steps.

Recommendation: Add error handling:

- name: Build and measure base branch
  run: |
    pnpm run build
    pnpm exec size-limit --json > /tmp/base-sizes.json || (echo "Failed to measure base sizes" && exit 1)

2. Shell Script Portability (bin/compare-bundle-sizes:51-52)

The script uses || true to suppress errors from git fetch/checkout, which could hide real problems.

Recommendation: Be more explicit about expected failures.

⚠️ Security Concerns

3. Unvalidated User Input (bundle-size.mjs:63-64,103-106)

The script parses command-line arguments but does not validate them before using as file paths. While this is a development tool, adding validation for file paths would prevent potential issues.

Recommendation: Add explicit validation to ensure file paths do not contain directory traversal attempts.

📝 Code Quality Issues

4. Inconsistent Exit Code Handling (bundle-size.mjs:91)

Line 91 has unnecessary return before process.exit(1):

return process.exit(1);  // Line 91

Fix: Remove return since process.exit() terminates immediately:

console.error(`${colors.red}Error reading ${filePath}: ${error.message}${colors.reset}`);
process.exit(1);

5. Magic Numbers in String Padding (bundle-size.mjs:154,219)

const diffPart = diffStr.padStart(20 + 9);  // Why 20 + 9 = 29?

The + 9 accounts for ANSI color codes, but this is not documented.

Recommendation: Add constants or comments:

const ANSI_CODE_LENGTH = 9; // Length of color escape sequences
const diffPart = diffStr.padStart(20 + ANSI_CODE_LENGTH);

6. Grep Output Suppression (bin/compare-bundle-sizes:53-54,62-63)

pnpm install --frozen-lockfile 2>&1 | grep -v "^$" | head -5 || true

This suppresses all errors with || true, which could hide installation failures.

🎯 Performance Considerations

7. Double Build in Workflow

The workflow builds twice (base + PR). For large projects, this could be slow. Current implementation is acceptable, but worth noting for future optimization with build artifact caching.

🧪 Test Coverage

8. Missing Automated Tests

The PR description shows local testing but no automated tests for:

  • scripts/bundle-size.mjs utility functions
  • Edge cases: missing base files, malformed JSON, negative diffs

Recommendation: Consider adding unit tests for the script in a future PR.

📋 Minor Issues

9. Inconsistent Terminology

  • PR description says "gzip-only" but config tracks raw, gzip, AND brotli
  • Update PR description to match actual implementation

10. Missing Branch Name Validation (bundle-size.yml:27)

The skip check does not validate that branch names are safe. Branch names with special characters could cause issues.

🚀 Recommendations Summary

Must Fix Before Merge:

  1. ✅ Add error handling for size-limit failures in workflow
  2. ✅ Remove unnecessary return before process.exit(1) (line 91)
  3. ✅ Update PR description to accurately describe what is tracked

Should Fix:
4. Improve git error handling in bin/compare-bundle-sizes
5. Add input validation to scripts/bundle-size.mjs
6. Add constants for magic numbers in formatting

Nice to Have:
7. Add unit tests for bundle-size.mjs
8. Validate branch names in skip logic
9. Document why 0.5KB threshold was chosen

📚 CLAUDE.md Compliance

✅ Follows monorepo structure guidelines
✅ Uses pnpm (not npm/yarn)
✅ No manual formatting issues
⚠️ Per CRITICAL REQUIREMENTS, run these locally before claiming "fixed":

pnpm run size
pnpm run size:json
bin/compare-bundle-sizes master

Overall Assessment

This is a high-quality PR that adds real value. The architecture is sound and the implementation is clean. The issues identified are primarily defensive programming improvements rather than bugs. With the critical fixes addressed, this will be production-ready.

Great work! 🎉

@AbanoubGhadban AbanoubGhadban merged commit 0358036 into feature/bundle-size-ci-base Nov 30, 2025
1 check passed
@AbanoubGhadban AbanoubGhadban deleted the feature/bundle-size-ci branch November 30, 2025 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants