0.0
The project is in a healthy, maintained state
Inertia + React rendering for Madmin resources
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 3.3
>= 7.2
 Project Readme

madmin_inertia

Renders Madmin resources (index, show, new, edit, filters, search, pagination) as Inertia + React pages.

Requirements

  • Rails 7.2+ with Active Storage and Active Job loaded (Madmin needs them)
  • Nothing else to run the admin: it ships a prebuilt JS and CSS bundle, so it works in importmap apps with no Node, esbuild or Tailwind.
  • To customize views: jsbundling-rails with esbuild. Importmap apps can run the admin but not customize its views.

Install

Add the gem next to Madmin, from RubyGems:

# Gemfile
gem "madmin"
gem "madmin_inertia"

or straight from GitHub:

gem "madmin"
gem "madmin_inertia", github: "sethhorsley/madmin-inertia"

Then:

bundle install
rails g madmin:install
rails g madmin_inertia:install   # checks the app; there is no JS setup

Visit /madmin.

Customizing views

Like Madmin's rails g madmin:views, copy a gem component into your app only when you need to change it:

rails g madmin_inertia:views                 # layout, dashboard, index, show, form
rails g madmin_inertia:views:layout          # app/javascript/madmin/layouts/admin-layout.jsx
rails g madmin_inertia:views:dashboard       # app/javascript/madmin/pages/dashboard/index.jsx
rails g madmin_inertia:views:index           # app/javascript/madmin/pages/resource/index.jsx (all resources)
rails g madmin_inertia:views:index Post      # app/javascript/madmin/pages/resource/post/index.jsx (only Post)
rails g madmin_inertia:views:show Post
rails g madmin_inertia:views:form Post       # new and edit

Each generator registers the copied component for you. A model-specific view wins over a generic one, which wins over the gem's.

The first eject runs rails g madmin_inertia:bundle. It creates a six-line app/javascript/madmin.jsx, installs @inertiajs/react, react, react-dom, links the gem's madmin-inertia JS package (pnpm, yarn, bun or npm), patches the esbuild build script, and adds Tailwind @source lines when Tailwind is present. Components are copied as JSX under app/javascript/madmin/. Run yarn build (or pnpm build, npm run build) afterwards; once the app produces madmin.js, the layout loads it instead of the gem's prebuilt bundle (the gem's CSS still loads, so no Tailwind is required).

Ejecting needs a package.json (jsbundling-rails with esbuild). Importmap apps run the admin from the prebuilt bundle but can't customize its views, because there is no compiler for JSX; the generators stop with an error telling you to add jsbundling-rails.

Host contract

  • Optionally define a private admin_user_props in Madmin::ApplicationController returning {user: {name:, email:}, logout: path} to show the signed-in user in the default layout.
  • Define your own Madmin::DashboardController#show to replace the gem's dashboard (the gem only supplies one when the app has none).
  • Field, Value, Filters, indexUrl, buttonClass and inputClass are exported from madmin-inertia for ejected components.
  • Override layouts/madmin/inertia if your asset names differ (default loads application CSS and the madmin JS bundle).

Without Inertia

Leave the gem out of the Gemfile; Madmin renders its own ERB pages.

Development

The prebuilt bundle in app/assets/builds comes from build/. After changing anything under app/javascript or index.jsx:

cd build && pnpm install && pnpm build

The UI is shadcn/ui (build/components.json, JSX, in app/javascript/components/ui). Add components from build/ with pnpm dlx shadcn@latest add <name>; the generated @/ imports work as is. The root tsconfig.json maps @/* to app/javascript, which esbuild reads per file, so it holds even when an app bundles this source (the app's own @/ is unaffected). Vite ignores paths: add vite-tsconfig-paths, or alias @ to the gem's app/javascript for files inside the gem. The CLI writes import { cn } from "cn" (shadcn's own cn package); tsconfig.json maps cn to lib/utils (clsx + tailwind-merge) so it builds without that package.

Commit the rebuilt madmin_inertia.js and madmin_inertia.css. build/ has its own node_modules on purpose: apps link the gem root, and a second copy of React there would break hooks.