Does Ruby on Rails Work With Vitest?
Vitest can test Rails frontend assets and JavaScript, but not Rails backend code—you'll need separate testing strategies for each layer.
Quick Facts
How Ruby on Rails Works With Vitest
Vitest is a JavaScript/TypeScript testing framework designed for Vite-bundled projects, making it ideal for testing Rails frontend code when Rails uses Vite as its asset bundler (standard since Rails 7). However, Vitest cannot test Rails backend Ruby code—that's handled by Minitest or RSpec. In a typical Rails + Vitest setup, you'd use Vitest exclusively for JavaScript components, utilities, and frontend logic, while keeping Minitest for Rails models, controllers, and integration tests. The developer experience works smoothly when you treat them as complementary tools: Vitest runs via `npm run test` for your JavaScript, while `rails test` handles backend code. You'll need both test suites in your CI/CD pipeline. The main architectural consideration is ensuring your Rails views and JavaScript remain loosely coupled enough that Vitest can effectively unit-test the JS in isolation without invoking Rails.
Best Use Cases
Quick Setup
bundle exec rails generate vite:install && npm install -D vitest @vitest/ui happy-dom// vitest.config.ts
import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
import rails from 'vite-plugin-rails';
export default defineConfig({
plugins: [rails(), vue()],
test: {
globals: true,
environment: 'happy-dom',
include: ['app/javascript/**/*.spec.ts'],
},
});
// app/javascript/utils/__tests__/math.spec.ts
import { describe, it, expect } from 'vitest';
import { add } from '../math';
describe('Math utilities', () => {
it('adds two numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});
});
// package.json
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui"
}
}Known Issues & Gotchas
Vitest cannot directly test Rails-rendered HTML or make Rails HTTP requests
Fix: Use Rails system tests (Capybara/Selenium) for full integration testing; use Vitest only for isolated JS unit tests
Default Vitest globals (describe, it, expect) may conflict if you also use Minitest syntax in the same codebase
Fix: Use explicit imports in test files or configure Vitest's globals: false and import helpers individually
Rails asset pipeline or importmap setup must be correctly configured to resolve modules that Vitest can consume
Fix: Ensure your vite.config.ts properly aliases Rails paths and that your JS is written as ES modules
Environment variables and Rails secrets won't automatically load in Vitest without explicit configuration
Fix: Use .env files and load them in vitest.config.ts, or mock them in individual tests
Alternatives
- •Jest + Rails (more mature ecosystem, slower, but battle-tested for React/Vue in Rails)
- •RSpec with Rails system tests using Capybara (no separate JS framework; tests full stack)
- •Node.js test runner (tsx/tsx test) for pure JS testing without Vite integration
Resources
Related Compatibility Guides
Explore more compatibility guides