RepoPilotOpen in app →

rails/bootsnap

Boot large Ruby/Rails apps faster

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3d ago
  • 16 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 67% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/rails/bootsnap)](https://repopilot.app/r/rails/bootsnap)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/rails/bootsnap on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: rails/bootsnap

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/rails/bootsnap shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3d ago
  • 16 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 67% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live rails/bootsnap repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/rails/bootsnap.

What it runs against: a local clone of rails/bootsnap — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in rails/bootsnap | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 33 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>rails/bootsnap</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of rails/bootsnap. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/rails/bootsnap.git
#   cd bootsnap
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of rails/bootsnap and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "rails/bootsnap(\\.git)?\\b" \\
  && ok "origin remote is rails/bootsnap" \\
  || miss "origin remote is not rails/bootsnap (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "lib/bootsnap.rb" \\
  && ok "lib/bootsnap.rb" \\
  || miss "missing critical file: lib/bootsnap.rb"
test -f "lib/bootsnap/setup.rb" \\
  && ok "lib/bootsnap/setup.rb" \\
  || miss "missing critical file: lib/bootsnap/setup.rb"
test -f "lib/bootsnap/load_path_cache/cache.rb" \\
  && ok "lib/bootsnap/load_path_cache/cache.rb" \\
  || miss "missing critical file: lib/bootsnap/load_path_cache/cache.rb"
test -f "lib/bootsnap/compile_cache/iseq.rb" \\
  && ok "lib/bootsnap/compile_cache/iseq.rb" \\
  || miss "missing critical file: lib/bootsnap/compile_cache/iseq.rb"
test -f "lib/bootsnap/load_path_cache/core_ext/kernel_require.rb" \\
  && ok "lib/bootsnap/load_path_cache/core_ext/kernel_require.rb" \\
  || miss "missing critical file: lib/bootsnap/load_path_cache/core_ext/kernel_require.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 33 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~3d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/rails/bootsnap"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Bootsnap is a Ruby gem that optimizes application boot times by caching expensive computations—specifically Ruby bytecode compilation (ISeq), YAML parsing, and file path lookups. It plugs into the Ruby require system to intercept and cache the results of require calls, dramatically reducing startup time for large Rails and Ruby applications (50-75% improvements reported in production). Modular architecture: lib/bootsnap/ contains the core modules—load_path_cache/ handles require path caching (with cache.rb, path_scanner.rb, loaded_features_index.rb), compile_cache/ handles bytecode compilation (iseq.rb for Ruby, yaml.rb for YAML), and core_ext/ monkey-patches kernel_require.rb. The C extension in ext/bootsnap/ provides low-level optimizations. CLI tooling lives in lib/bootsnap/cli/.

👥Who it's for

Rails developers and maintainers of large Ruby applications who need faster boot times for development, testing, and production deployments. DevOps engineers deploying containerized Ruby apps benefit from reduced startup latency. Contributors are typically maintainers of Rails and developers familiar with Ruby internals.

🌱Maturity & risk

Highly mature and production-ready. The repo shows active development with CI/CD via GitHub Actions (.github/workflows/ci.yaml), comprehensive test coverage (test/ directory with iseq_cache_test.rb, bundler_test.rb, etc.), and real-world adoption by Discourse, Shopify core, and Rails itself. Actively maintained with clear documentation and a detailed CHANGELOG.md.

Standard open source risks apply.

Active areas of work

No specific commit recency data provided in the file structure, but the presence of .github/dependabot.yml and active CI workflows suggests ongoing maintenance. The CLI module (lib/bootsnap/cli/worker_pool.rb) suggests recent work on parallel cache compilation.

🚀Get running

git clone https://github.com/rails/bootsnap.git
cd bootsnap
bundle install
bundle exec bin/setup
bundle exec rake test

Daily commands: Development: bin/console for an interactive REPL. Tests: bundle exec rake test or bundle exec bin/testunit. Minimal dependencies: bin/test-minimal-support. See Rakefile for test targets.

🗺️Map of the codebase

  • lib/bootsnap.rb — Main entry point and initialization module that orchestrates all bootsnap features—every contributor must understand the public API and feature flags here.
  • lib/bootsnap/setup.rb — Rails integration point that enables bootsnap in real applications—critical for understanding how the gem is activated in production.
  • lib/bootsnap/load_path_cache/cache.rb — Core caching engine for load path resolution that provides the largest performance gains—the most complex and performance-critical module.
  • lib/bootsnap/compile_cache/iseq.rb — Bytecode compilation cache for Ruby files—one of two major optimization paths alongside load_path_cache.
  • lib/bootsnap/load_path_cache/core_ext/kernel_require.rb — Monkey-patches Ruby's require/load to intercept file lookups—the integration point where cache is applied to actual require calls.
  • ext/bootsnap/bootsnap.c — Native C extension for platform-level optimizations—required for understanding portability and OS-specific behavior.
  • lib/bootsnap/load_path_cache/store.rb — Persistent cache storage layer (marshaled to disk)—determines how cache state is read/written across application restarts.

🛠️How to make changes

Add a new compile cache backend for a file type

  1. Create new cache handler in lib/bootsnap/compile_cache/ (e.g., compile_cache/json.rb) (lib/bootsnap/compile_cache)
  2. Implement cache interface with 'input_to_output' method and cache validity checks (lib/bootsnap/compile_cache/yaml.rb)
  3. Register handler in compile_cache.rb by adding entry to HANDLERS or ALWAYS_CACHE_HANDLERS (lib/bootsnap/compile_cache.rb)
  4. Add tests to verify cache hit/miss and invalidation behavior (test/compile_cache)

Modify require/load interception behavior

  1. Update Kernel#require override in kernel_require.rb to change path resolution logic (lib/bootsnap/load_path_cache/core_ext/kernel_require.rb)
  2. If change affects cache key or validity, update change_observer.rb to detect the new condition (lib/bootsnap/load_path_cache/change_observer.rb)
  3. Add integration tests in test/integration/kernel_test.rb to verify require behavior (test/integration/kernel_test.rb)

Add a new configuration option

  1. Add environment variable and initialization parameter to lib/bootsnap/setup.rb (lib/bootsnap/setup.rb)
  2. Pass configuration to Bootsnap.setup or relevant cache modules (lib/bootsnap.rb)
  3. Document in README.md under Usage section (README.md)
  4. Add test coverage in test/setup_test.rb (test/setup_test.rb)

Improve cache invalidation detection

  1. Add new condition check to change_observer.rb in the 'changes?' method (lib/bootsnap/load_path_cache/change_observer.rb)
  2. If tracking filesystem state, update path_scanner.rb or cache.rb to collect necessary metadata (lib/bootsnap/load_path_cache/path_scanner.rb)
  3. Add test case to change_observer_test.rb verifying the new detection logic (test/load_path_cache/change_observer_test.rb)

🔧Why these technologies

  • Ruby C Extension (ext/bootsnap/bootsnap.c) — Provides native performance optimizations for path operations and file system access that are bottlenecks in pure Ruby
  • Marshal serialization — Fast binary format for caching complex Ruby objects (file indices, hashes) to disk without parsing overhead
  • RubyVM::InstructionSequence (ISeq) — Direct access to Ruby's compiled bytecode representation allows caching pre-compiled code without re-parsing
  • Monkey-patching Kernel#require/load — Only way to intercept all require calls in a running Ruby process without modifying user code or using require hooks

⚖️Trade-offs already made

  • Cache stored in tmp/cache as persistent files rather than in-memory only

    • Why: Allows cache to survive process restarts and be shared across multiple Rails processes
    • Consequence: Adds disk I/O but typically negligible compared to avoiding filesystem scanning; requires invalidation logic
  • Load path cache invalidated on timestamp/size changes of load_path directories

    • Why: Simple heuristic avoids expensive directory re-scanning on every boot
    • Consequence: Can miss fine-grained changes (e.g., file deleted then recreated with same timestamp); users must manually clear cache if needed
  • Requires monkeypatching Kernel#require rather than using require hooks

    • Why: Require hooks (introduced in Ruby 2.5) are slower and less flexible for caching; monkeypatch needed for legacy support
    • Consequence: Tighter coupling with Ruby internals; incompatibility risk across Ruby versions
  • Separate compile_cache and load_path_cache as independent systems

    • Why: Allows each to be enabled/disabled independently and use different invalidation strategies
    • Consequence: Adds complexity; no single unified cache key means changes in one system don't automatically invalidate the other

🚫Non-goals (don't propose these)

  • Does not handle Windows—explicitly marked as macOS/Linux only in README
  • Does not replace full dependency management—works alongside Bundler, not instead of it
  • Does not provide real-time cache invalidation—relies on polling filesystem timestamps
  • Does not support require hooks or alternative require mechanisms—only patches Kernel#require
  • Does not optimize runtime performance—only boot-time; cached code runs at normal speed
  • Does not cache Rails-specific autoloading—only standard Kernel#require

🪤Traps & gotchas

Critical: BOOTSNAP_CACHE_DIR must be writable (defaults to tmp/cache); Rails will fail to boot if it's read-only. Cache files are never auto-deleted—stale caches cause performance degradation over time and require manual cleanup. In development mode, cache is rebuilt on changes (slower but correct), but in production, if code changes without cache purge, old bytecode may be executed. The C extension requires compilation, so ensure build tools are available (gcc, ruby-dev headers). ISeq caching (compile_cache_iseq) breaks code coverage reporting—disable it when running coverage tools.

🏗️Architecture

💡Concepts to learn

  • Ruby ISeq (Instruction Sequence) — Core to compile_cache/iseq.rb—understanding ISeq is essential for caching bytecode across boot cycles; it's what RubyVM::ISeq represents
  • Kernel#require and require hooks — Bootsnap monkey-patches Kernel#require in core_ext/kernel_require.rb to intercept file lookups; understanding require's mechanics is critical to modifying this
  • $LOAD_PATH scanning and caching — load_path_cache/ exists because Ruby normally scans all $LOAD_PATH directories on every require; this concept explains 75% of Bootsnap's speedup
  • Memory-mapped I/O and file-based caching — lib/bootsnap/load_path_cache/store.rb uses file I/O for persistence; understanding mmap trade-offs is relevant for cache performance optimization
  • Bloom filters (possible path lookup optimization) — load_path_cache/loaded_features_index.rb may use probabilistic data structures for fast negative lookups when a file is not in the cache
  • C extensions and Ruby interop (FFI/C API) — ext/bootsnap/bootsnap.c interfaces directly with Ruby's C API; changes here require familiarity with Ruby's C extension patterns
  • Cache invalidation strategies — The README warns 'bootsnap will never clean up its own cache'—understanding when and how caches become stale is critical to production reliability
  • ruby/ruby — Bootsnap depends on Ruby internals (RubyVM::ISeq, require hooks); tracking Ruby's development ensures compatibility
  • rails/rails — Primary consumer of Bootsnap; Rails' boot.rb integration is the main use case and design target
  • bundler/bundler — Bootsnap integrates with Bundler (lib/bootsnap/bundler.rb) to cache require paths for gems
  • discourse/discourse — Real-world user reporting 50% boot time reduction; useful reference for production adoption and testing
  • Shopify/shopify-app-template — Another major adopter; relevant for seeing how Bootsnap is configured in large production systems

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for lib/bootsnap/bundler.rb

bundler.rb is a critical integration point with Bundler but has minimal test coverage (only test/bundler_test.rb exists). This module handles gem loading optimization and deserves extensive tests covering edge cases like gem resolution failures, missing gems, and concurrent bundler operations. High-value because Bundler integration failures could silently break production deployments.

  • [ ] Review lib/bootsnap/bundler.rb to understand all public methods and edge cases
  • [ ] Expand test/bundler_test.rb with test cases for: gem resolution failures, missing gemfiles, concurrent operations, and invalid gem specifications
  • [ ] Add tests for bundler.rb interactions with lib/bootsnap/load_path_cache/cache.rb
  • [ ] Test bundler integration with the CLI (lib/bootsnap/cli.rb) via test/cli_test.rb

Add integration tests for Windows compatibility in lib/bootsnap/load_path_cache/path_scanner.rb

The path_scanner.rb handles file path scanning but the repo's README explicitly states 'This gem works on macOS and Linux' - no Windows support claim. However, path_scanner.rb needs Windows-specific testing for path separators, case-insensitive filesystems, and symlink handling. Adding Windows CI workflow and focused tests would expand addressable market and prevent silent path resolution bugs on Windows.

  • [ ] Add Windows test environment to .github/workflows/ci.yaml (using windows-latest runner)
  • [ ] Create test/load_path_cache/path_scanner_windows_test.rb for Windows-specific edge cases: backslashes, UNC paths, case-insensitivity
  • [ ] Test lib/bootsnap/load_path_cache/path.rb path normalization on Windows
  • [ ] Document Windows support status in README.md if tests pass

Add performance regression tests comparing cache hit/miss performance metrics

Bootsnap's entire value proposition is performance improvement, but there are no benchmarking tests to prevent performance regressions. The test suite only validates correctness, not speed. Adding a performance regression test suite would catch optimizations gone wrong and provide baseline metrics for future improvements.

  • [ ] Create test/performance/cache_performance_test.rb with benchmarks for: YAML compilation cache hits/misses, ISeq compilation cache, load path cache lookups
  • [ ] Add performance assertions in test/performance/ that fail if cache operations exceed baseline thresholds (e.g., 'load_path cache lookup must complete in <1ms')
  • [ ] Integrate performance tests into .github/workflows/ci.yaml as optional reporting (not blocking, but visible)
  • [ ] Document performance baseline metrics in CHANGELOG.md or a new PERFORMANCE.md file

🌿Good first issues

  • Add integration tests for readonly mode (lib/bootsnap.rb accepts readonly: true but test/compile_cache/ and test/load_path_cache/ appear to lack explicit readonly mode test cases).
  • Document the cache invalidation strategy in CONTRIBUTING.md with examples—the README warns about manual cleanup but doesn't explain when/how to detect stale caches or measure cache age.
  • Add telemetry/metrics to lib/bootsnap/compile_cache/iseq.rb and lib/bootsnap/load_path_cache/cache.rb to track cache hit/miss rates—helpful for debugging performance issues in user apps.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • ff7f97c — Merge pull request #544 from justinlocsei/readme-header-size (byroot)
  • 48525d5 — Use the latest header size in the readme (justinlocsei)
  • 827d6d3 — Merge pull request #543 from byroot/padding (byroot)
  • 2ca9408 — Reduce cache key further to just 32B (byroot)
  • 85d7404 — Further reduce cache keys to 40B (byroot)
  • 15672d4 — Shrink the cache key from 64 to 48 bytes (byroot)
  • 4e14f7e — Release 1.24.3 (byroot)
  • 7c36e01 — Fix encoding in Ruby [Bug #22023] workaround (byroot)
  • 21b7ad8 — Release 1.24.2 (byroot)
  • fbcb561 — Merge pull request #540 from byroot/use-proper-parser (byroot)

🔒Security observations

Bootsnap is a performance optimization library with generally solid security posture. The main concerns are around the native C extension requiring careful implementation review, cache file permission handling to prevent information leakage on shared systems, and safe YAML deserialization practices. The project has good CI/CD setup (GitHub Actions) and uses dependabot for dependency monitoring, which is positive. No hardcoded secrets or critical infrastructure misconfiguration was detected in the visible file structure. Low-risk items relate to documentation and best practice guidance rather than code vulnerabilities.

  • Medium · Native C Extension Without Input Validation — ext/bootsnap/bootsnap.c, ext/bootsnap/extconf.rb. The codebase includes a native C extension (ext/bootsnap/bootsnap.c) that handles caching and file operations. Without access to the actual C code, there's a potential risk of buffer overflows, memory safety issues, or improper input validation in the extension. C extensions are a common attack vector if not carefully implemented. Fix: Conduct a thorough security audit of the C extension code. Implement strict input validation, use safe string handling functions, enable compiler security flags (e.g., -fstack-protector-strong, -D_FORTIFY_SOURCE=2), and consider using tools like AddressSanitizer during development.
  • Medium · Unsafe Cache File Permissions — lib/bootsnap/load_path_cache/store.rb, lib/bootsnap/compile_cache. The bootsnap library caches compiled bytecode and path data to disk. If cache files are created with overly permissive permissions, sensitive application code or paths could be readable by unprivileged users on shared systems, potentially leaking application structure information. Fix: Ensure cache files are created with restrictive permissions (0600 or 0644 depending on use case). Implement explicit permission setting when writing cache files and validate that the cache directory itself has appropriate ownership and permissions.
  • Medium · Potential YAML Deserialization Risk — lib/bootsnap/compile_cache/yaml.rb. The codebase includes YAML caching functionality (lib/bootsnap/compile_cache/yaml.rb). If YAML data is deserialized without proper safeguards, it could be vulnerable to arbitrary code execution through YAML gadget chains, especially if untrusted input is processed. Fix: Use safe YAML loading methods (e.g., YAML.safe_load with permitted_classes restriction). Never use YAML.load on untrusted data. Validate and sanitize all YAML input before deserialization.
  • Low · Missing Security Headers in Documentation — README.md, CONTRIBUTING.md. While not a direct code vulnerability, the README and documentation don't mention security considerations for users, such as cache poisoning risks or appropriate cache directory permissions. Fix: Add a security section to the documentation outlining best practices for cache directory permissions, risks of cache poisoning, and recommendations for secure deployment in multi-user environments.
  • Low · Dependency Version Pinning Not Visible — Gemfile, bootsnap.gemspec. The provided dependency file content is empty, making it impossible to assess whether known vulnerable gems are being used. This is a configuration oversight rather than a code vulnerability. Fix: Review and regularly update gem dependencies. Use tools like bundle-audit or dependabot (already configured in .github/dependabot.yml) to automatically detect and alert on vulnerable gem versions. Ensure all dependencies are pinned to secure versions.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · rails/bootsnap — RepoPilot