Does Ruby on Rails Work With Vitest?

Partially CompatibleLast verified: 2026-02-26

Vitest can test Rails frontend assets and JavaScript, but not Rails backend code—you'll need separate testing strategies for each layer.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
medium
Minimum Versions
Ruby on Rails: 6.0
Vitest: 0.34.0

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

Testing Vue.js or React components embedded in Rails views with fast HMR feedback
Unit testing JavaScript utilities and helper functions used across your Rails frontend
Testing Stimulus controllers that drive Rails interactivity without Rails request overhead
Running frontend tests in CI before backend tests to catch JS errors early

Quick Setup

bash
bundle exec rails generate vite:install && npm install -D vitest @vitest/ui happy-dom
bash
// 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

critical

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

warning

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

warning

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

info

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