react-manifest-rails
Generate per-controller Sprockets manifests for React code in Rails.
This gem creates ux_*.js bundles and includes them with react_bundle_tag.
Quick Start (Development)
- Add gems:
# Gemfile
gem "react-manifest-rails"
group :development do
gem "listen", "~> 3.0"
end
- Install:
bundle install
If your app uses this standard layout, you can keep defaults and only create the initializer if you want overrides:
ux_root: app/assets/javascripts/ux
app_dir: app
output_dir: app/assets/javascripts
extensions: js, jsx
- Add initializer:
# config/initializers/react_manifest.rb
require "react_manifest"
ReactManifest.configure do |config|
config.ux_root = "app/assets/javascripts/ux"
config.app_dir = "app"
config.output_dir = "app/assets/javascripts"
config.manifest_subdir = "ux_manifests"
config.shared_bundle = "ux_shared"
config.always_include = []
config.ignore = []
config.exclude_paths = ["react", "react_dev", "vendor"]
config.size_threshold_kb = 500
config.dry_run = false
config.verbose = false
config.stdout_logging = true
end
- Put React files under:
app/assets/javascripts/ux/
app/
users/
users_index.jsx
components/
nav.jsx
- Include bundles in your layout:
<%= react_bundle_tag defer: true %>
- Start server:
bundle exec rails s
In development:
- If expected
ux_*.jsfiles are missing, the gem generates them once on boot. - If
listenis installed, file changes regenerate manifests automatically. - If
listenis missing, runbundle exec rails react_manifest:generatemanually. - Set
config.stdout_logging = falseto silence ReactManifest console lines while keeping Rails logger output.
Configuration Notes
ignore:- Skips controller directory names directly under
ux/app/. - Example:
ignore = ["admin"]skipsux/app/admin/*.
- Skips controller directory names directly under
exclude_paths:- Excludes files by matching path segments while scanning the
ux_roottree. - Example:
exclude_paths = ["vendor"]excludesux/vendor/*and any nested.../vendor/...segment. - This is not based on what is included in
application.js.
- Excludes files by matching path segments while scanning the
dry_run:- Preview mode only; computes and prints changes but writes no files.
verbosevsstdout_logging:verbose: extra diagnostic detail.stdout_logging: whether ReactManifest status lines are printed to terminal stdout.
Scope:
- Manifest generation only scans files under
ux_root.
- Manifest generation only scans files under
What Gets Generated
ux_shared.js: shared files outsideux/app/ux_<controller>.js: one bundle per directory underux/app/- Generated manifests are written to
app/assets/javascripts/ux_manifests/by default. - Existing legacy
app/assets/javascripts/ux_*.jsfiles are moved automatically on generation.
Example:
ux/app/users/...->ux_users.jsux/app/admin/...->ux_admin.js
Commands
- Generate manifests now:
bundle exec rails react_manifest:generate
- Watch in foreground (debugging only; not required in normal dev):
bundle exec rails react_manifest:watch
- Print bundle size report:
bundle exec rails react_manifest:report
Troubleshooting
react_manifest:generate is not recognized
Run:
bundle exec rails -T | grep react_manifest
If nothing appears:
- Confirm the gem is in
Gemfileand installed (bundle show react-manifest-rails). - Ensure the gem is not disabled with
require: false. - Restart Spring/server (
bin/spring stop, then re-run command).
Server starts but nothing happens
Check these in order:
app/assets/javascripts/uxexists.- Your controller files are under
ux/app/<controller>/. - Your layout includes
<%= react_bundle_tag %>. - Run
bundle exec rails react_manifest:generateonce and check for generatedux_*.jsinapp/assets/javascripts.
Auto-watch in dev does not run
- Ensure
listenis in the development group. - Restart the Rails server after adding
listen. - If you choose not to install
listen, manual generation is the supported fallback.
Compatibility
- Ruby: 3.2+
- Rails/Railties: 7.x to 8.x
- Asset pipeline: Sprockets
License
MIT