Open-source project
ElMassimo/vite_ruby avatar
ElMassimo/vite_ruby

vite_ruby: bringing Vite's dev server to Rails, Hanami, Padrino and Rack apps

⚡️ Vite.js in Ruby, bringing joy to your JavaScript experience

1,590 stars151 forksRubyMIT

At a glance

What is it?
vite_ruby is a set of Ruby gems and Vite plugins that put Vite in front of a Ruby web application, so the front end gets an instant-starting dev server with hot reload while production still bundles and deploys through the framework's asset pipeline. The repository is a monorepo covering four framework integrations and a legacy compatibility set.
Who is it for?
Adopt vite_ruby if you are building a Ruby web application with a modern JavaScript front end and you want Vite's dev server and hot reload without hand-rolling the bridge between the two toolchains. Do not adopt it if your front end is server-rendered ERB with no bundler step, or if you cannot add a Node toolchain to your build environment.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A monorepo of four integrations, not one gem

vite_ruby is described as Vite.js in Ruby, and the README states that the repository contains libraries that will allow you to easily integrate Vite in your favourite Ruby framework, such as Rails or Hanami. The primary language of the repository is Ruby, the licence is MIT, and the homepage is vite-ruby.netlify.app.

The first structural fact is that this is a monorepo, and the top-level listing shows it clearly. There are four framework integration directories: vite_rails, vite_hanami, vite_padrino and vite_ruby, the last being the generic Rack one. Alongside them sit vite-plugin-rails and vite-plugin-ruby, which are the Vite plugin halves of the integration, and a pair of legacy directories, vite_rails_legacy and vite_plugin_legacy, which exist for applications that have not yet moved to the current plugin set.

That is a lot of surface area, and it maps onto a real problem in the Ruby ecosystem. Vite is a Node tool, and a Ruby application has to run it as a separate process, hand it configuration, tell it where to put the built assets, and then serve those assets from the framework. Each framework has its own conventions for that, and vite_ruby has already written the integration for Rails, Hanami, Padrino and plain Rack rather than leaving you to.

The repository also carries the tooling a monorepo needs: a pnpm-workspace.yaml and a pnpm-lock.yaml for the JavaScript side, a Gemfile and Gemfile.lock for the Ruby side, a package.json that is marked private and named vite_ruby_monorepo, a Rakefile, and gemfiles/ for testing against multiple dependency sets.

The repository is not archived, and the last push was on 2026-10-16, so it is actively worked on. There are no GitHub releases, which for a gem collection is normal because the versions live on RubyGems.

Why Vite at all, and what the dev server actually changes

The README explains the choice by contrasting Vite's development behaviour with its production behaviour, and the argument is worth restating because it is the whole case for the project.

During development, Vite does not bundle your code. The dev server is extremely fast to start, and changes are updated instantly. The linked Vite documentation is cited for both the problem of bundling and the problem of slow updates, which is the standard framing: a traditional bundler rebuilds a dependency graph on every change, and a project with a large dependency tree pays for that on every save.

In production, the same tool bundles with tree-shaking, lazy-loading and common chunk splitting out of the box. The README also points out that Vite ships good defaults and is easier to configure than similar tools such as webpack, and the Special Thanks section names webpacker, the Rails webpack integration, alongside Vite itself, which is a nod to the previous generation of Rails front-end tooling.

So the pitch is not that Vite is a nicer bundler. It is that the development experience, which is where a front-end developer spends most of their day, is dramatically different, and that the production output is still a normal bundle that the deployment pipeline handles.

The features list makes the same point in four lines: instant server start, blazing fast hot reload, zero-config deployments, and integration with assets:precompile. That last one is the piece that matters for a Rails operator, because it means the existing asset pipeline invocation still does what it always did, and the deploy story does not change.

The audience is a Ruby developer with a JavaScript-heavy front end, who is currently paying bundler rebuild times on every change, and who does not want to leave the Ruby side of the stack.

