rails/webpacker
Use Webpack to manage app-like JavaScript modules in Rails
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓21+ active contributors
- ✓Distributed ownership (top contributor 22% of recent commits)
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 2y ago
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.
[](https://repopilot.app/r/rails/webpacker)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/webpacker on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: rails/webpacker
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/rails/webpacker 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 all four use cases
- 21+ active contributors
- Distributed ownership (top contributor 22% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
<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/webpacker
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/rails/webpacker.
What it runs against: a local clone of rails/webpacker — 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/webpacker | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 693 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of rails/webpacker. If you don't
# have one yet, run these first:
#
# git clone https://github.com/rails/webpacker.git
# cd webpacker
#
# 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/webpacker and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "rails/webpacker(\\.git)?\\b" \\
&& ok "origin remote is rails/webpacker" \\
|| miss "origin remote is not rails/webpacker (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/webpacker.rb" \\
&& ok "lib/webpacker.rb" \\
|| miss "missing critical file: lib/webpacker.rb"
test -f "lib/webpacker/configuration.rb" \\
&& ok "lib/webpacker/configuration.rb" \\
|| miss "missing critical file: lib/webpacker/configuration.rb"
test -f "lib/webpacker/compiler.rb" \\
&& ok "lib/webpacker/compiler.rb" \\
|| miss "missing critical file: lib/webpacker/compiler.rb"
test -f "lib/webpacker/manifest.rb" \\
&& ok "lib/webpacker/manifest.rb" \\
|| miss "missing critical file: lib/webpacker/manifest.rb"
test -f "lib/webpacker/helper.rb" \\
&& ok "lib/webpacker/helper.rb" \\
|| miss "missing critical file: lib/webpacker/helper.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 693 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~663d)"
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/webpacker"
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).
⚡TL;DR
Webpacker is a retired Rails gem (v5 branch still maintained) that wraps Webpack to bundle and manage app-like JavaScript modules in Rails applications. It provides Rails-integrated webpack configuration, Babel transpilation, and development server integration via lib/install/config/webpack/*.js and lib/tasks/webpacker.rake, but is no longer officially evolved—Rails 7+ prefers jsbundling-rails or import maps. Dual-language gem structure: Ruby side in lib/tasks/webpacker.rake and lib/install/binstubs.rb provides Rails integration, task definitions, and installation templates; JavaScript side in lib/install/config/webpack/{base,development,production,test}.js and lib/install/application.js provides Webpack configuration. Package.json and Babel preset at lib/install/ define bundler behavior. Docs in docs/ cover configuration and migration paths.
👥Who it's for
Rails developers (v5 and earlier) maintaining legacy applications that integrated JavaScript via Webpacker; contributors to the maintenance branch are Rails core team members and security-fix volunteers, not active feature developers. New Rails projects should not use this.
🌱Maturity & risk
Production-mature but officially retired (see CHANGELOG.md and README status). The v5 branch (5-x-stable) receives only security fixes following Rails maintenance policy; v6 development was abandoned in favor of the community fork Shakapacker. CI is comprehensive (ruby.yml, js-lint.yml, jest.yml, rubocop.yml in .github/workflows/) but indicates legacy maintenance rather than active development.
Critical risk: This gem is no longer officially maintained or updated—JavaScript dependencies in lib/install/package.json will not receive updates. Rails 7+ removed Webpacker from defaults entirely. Risk of incompatibility with Node.js versions above .node-version spec. Single point of failure: if security issues arise in Webpack itself, they may not be patched in this gem. Do not start new Rails projects with this.
Active areas of work
Webpacker is in security-only maintenance mode on the 5-x-stable branch; this main branch shows v6 abandoned. No active feature work. The related fork Shakapacker (by Justin Gordon, listed in README) continues v6 development with hot-module reloading focus. GitHub workflows run tests on every push but no recent commits indicate active development.
🚀Get running
Clone the 5-x-stable branch (NOT main, which is abandoned v6): git clone --branch 5-x-stable https://github.com/rails/webpacker.git && cd webpacker && bundle install && yarn install (uses Yarn per gemfiles and .node-version). Then: bundle exec rake to run Ruby tests, yarn test to run Jest tests (see .github/workflows/jest.yml).
Daily commands: Development: bundle exec bin/webpacker-dev-server (runs Webpack dev server with hot module reloading in v6 work only; v5 uses bundle exec bin/webpacker watch). Compile: bundle exec bin/webpacker or bundle exec rails webpacker:compile (rake task in lib/tasks/webpacker.rake). Tests: bundle exec rspec, yarn test (see .github/workflows for exact commands).
🗺️Map of the codebase
lib/webpacker.rb— Main entry point and primary API for Rails integration; all Webpacker functionality flows through this modulelib/webpacker/configuration.rb— Loads and manages webpacker.yml configuration; controls build behavior and asset resolutionlib/webpacker/compiler.rb— Orchestrates Webpack compilation process; the critical bridge between Rails and Webpacklib/webpacker/manifest.rb— Parses and caches compiled manifest.json; enables Rails to locate bundled assets at runtimelib/webpacker/helper.rb— Provides Rails view helpers (javascript_pack_tag, stylesheet_pack_tag); used on nearly every pagepackage/index.js— Node.js entry point that exports Webpack configuration and environment setuplib/install/template.rb— Installation script that sets up Webpacker in a new Rails app; defines initial project structure
🛠️How to make changes
Add a New Webpack Loader (e.g., for a new file type)
- Create a new loader file in package/rules/ (e.g., package/rules/svelte.js) that exports a rule object with test regex and loader/options (
package/rules/svelte.js) - Import the new rule in package/rules/index.js and add it to the exported rules array (
package/rules/index.js) - Add the loader dependency to package.json in the root of the webpacker gem (
package.json) - Add integration test in package/tests/ to verify the rule is properly included (
package/__tests__/index.js)
Create a New Rake Task for Custom Build Step
- Create a new file under lib/tasks/webpacker/ (e.g., lib/tasks/webpacker/custom_build.rake) that defines the task and calls Webpacker.compiler or commands (
lib/tasks/webpacker/custom_build.rake) - Call Webpacker commands via lib/webpacker/commands.rb (e.g., Webpacker::Commands.compile or .clobber) (
lib/webpacker/commands.rb) - If the task depends on webpack, ensure it chains from :environment and calls config.verify! to validate setup (
lib/tasks/webpacker/verify_install.rake)
Modify Webpack Configuration for a New Environment (e.g., 'staging')
- Create lib/install/config/webpack/staging.js that imports base and overrides settings (source maps, minification, etc.) (
lib/install/config/webpack/staging.js) - Create package/environments/staging.js that exports environment-specific settings (dev_server, output_path) (
package/environments/staging.js) - Update package/index.js to require and use the staging environment when NODE_ENV=staging (
package/index.js) - Test the new environment with package/tests/staging.js to ensure config merges correctly (
package/__tests__/staging.js)
Add a New Configuration Option to webpacker.yml
- Add the new key and default value to config/webpacker.yml (the template used during installation) (
config/webpacker.yml) - Update lib/webpacker/configuration.rb to load and expose the new option via an accessor method (
lib/webpacker/configuration.rb) - Pass the new config value from package/config.js to the webpack configuration object if it affects build behavior (
package/config.js) - Add a test in the Ruby test suite (lib/webpacker spec files if they exist, or update verification task) to validate the option is loaded (
lib/webpacker/configuration.rb)
🔧Why these technologies
- Webpack — Handles modern JavaScript bundling, code splitting, and asset hashing; integrates with npm ecosystem
- Babel — Transpiles modern ES6+ syntax to browser-compatible JavaScript; configured via package/babel/preset.js
- Rails Railtie — Cleanly integrates Webpacker into Rails initialization and asset pipeline lifecycle
- Manifest JSON — Provides deterministic asset lookup at runtime; enables cache busting and CDN serving via fingerprints
- Node.js Child Processes — Isolates webpack execution from Rails; allows parallel builds and dev server management
⚖️Trade-offs already made
-
Synchronous compilation in rails/helper.rb via blocking process.wait
- Why: Simpler Ruby integration and guaranteed asset availability before render
- Consequence: Page render blocks if assets need recompilation (mitigated by caching manifest.json in memory)
-
Separate dev_server process instead of inline bundler
- Why: Isolates HMR and allows developers to restart Rails without restarting webpack
- Consequence: Additional process to manage; requires dev_server proxy configuration
-
YAML configuration in webpacker.yml instead of inline Ruby
- Why: Familiar Rails convention; decouples build config from Rails code
- Consequence: Requires YAML parsing and validation; less flexibility than Ruby DSL
-
Retired in favor of jsbundling-rails and import-maps (Rails 7+)
- Why: Modern Rails no longer requires centralized bundler; ESM and importmap-rails are lighter alternatives
- Consequence: No new features; users must migrate to newer tooling
🚫Non-goals (don't propose these)
- Does not serve as a general-purpose Webpack wrapper; specifically optimized for Rails apps
- Does not handle JavaScript minification or optimization beyond what Webpack and Babel provide
- Does not provide TypeScript configuration out of the box (users must add loaders manually)
- Does not manage or download Node.js or Yarn; assumes they are already installed
- Does not provide a UI or CLI for interactive configuration;
🪤Traps & gotchas
- Webpacker is retired—do not use for new Rails 7+ projects. 2. The main branch contains abandoned v6 code; use 5-x-stable for production apps. 3. .node-version pins Node.js version; newer versions may break Webpack 4 setup. 4. lib/install/config/webpacker.yml requires source_path and public_root_path tuning for custom Rails setups; misconfig silently breaks bundling. 5. Babel preset is pinned at ./node_modules/@rails/webpacker/package/babel/preset.js in package.json—custom presets require manual override. 6. Rails 7+ imports removed Webpacker from defaults; upgrading Rails may break existing setups. 7. lib/install/bin/webpacker-dev-server is a wrapper—actual dev server runs via Webpack Dev Middleware; must be running alongside Rails for live reload.
🏗️Architecture
🔗Related repos
rails/jsbundling-rails— Official Rails replacement for Webpacker (Rails 7+); same problem domain but simpler abstraction using esbuild/Webpack/Rollup without Rails-specific wrapperrails/importmap-rails— Alternative bundling strategy for Rails 7+ that avoids compilation entirely via ES module imports; recommended over Webpacker for new appsshakacode/shakapacker— Community fork continuing v6 development with HMR focus; where active Webpacker-like development happens after official retirementrails/rails— The Rails framework itself; Webpacker was a Rails-distributed gem until v7 removed it; understanding Rails plugin architecture is essentialwebpack/webpack— The underlying bundler Webpacker wraps; understanding Webpack config patterns in lib/install/config/ requires Webpack documentation
🪄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 integration tests for Dev Server Proxy functionality
The lib/webpacker/dev_server_proxy.rb file exists but there are no corresponding test files in the repository's test structure. Given that dev server proxying is critical for Rails development workflow (handling WebSocket proxying, asset serving, and HMR), adding comprehensive integration tests would prevent regressions and document expected behavior. This is especially important given Webpacker's retirement status—thorough tests help users maintain their own forks.
- [ ] Create
test/webpacker/dev_server_proxy_test.rbwith tests for proxy initialization, request forwarding, and error handling - [ ] Add tests for WebSocket upgrade handling in the proxy
- [ ] Test proxy behavior with different
webpacker.ymlconfigurations (dev_server settings) - [ ] Verify proxy correctly handles dev server URL generation per
lib/webpacker/dev_server.rb
Add missing Rails version compatibility tests in CI
The repository has multiple Gemfile-rails.*.x files (5.2, 6.0, 6.1) in gemfiles/ directory but the CI workflow files (.github/workflows/ruby.yml) don't show explicit matrix testing across these versions. Since Webpacker supports legacy Rails versions and the retirement message directs users to alternatives, comprehensive version-specific testing prevents accidental breakage for users still maintaining Webpacker.
- [ ] Update
.github/workflows/ruby.ymlto add a matrix strategy testing against Rails 5.2.x, 6.0.x, and 6.1.x using the corresponding Gemfiles - [ ] Ensure each Rails version test runs the full test suite from
lib/tasks/webpacker.rake - [ ] Add separate CI job to verify binstubs work across versions using
lib/tasks/webpacker/check_binstubs.rake - [ ] Document the Rails version support matrix in
CONTRIBUTING.md
Add comprehensive tests for webpack configuration resolution in different environments
lib/install/config/webpack/ contains base, development, production, and test configs, but there's likely missing test coverage for how these configs are selected and merged based on lib/webpacker/configuration.rb. The lib/tasks/webpacker/verify_config.rake task suggests config validation exists but tests don't clearly verify the conditional logic that selects webpack configs per environment.
- [ ] Create
test/webpacker/webpack_config_resolution_test.rbtesting config selection for development, production, and test environments - [ ] Add tests verifying webpack config merges correctly with
lib/install/config/webpack/base.js - [ ] Test that environment-specific variables (NODE_ENV, RAILS_ENV) correctly influence config selection per
lib/webpacker/env.rb - [ ] Verify babel preset path resolution works correctly as defined in the package.json snippet's babel.presets
🌿Good first issues
- Add test coverage for lib/tasks/webpacker/check_node.rake—currently no Jest/RSpec tests visible in file list for checking Node.js binary availability during Rails startup: Ensures Webpacker fails gracefully on misconfigured Node.js environments instead of cryptic bundler errors
- Document common webpack config customizations in docs/customizing_babel_config.md with examples for tree-shaking, code-splitting, and CSS extraction—currently only covers Babel: Reduces support burden for users extending base Webpack config in lib/install/config/webpack/base.js
- Add migration script or guide in docs/ showing step-by-step conversion from Webpacker to jsbundling-rails with esbuild, mapping lib/install/config/webpack/ to esbuild config: The README recommends switching but provides only a link; detailed walkthrough would ease migration for thousands of legacy Rails apps
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 22 commits
- @amatsuda — 21 commits
- @justin808 — 18 commits
- @rafaelfranca — 13 commits
- @guillaumebriday — 5 commits
📝Recent commits
Click to expand
Recent commits
a715e05— Merge pull request #3327 from rails/dependabot/npm_and_yarn/babel/traverse-7.23.7 (amatsuda)7b71ce0— Edge Rails no longer supports Ruby < 3.1 (amatsuda)9d265ae— Bump @babel/traverse from 7.16.3 to 7.23.7 (dependabot[bot])4390925— Merge pull request #3316 from rails/dependabot/npm_and_yarn/tough-cookie-4.1.3 (amatsuda)42b38b3— Merge pull request #3317 from rails/dependabot/npm_and_yarn/semver-6.3.1 (amatsuda)e574aa0— Merge pull request #3318 from rails/dependabot/npm_and_yarn/word-wrap-1.2.4 (amatsuda)d4b1bbe— Merge pull request #3319 from rails/dependabot/github_actions/actions/checkout-4 (amatsuda)5d14285— Bump actions/checkout from 3 to 4 (dependabot[bot])2fc03c1— Bump word-wrap from 1.2.3 to 1.2.4 (dependabot[bot])04b80ce— Bump semver from 6.3.0 to 6.3.1 (dependabot[bot])
🔒Security observations
The Webpacker codebase presents significant security concerns primarily due to its retired status and lack of active maintenance. The project will not receive security updates, making it unsuitable for production use in new applications. Additional concerns include missing explicit dependency declarations, inadequate build configuration security, and lack of security scanning tools. Organizations currently using Webpacker should prioritize migration to actively maintained alternatives (jsbundling-rails or importmap-rails) and implement comprehensive dependency scanning and validation during the transition.
- High · Retired Project - No Active Maintenance —
Project-wide / README.md. Webpacker has been officially retired by the Rails team as of Rails 7 (December 2021). The project is no longer receiving security updates, bug fixes, or active maintenance. This poses significant long-term security risks as vulnerabilities discovered in dependencies will not be patched. Fix: Migrate to actively maintained alternatives: (1) jsbundling-rails with Webpack, (2) importmap-rails, or (3) another actively maintained JavaScript bundler. Follow the official migration guide at https://github.com/rails/jsbundling-rails/blob/main/docs/switch_from_webpacker.md - High · Missing Dependency Pinning in package.json —
package.json. The package.json file shows an empty 'dependencies' object with no pinned versions. This creates supply chain risks as any subsequent installation could pull vulnerable or malicious versions of transitive dependencies. Webpacker's own dependencies are not explicitly declared, making it difficult to audit and control the dependency tree. Fix: Explicitly declare all required dependencies with pinned versions. Usenpm ciinstead ofnpm installto ensure reproducible builds. Implement dependency scanning tools like npm audit, Snyk, or Dependabot to identify and track vulnerabilities. - Medium · Babel Configuration Preset Path Vulnerability —
package.json (babel.presets). The babel configuration references './node_modules/@rails/webpacker/package/babel/preset.js' with a relative path. If the node_modules directory structure is compromised or manipulated, this could lead to loading malicious babel presets that could execute arbitrary code during the build process. Fix: Use absolute package references instead of relative node_modules paths. Use a package resolver or ensure strict file permissions on node_modules. Validate the integrity of the babel preset through checksums or use npm shrinkwrap/lockfile verification. - Medium · Inadequate Browserslist Configuration —
package.json (browserslist). The browserslist is set to 'defaults', which may not align with your application's actual browser support requirements. This could result in transpilation to older JavaScript standards or, conversely, shipping code incompatible with older browsers that you need to support. This indirect security issue affects feature availability and polyfill inclusion. Fix: Explicitly define browserslist targets based on your actual user base and support requirements. Use tools like 'browserslist' query to review what this configuration includes. Consider using '>= 0.5%, last 2 versions, not dead' or more specific targets. - Medium · Missing Security Configuration Files —
Project root. No evidence of security-focused configuration files such as .npmrc, security policy files, or dependency scanning configurations. The codebase lacks explicit security guardrails for the JavaScript build pipeline. Fix: Add .npmrc with security settings (audit-level=moderate, fund=false). Create or update SECURITY.md with vulnerability reporting guidelines. Implement automated dependency scanning in CI/CD pipelines using tools like npm audit, Snyk, or GitHub security advisories. - Low · Missing ESLint Security Plugin —
.eslintrc.js. While .eslintrc.js exists, there is no indication of security-focused ESLint plugins (such as eslint-plugin-security) being configured. This misses opportunities to catch common security issues like hardcoded secrets or unsafe patterns during development. Fix: Install and configure eslint-plugin-security. Add security-related linting rules to catch potential vulnerabilities early in development. Include checks for hardcoded credentials, unsafe string operations, and other security anti-patterns.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.