Why Inertia.js Rails is a big deal for modern web apps
The Bridge Between Two Worlds: Why Inertia.js is the Future of Rails Full-Stack
In my previous post, I introduced my first full-stack project: an email-based Helpdesk system. I briefly mentioned using Ruby on Rails and Svelte with Inertia.js. Today, I want to go deeper into the “why.”
Specifically, I want to discuss why the Inertia-Rails adapter is a massive deal for developers who love the productivity of Rails but crave the interactivity of modern JavaScript.
The “Modern Web” Wall
As a Rails lover, I’m a fan of the “Omakase” approach. Rails handles routing, database migrations, and security with an elegance that is hard to match. However, when building my Helpdesk, I hit a wall with ERB.
Modern users expect “snappy” interfaces—things like real-time ticket filtering, instant comment updates, and smooth transitions. While you can do this with Stimulus or Turbo (Hotwire), it often feels like you’re “fighting” the framework to get the state management right.
The Alternatives
- The Pure SPA (The “Hard” Way): You build a Rails API and a separate React/Svelte app. Now you have two repositories, CORS issues, complex Auth (JWT), and you’ve duplicated your routing logic.
- Hotwire (The “Rails” Way): It’s great for adding “sprinkles” of interactivity, but for high-fidelity apps, managing Turbo Streams and Frames can become a complex web of hidden logic.
What makes Inertia.js different?
Inertia is often called “The Modern Monolith.” It allows you to build a single-page app without the pain of building a separate API. It works as a bridge: Rails handles the “What” (the data) and Svelte handles the “How” (the UI).
How it looks in practice:
In a standard Rails app, your controller might look like this:
1
2
3
4
5
# Standard Rails
def index
@tickets = Ticket.all
# Renders index.html.erb
end
With the Inertia-Rails adapter, it changes to this:
1
2
3
4
5
6
7
# Inertia Rails
def index
render inertia: {
tickets: Ticket.all
}
# Renders in frontend/pages/tickets/index.svelte
end
And in the client side you can just easily handle frontend like you always do
1
2
3
4
5
6
7
<script>
let tickets = $prop();
</script>
{#each tickets as ticket}
<div>ID: {ticket.id}</div>
<div>Name: {ticket.name}</div>
{/each}
The magic here is that the adapter is smart is enough to know you will passing the tickets value into index.svelte if you setup correctly which will keep the Rails way as standard is a Svelte component. Inertia takes those props and hands them directly to your frontend. No fetch calls, no Axios boilerplate, and no onMount hooks just to get data on the screen.
Why this is a “Big Deal”
1. The Death of the “Client-Side Router”
One of the most annoying parts of building an SPA is duplicating your routes. You have to define /tickets in your API and /tickets in your React/Svelte router. With Inertia, Rails remains the source of truth. You use Rails routes, and Inertia intercepts the clicks to swap the Svelte components.
2. State Management is “Free”
Because the server provides the “props” for every page, you don’t need a complex state management library (like Redux or Pinia) for 90% of your app. When you submit a form via an Inertia visit, Rails updates the database and redirects; Inertia then automatically refreshes the props on the page. It feels like a lightning-fast SPA, but the logic is pure Rails.
3. Shared Data (The Secret Weapon)
Inertia allows you to “share” data globally. Want the current logged-in user or flash messages available in every single Svelte component? You can configure it in your application_controller.rb:
1
2
3
4
5
6
7
8
9
class ApplicationController < ActionController::Base
inertia_share do
{
auth: { user: current_user },
flash: flash.to_hash
}
end
end
Conclusion
This is my thought about the Inertia.js adapter. Of course you can always use different backend like Larvarel and use your favorite frontend like React or Vue. The main point I like here is how this can help me solve a lot of problems without sacrifice I used to love.
See you later in future post.