Installing: one gem line, one bundle, one command

The installation is short and the three packages are named in one comment, which is the first thing to get right.

ruby
gem 'vite_rails' # vite_hanami for Hanami apps, vite_ruby for Rack apps

vite_rails is for Rails, vite_hanami for Hanami, and vite_ruby for Rack applications. The Padrino integration, vite_padrino, is in the repository too.

After the Gemfile change, the README gives two commands:

bash
bundle install
bundle exec vite install

The second one generates the configuration files and a sample setup. That is the whole install. The generator is what writes your project's Vite configuration and the framework-specific wiring, and it is also what you run again after upgrading, since the generated files change with the plugin versions.

The first run in development is a bin/vite command rather than a Ruby command, which is the detail that surprises people:

bash
bin/vite dev

You restart your web server, run bin/vite dev to start the Vite development server, and then visit any page and look for a printed console output reading Vite Ruby, which the README shows with a lightning symbol in front of it. That string is the success signal, and it is a useful one, because a page that renders without the injected dev client usually means the plugin is not active or the asset paths are wrong.

The configuration reference is published on the documentation website, along with the guides, and the README links a specific default config file in the repository at vite-plugin-ruby/default.vite.json, which is the file the generator starts from. The example application is pingcrm-vite, a Rails app, with a live instance on Heroku referenced in the README, and there is an examples/ directory in the repository holding a Hanami bookshelf app, a Padrino blog tutorial and a Rails example.

The monorepo toolchain: pnpm workspaces, Ruby version files, mise

The repository layout is a good guide to how the project is developed, and it shows a Ruby and JavaScript codebase held together deliberately.

There is a pnpm-workspace.yaml and a pnpm-lock.yaml, and the root package.json is marked private and named vite_ruby_monorepo. Its engines field pins node 24 and pnpm 12, and there is a .node-version file and a .ruby-version file, plus a mise.toml, which is the toolchain manager that keeps those versions consistent across a team and in CI.

The scripts in the root package.json cover the release process and the documentation site. The release script runs node scripts/release.cjs, the changelog is generated with scripts/changelog.cjs using conventional-changelog-cli, and the docs script delegates to a separate package in the docs/ directory, with a docs:search script alongside it. The docs being their own package with their own search index explains the searchable configuration reference the README advertises.

Quality tooling is split along the language lines. lint-staged runs eslint --fix on JavaScript, TypeScript and Vue files and bin/rubocop -A on Ruby files, and the repository carries .eslintrc.cjs, .eslintignore, .rubocop.yml, .rubocop_todo.yml and tsconfig.json. There is a .husky/ directory and a postinstall script that runs husky install, so the hooks are set up on clone. A .npmrc is present for npm configuration, and the netlify.toml is what deploys the documentation site.

The presence of a rubocop_todo.yml is worth a small note, because it is an honest signal rather than a flaw. A todo file records the offences the project has accepted for now, which keeps the linter enabled while making the remaining debt explicit. The badge set in the README points at a Code Climate maintainability grade and a test coverage score, so both are tracked in CI.

The legacy directories, and the version pinning you inherit

Two directories in the repository need explaining, because they tell you about the shape of the project's history and about what adopting it costs.

vite_rails_legacy and vite_plugin_legacy exist alongside the current vite_rails and vite-plugin-rails. The word legacy here refers to the older plugin arrangement, kept for applications that have not migrated. A project with a long-lived Rails codebase is likely to have one of these configurations already, and the presence of both in one repository tells you the maintainers support the migration rather than requiring a big-bang change.

The version pinning is the other thing. The engines field in the root package.json asks for node 24 and pnpm 12, and the .node-version and .ruby-version files pin the same thing for the toolchain managers. For a Rails application, adding a Node toolchain to the development and CI environment is the real adoption cost, not the gem itself. A Rails team that has never had Node in its build image will need to install it, and a team with an existing Node setup may find the required version does not match what its other front-end tooling wants.

