# webpackr **Repository Path**: mirrors_shakacode/webpackr ## Basic Information - **Project Name**: webpackr - **Description**: Use Webpack to manage app-like JavaScript modules in Rails - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-01-18 - **Last Updated**: 2026-05-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Shakapacker (v10) --- _πŸš€ Shakapacker 10 supports [Rspack](https://rspack.rs/)! 10x faster than webpack!_ _πŸ“– **Full documentation at [shakapacker.com](https://shakapacker.com)**_ --- _Official, actively maintained successor to [rails/webpacker](https://github.com/rails/webpacker). ShakaCode stands behind the long-term maintenance and development of this project for the Rails community._ - ⚠️ See the [6-stable](https://github.com/shakacode/shakapacker/tree/6-stable) branch for Shakapacker v6.x code and documentation. :warning: - **See the [v10.0.0 release notes](https://github.com/shakacode/shakapacker/releases/tag/v10.0.0) for upgrading from v9 to v10.** - **See [V9 Upgrade](./docs/v9_upgrade.md) for upgrading from v8 to v9.** - See [V8 Upgrade](./docs/v8_upgrade.md) for upgrading from the v7 release. - See [V7 Upgrade](./docs/v7_upgrade.md) for upgrading from the v6 release. - See [V6 Upgrade](./docs/v6_upgrade.md) for upgrading from v5 or prior v6 releases. [![Ruby based checks](https://github.com/shakacode/shakapacker/workflows/Ruby%20based%20checks/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![Jest specs](https://github.com/shakacode/shakapacker/workflows/Jest%20specs/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![Rubocop](https://github.com/shakacode/shakapacker/workflows/Rubocop/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![JS lint](https://github.com/shakacode/shakapacker/workflows/JS%20lint/badge.svg)](https://github.com/shakacode/shakapacker/actions) [![node.js](https://img.shields.io/badge/node-%3E%3D%2020-brightgreen.svg)](https://www.npmjs.com/package/shakapacker) [![Gem](https://img.shields.io/gem/v/shakapacker.svg)](https://rubygems.org/gems/shakapacker) [![npm version](https://badge.fury.io/js/shakapacker.svg)](https://badge.fury.io/js/shakapacker) Shakapacker makes it easy to use the JavaScript pre-processor and bundler [Webpack v5+](https://webpack.js.org/) to manage frontend JavaScript in Rails. It can coexist with the asset pipeline, leaving Webpack responsible solely for frontend JavaScript, or can be used exclusively, making it also responsible for images, fonts, and CSS. Check out 6.1.1+ for [SWC](https://swc.rs/) and [esbuild-loader](https://github.com/privatenumber/esbuild-loader) support! They are faster than Babel! See a comparison of [Shakapacker with jsbundling-rails](https://github.com/rails/jsbundling-rails/blob/main/docs/comparison_with_webpacker.md). For an in-depth discussion of choosing between `shakapacker` and `jsbundling-rails`, see the discussion [Webpacker alternatives - which path should we go to? #8783](https://github.com/decidim/decidim/discussions/8783) and the resulting PR [Switch away from Webpacker to Shakapacker #10389](https://github.com/decidim/decidim/pull/10389). For discussions, see our [Slack Channel](https://reactrails.slack.com/join/shared_invite/enQtNjY3NTczMjczNzYxLTlmYjdiZmY3MTVlMzU2YWE0OWM0MzNiZDI0MzdkZGFiZTFkYTFkOGVjODBmOWEyYWQ3MzA2NGE1YWJjNmVlMGE). --- ## ShakaCode Support [ShakaCode](https://www.shakacode.com) focuses on helping Ruby on Rails teams use React and Webpack better. We can upgrade your project and improve your development and customer experiences, allowing you to focus on building new features or fixing bugs instead. For an overview of working with us, see our [Client Engagement Model](https://www.shakacode.com/blog/client-engagement-model/) article and [how we bill for time](https://www.shakacode.com/blog/shortcut-jira-trello-github-toggl-time-and-task-tracking/). We also specialize in helping development teams lower infrastructure and CI costs. Check out our project [Control Plane Flow](https://github.com/shakacode/control-plane-flow/), which can allow you to get the ease of Heroku with the power of Kubernetes and big cost savings. If you think ShakaCode can help your project, [click here](https://meetings.hubspot.com/justingordon/30-minute-consultation) to book a call with [Justin Gordon](mailto:justin@shakacode.com), the creator of React on Rails and Shakapacker. Here's a testimonial of how ShakaCode can help from [Florian Gâßler](https://github.com/FGoessler) of [Blinkist](https://www.blinkist.com/), January 2, 2023: > Hey Justin πŸ‘‹ > > I just wanted to let you know that we today shipped the webpacker to shakapacker upgrades and it all seems to be running smoothly! Thanks again for all your support and your teams work! 😍 > > On top of your work, it was now also very easy for me to upgrade Tailwind and include our external node_module based web component library which we were using for our other (more modern) apps already. That work is going to be shipped later this week though as we are polishing the last bits of it. πŸ˜‰ > > Have a great 2023 and maybe we get to work together again later in the year! πŸ™Œ Read the [full review here](https://clutch.co/profile/shakacode#reviews?sort_by=date_DESC#review-2118154). Here's a testimonial from Jon Rajavuori of [Academia.edu](https://www.academia.edu/) about migrating frontend builds from Webpack to [rspack](https://rspack.rs/) with ShakaCode's help, shared in March 2026: > We've been running [rspack](https://rspack.rs/) most of the week now for frontend builds! It's a performance-focused drop-in replacement for Webpack that apparently works as advertised. The impact has been between a **2-4x build speed increase** depending on the environment and conditions. > > The typical case of first startup with a warm cache has gone from roughly 1m with Webpack down to about **20s** β€” close to the amount of time other dev components take to startup. > > As for production **incremental** builds, they now take around 10s when only a few lines in one bundle have changed! > > Additional stats from follow-up conversation with Jon: > > - Cold-cache startup: **4m30s β†’ 3m30s** (~22% faster; 2-4x gains apply to warm-cache and incremental builds) > - Production incremental builds: **~10 seconds** > - HMR rebuild time: unchanged at ~8s (bottleneck is orchestration, not compilation) --- - [Prerequisites](#prerequisites) - [Features](#features) - [Optional support](#optional-support) - [Installation](#installation) - [Rails v6+](#rails-v6) - [Concepts](#concepts) - [Usage](#usage) - [Configuration and Code](#configuration-and-code) - [Configuration Guide](./docs/configuration.md) - [View Helpers](#view-helpers) - [View Helpers `javascript_pack_tag` and `stylesheet_pack_tag`](#view-helpers-javascript_pack_tag-and-stylesheet_pack_tag) - [View Helpers `append_javascript_pack_tag`, `prepend_javascript_pack_tag` and `append_stylesheet_pack_tag`](#view-helper-append_javascript_pack_tag-prepend_javascript_pack_tag-and-append_stylesheet_pack_tag) - [View Helper: `asset_pack_path`](#view-helper-asset_pack_path) - [View Helper: `image_pack_tag`](#view-helper-image_pack_tag) - [View Helper: `favicon_pack_tag`](#view-helper-favicon_pack_tag) - [View Helper: `preload_pack_asset`](#view-helper-preload_pack_asset) - [HTTP 103 Early Hints](#http-103-early-hints) - [Images in Stylesheets](#images-in-stylesheets) - [Server-Side Rendering (SSR)](#server-side-rendering-ssr) - [Development](#development) - [Automatic Webpack Code Building](#automatic-webpack-code-building) - [Compiler strategies](#compiler-strategies) - [Common Development Commands](#common-development-commands) - [Ruby API Reference](#ruby-api-reference) - [Webpack Configuration](#webpack-configuration) - [Babel configuration](#babel-configuration) - [SWC configuration](#swc-configuration) - [esbuild loader configuration](#esbuild-loader-configuration) - [Integrations](#integrations) - [React](#react) - [Typescript](#typescript) - [CSS](#css) - [Postcss](#postcss) - [Sass](#sass) - [Less](#less) - [Stylus](#stylus) - [CoffeeScript](#coffeescript) - [Other frameworks](#other-frameworks) - [Custom Rails environments](#custom-rails-environments) - [Upgrading](#upgrading) - [Paths](#paths) - [Additional paths](#additional-paths) - [Deployment](#deployment) - [Example Apps](#example-apps) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) - [License](#license) - [Supporters](#supporters) ## Prerequisites - Ruby 2.7+ - Rails 5.2+ - Node.js 20+ ## Features - Rails view helpers that fully support Webpack output, including HMR and code splitting. - Convenient but not required webpack configuration. The only requirement is that your webpack configuration creates a manifest. - HMR with the `shakapacker-dev-server`, such as for hot-reloading React! - Automatic code splitting using multiple entry points to optimize JavaScript downloads. - Support for [NPM](https://www.npmjs.com/package/npm), Yarn ([classic](https://classic.yarnpkg.com/lang/en/) and [berry](https://yarnpkg.com/getting-started)), [PNPM](https://pnpm.io/), and [Bun](https://bun.sh/) - [Webpack v5+](https://webpack.js.org/) - ES6 with [babel](https://babeljs.io/), [SWC](https://swc.rs/), or [Esbuild](https://github.com/privatenumber/esbuild-loader) - Asset compression, source-maps, and minification - CDN support - Extensible and configurable. For example, all major dependencies are specified as peers, so you can upgrade easily. ### Optional support _Requires extra packages to be installed._ - React - TypeScript - Stylesheets - Sass, Less, Stylus and Css, PostCSS - CoffeeScript ## Installation ### Rails v6+ With Rails v6+, skip JavaScript for a new app and follow below Manual Installation Steps to manually add the `shakapacker` gem to your Gemfile. ```bash rails new myapp --skip-javascript ``` _Note, Rails 6 installs the older v5 version of webpacker unless you specify `--skip-javascript`._ Add `shakapacker` gem to your `Gemfile`: ```bash bundle add shakapacker --strict ``` Then run the following to install Shakapacker: ```bash ./bin/bundle install bundle exec rake shakapacker:install ``` Before initiating the installation process, ensure you have committed all changes. During install, Shakapacker may encounter conflicts with existing files. You can approve prompts interactively, use `FORCE=true` to overwrite without prompting, or use `SKIP=true` to preserve existing files and only create missing ones. Accepted truthy values are `true`, `1`, and `yes` (case-insensitive). If both are set, `FORCE` takes precedence. Shakapacker uses the [`package_json`](https://github.com/shakacode/package_json) gem to handle updating the `package.json` and interacting with the underlying package manager of choice for managing dependencies and running commands; the package manager is managed using the [`packageManager`](https://nodejs.org/api/packages.html#packagemanager) property in the `package.json`, otherwise falling back to the value of `PACKAGE_JSON_FALLBACK_MANAGER` if set or otherwise `npm`. If `packageManager` is not set when running `shakapacker:install`, Shakapacker will set it based on the lockfile and the result of calling `--version` on the inferred manager; if no lockfile is present, then `npm` be used unless you choose to explicitly set the `PACKAGE_JSON_FALLBACK_MANAGER` to your preferred package manager. > [!NOTE] > > The `packageManager` property is only used to determine the package manager to use, based primarily on its name. > The version (if present) is only used to determine if Yarn Classic or Yarn Berry should be used, but is otherwise > _not_ checked, nor is [`corepack`](https://nodejs.org/api/corepack.html) used to ensure that the package manager is installed. > > It is up to the developer to ensure that the desired package manager is actually install at the right version, which can be done > using `corepack` or by other means. See [here](https://github.com/G-Rath/package_json#specifying-a-package-manager) for a list of the supported package managers and more information; note that `package_json` does not handle ensuring the manager is installed. If you wish to use [Yarn PnP](https://yarnpkg.com/features/pnp) you will need to configure Babel using a `babel.config.js` file rather than via `package.json` - see [customizing Babel Config](./docs/customizing_babel_config.md) for examples on how to do this. > [!NOTE] > > The rest of the documentation will only reference `npm` when providing commands such as to install optional packages except in cases where > a particular package manager requires a very different command; otherwise it should be safe to just replace `npm` with the name of your > preferred package manager when running the command Note, in v6+, most JS packages are peer dependencies. During `shakapacker:install`, Shakapacker adds the subset required for your chosen bundler/transpiler setup rather than forcing every supported package into every app. See: - [Optional Peer Dependencies](./docs/optional-peer-dependencies.md) for how optional peers work - [Shakapacker's Peer Dependencies](./docs/peer-dependencies.md) for the current supported version ranges This keeps installation flexible while still making the supported dependency ranges explicit. ### Optional Peer Dependencies All peer dependencies in Shakapacker are marked as optional via `peerDependenciesMeta`. This design decision ensures: - **No warnings during package installation** when dependencies are not needed - **Clear visibility of supported package versions** for upgrades - **Flexibility to choose only the tools you need** (webpack vs rspack, babel vs swc vs esbuild) The optional peer dependencies approach means you only install what you actually use, while still maintaining version compatibility constraints when you do install those packages. #### Required Dependencies by Configuration Depending on your setup, you'll need different subsets of the optional peer dependencies: **For Webpack + Babel (traditional setup):** ```json { "dependencies": { "shakapacker": "^10.0.0", "@babel/core": "^7.17.9", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", "@babel/runtime": "^7.17.9", "babel-loader": "^8.2.4", "compression-webpack-plugin": "^9.0.0", "terser-webpack-plugin": "^5.3.1", "webpack": "^5.101.0", "webpack-assets-manifest": "^5.0.6", "webpack-cli": "^6.0.0", "webpack-dev-server": "^5.2.2" } } ``` > **Note:** `webpack-cli` v7 is also supported but requires Node.js >= 20.9.0. If you're on Node >= 20.9.0, you can use `"webpack-cli": "^7.0.0"` instead. See [peer-dependencies.md](./docs/peer-dependencies.md) for the full supported range. **For Webpack + SWC (faster alternative):** ```json { "dependencies": { "shakapacker": "^10.0.0", "@swc/core": "^1.3.0", "swc-loader": "^0.2.0", "compression-webpack-plugin": "^9.0.0", "terser-webpack-plugin": "^5.3.1", "webpack": "^5.101.0", "webpack-assets-manifest": "^5.0.6", "webpack-cli": "^6.0.0", "webpack-dev-server": "^5.2.2" } } ``` **For Rspack + SWC (10x faster bundling):** ```json { "dependencies": { "shakapacker": "^10.0.0", "@rspack/core": "^2.0.0-0", "@rspack/cli": "^2.0.0-0", "@swc/core": "^1.3.0", "swc-loader": "^0.2.0", "rspack-manifest-plugin": "^5.0.0" } } ``` **Quick tip:** You can easily switch between webpack and rspack using: ```bash bundle exec rake shakapacker:switch_bundler rspack -- --install-deps # For faster switching, use --no-uninstall to keep both bundlers installed bundle exec rake shakapacker:switch_bundler webpack -- --install-deps --no-uninstall ``` See the [Rspack Migration Guide](./docs/rspack_migration_guide.md) for details. **For CSS/Sass processing (add to any config above):** ```json { "dependencies": { "css-loader": "^6.8.1", "mini-css-extract-plugin": "^2.0.0", "sass": "^1.50.0", "sass-loader": "^13.0.0" } } ``` ## Concepts At its core, Shakapacker's essential function is to: 1. Provide configuration by a single file used by both Rails view helpers and JavaScript webpack compilation code. 2. Provide Rails view helpers, utilizing this configuration file so that a webpage can load JavaScript, CSS, and other static assets compiled by webpack, supporting bundle splitting, fingerprinting, and HMR. 3. Provide a community-supported, default webpack compilation that generates the necessary bundles and manifest, using the same configuration file. This compilation can be extended for any needs. ## Usage ### Configuration and Code **πŸ“– For a comprehensive guide to all configuration options, see the [Configuration Guide](./docs/configuration.md)** **πŸ“¦ For Node package exports and config object docs, see the [Node Package API Guide](./docs/node_package_api.md)** This includes documentation for: - All `config/shakapacker.yml` options (including `assets_bundler_config_path`) - Environment-specific configuration - Development server settings - Build configurations (`config/shakapacker-builds.yml`) - Best practices and common patterns You will need your file system to correspond to the setup of your `config/shakapacker.yml` file. Suppose you have the following configuration: `shakapacker.yml` ```yml default: &default source_path: app/javascript source_entry_path: packs public_root_path: public public_output_path: packs nested_entries: false # And more ``` And that maps to a directory structure like this: ``` app/javascript: └── packs: # sets up webpack entries β”‚ └── application.js # references ../src/my_component.js β”‚ └── application.css └── src: # any directory name is fine. Referenced files need to be under source_path β”‚ └── my_component.js └── stylesheets: β”‚ └── my_styles.css └── images: └── logo.svg public/packs # webpack output ``` Webpack intelligently includes only necessary files. In this example, the file `packs/application.js` would reference `../src/my_component.js` The `nested_entries` option allows webpack entry points in subdirectories (defaults to `true`). See the [Configuration Guide](./docs/configuration.md#nested_entries) for details. The `useContentHash` option enables content-based cache busting. It's disabled by default (except in production) to speed up development builds. See the [Configuration Guide](./docs/configuration.md#usecontenthash) for details. #### Precompile Hook Shakapacker supports running custom commands before compilation via the `precompile_hook` configuration option. For configuration details, see [precompile_hook in the Configuration Guide](./docs/configuration.md#precompile_hook). For complete usage guide, see the [Precompile Hook Guide](./docs/precompile_hook.md). #### Setting custom config path You can use the `SHAKAPACKER_CONFIG` environment variable to specify a custom config file path. See [Environment Variables in the Configuration Guide](./docs/configuration.md#environment-variables) for this and other configuration options. ### View Helpers The Shakapacker view helpers generate the script and link tags to get the webpack output onto your views. Be sure to consult the API documentation in the source code of [helper.rb](./lib/shakapacker/helper.rb). **Note:** For your styles or static assets files to be available in your view, you would need to link them in your "pack" or entry file. Otherwise, Webpack won't know to package up those files. #### View Helpers `javascript_pack_tag` and `stylesheet_pack_tag` These view helpers take your `shakapacker.yml` configuration file and the resulting webpack compilation `manifest.json` and generate the HTML to load the assets. You can then link the JavaScript pack in Rails views using the `javascript_pack_tag` helper. If you have styles imported in your pack file, you can link them by using `stylesheet_pack_tag`: ```erb <%= javascript_pack_tag 'application' %> <%= stylesheet_pack_tag 'application' %> ``` The `javascript_pack_tag` and `stylesheet_pack_tag` helpers will include all the transpiled packs with the chunks in your view, which creates HTML tags for all the chunks. You can provide multiple packs and other attributes. Note, `defer` defaults to showing. ```erb <%= javascript_pack_tag 'calendar', 'map', 'data-turbo-track': 'reload' %> ``` The resulting HTML would look like this: ```html ``` In this output, both the calendar and map codes might refer to other common libraries. Those get placed in something like the vendor bundle. The view helper removes any duplication. Note, the default of "defer" for the `javascript_pack_tag`. You can override that to `false`. If you expose jquery globally with `expose-loader,` by using `import $ from "expose-loader?exposes=$,jQuery!jquery"` in your `app/javascript/application.js`, pass the option `defer: false` to your `javascript_pack_tag`. The `javascript_pack_tag` also supports the `async` attribute, which you can enable by passing `async: true`: ```erb <%= javascript_pack_tag 'application', async: true %> ``` This will generate script tags with the `async` attribute, which allows the browser to download and execute the script asynchronously without blocking HTML parsing: ```html ``` Note that when using `async: true`, scripts may execute in any order as soon as they're downloaded, which could cause issues if your code has dependencies between files. In most cases, `defer` (the default) is preferred as it maintains execution order. > [!NOTE] > > When both `async` and `defer` attributes are specified, `async` takes precedence according to HTML5 specifications. So if you pass both `async: true` and `defer: true`, the script tag will use `async`. **Important:** Pass all your pack names as multiple arguments, not multiple calls, when using `javascript_pack_tag` and the `stylesheet_pack_tag`. Otherwise, you will get duplicated chunks on the page. ```erb <%# DO %> <%= javascript_pack_tag 'calendar', 'map' %> <%# DON'T %> <%= javascript_pack_tag 'calendar' %> <%= javascript_pack_tag 'map' %> ``` While this also generally applies to `stylesheet_pack_tag`, you may use multiple calls to stylesheet_pack_tag if, say, you require multiple `