The pnpm requirement is another one to think about. The repository uses pnpm workspaces, and the root package.json declares pnpm 12 in its engines, which means a contributor or a fork that uses npm or yarn will not get the same resolution. That is a normal consequence of a monorepo, and it is a documented one through the lockfile and the mise.toml.

So the honest summary of the upgrade path is this. Adding the gem to a new application is a three-command operation. Adding it to an existing application that already has a front-end build is a migration of that build to the Vite plugin, and the legacy directories are there for the ones who are not ready to do that yet. The README does not document a rollback procedure for the migration, and it points to the guides on the documentation website rather than enumerating them, which is where the framework-specific details live.

Where vite_ruby is the wrong answer

Three cases are worth naming clearly.

The first is a server-rendered application with no JavaScript build step. If your Rails app renders ERB templates and ships a little progressive enhancement JavaScript with no bundler, adding Vite buys you nothing. You would be introducing a Node toolchain, a second process to run in development, and a build step in production, to serve assets you were already serving with the asset pipeline. The gem solves a problem that only exists once you have a modern front end.

The second is a team that cannot own a Node toolchain. vite_ruby is a bridge between two toolchains, and a bridge means two versions to pin, two failure modes to debug, and a CI image that has to build both. A team whose operations are Ruby-only, or whose deploy pipeline is air-gapped and has a curated list of approved build tools, will find that the integration is the problem rather than the solution.

The third is an application that has already solved this with a working setup. The README's Special Thanks names webpacker, and if your Rails app has a webpacker pipeline that your team knows well, the argument for moving is a development speed improvement rather than a capability you lack. That is a legitimate reason to move, but it is a reason to benchmark first, and the README does not offer numbers.

There is also the ordinary scope limit. vite_ruby handles the Vite side, the asset handoff and the deployment integration. It does not give you a component library, a design system, a router or a data layer. If what you need is a front-end framework choice rather than a build tool choice, this is the wrong layer to solve it at.

Editorial conclusion

Adopt vite_ruby if you are building a Ruby web application with a modern JavaScript front end and you want Vite's dev server and hot reload without hand-rolling the bridge between the two toolchains. Do not adopt it if your front end is server-rendered ERB with no bundler step, or if you cannot add a Node toolchain to your build environment. Verify first that your Ruby and Node versions match the .ruby-version and .node-version files in the repository, that your production deploy runs assets:precompile or the equivalent, and that the configuration file your framework generates matches the configuration reference before you customise it.

Frequently asked questions

Which gem do I install for my Ruby framework?

The README gives `gem 'vite_rails'` for Rails, vite_hanami for Hanami apps and vite_ruby for Rack apps. The repository also contains vite_padrino for Padrino, along with the legacy vite_rails_legacy and vite_plugin_legacy for applications on the older plugin arrangement.

How do I install vite_ruby and run the dev server?

Add the gem to your Gemfile, then run `bundle install` and `bundle exec vite install` to generate the configuration files and a sample setup. After restarting your web server, run `bin/vite dev` and look for the printed console output on any page.

Does vite_ruby change how production assets are built?

The README lists integration with assets:precompile among the features, and describes zero-config deployments. In production Vite bundles with tree-shaking, lazy-loading and common chunk splitting, while the existing asset pipeline invocation handles the build.

What does vite_ruby need from the build environment?

The root package.json declares engines node 24 and pnpm 12, and the repository pins versions in .node-version, .ruby-version and mise.toml. The monorepo uses pnpm workspaces with a pnpm-workspace.yaml and pnpm-lock.yaml, so a Node and pnpm toolchain has to be present in development and CI.

Official sources

  1. ElMassimo/vite_ruby on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/elmassimo-vite-ruby.svg)](https://hysenlabs.com/projects/elmassimo-vite-ruby)

Was this useful?