Vitest UI: A Visual Test Dashboard for Vue Projects
AI generated
<v/>
{ }
Vitest UI · Vue 3 · Testing · Coverage
Vitest UI
A Visual Test Dashboard for Vue Projects

Vitest UI replaces plain terminal output with an interactive dashboard in the browser, complete with test filtering, module graph, coverage heatmap and snapshot diffs at a glance. Anyone regularly searching through hundreds of tests in a Vue project finds failing cases and untested code paths much faster with Vitest UI than by scrolling through console logs.

13 min read Test Filters · Module Graph · Coverage · Snapshot Diffs Vitest · Vue 3 · Vite · CI

1. What Vitest UI is and what it is for

Vitest UI is the official, browser based interface for the Vitest test runner. Instead of reading test results purely as text lines in a terminal, Vitest UI opens an interactive dashboard where tests, test files and test suites can be browsed, filtered and rerun individually. Important for framing this correctly: Vitest UI does not replace a testing library or test patterns, it is purely the presentation layer for results the same Vitest runner produces anyway.

For Vue projects this matters especially, because test suites with component tests, composable tests and integration tests quickly grow to several hundred individual test cases. Plain terminal output then forces you to scroll through long lists to find a single failing test. Vitest UI solves exactly that problem by making test results structured, searchable and filterable, without installing an additional tool, Vitest UI is part of the Vitest ecosystem itself.

A second aspect that sets Vitest UI apart from plain terminal reporters is direct interactivity. A test can be rerun in isolation with a click, a module graph shows dependencies, and coverage data is highlighted directly in the source code, all in the same view, without switching between multiple tools.

2. Installing and starting Vitest UI

Vitest UI is a separate, optional package, @vitest/ui, installed in addition to Vitest itself. After installation, the --ui flag is enough to open the dashboard in the default browser instead of terminal output. Vitest internally starts a small local server that streams test results to the dashboard in real time while tests keep running in the background.

For Vue projects using Vite as the build tool, integration is seamless, since Vitest already reuses the same Vite configuration and module resolver. An existing vitest.config.ts needs no extra configuration for Vitest UI, the --ui flag is enough, optionally paired with --open false when the dashboard should not auto open in a browser, for example in remote development environments.


# Install Vitest and the optional UI package
npm install -D vitest @vitest/ui

# Start Vitest with the interactive dashboard
npx vitest --ui

# Keep the UI server running but do not auto-open a browser tab
npx vitest --ui --open false

# vitest.config.ts requires no extra setup for the UI itself

3. The dashboard: test tree, filters and search

After startup, Vitest UI shows a hierarchical test tree on the left, grouped by test file and test suite, with color coding for passed, failed and skipped. A search field filters the tree live by file name or test name, handy in large Vue projects with many component and composable tests, where a specific test needs to be found again quickly without rerunning the entire suite.

Clicking on a single test opens a detail view on the right side of the dashboard, with the full assertion history, execution time and, on failure, the exact diff between expected and actual value. For Vue component tests with @vue/test-utils, Vitest UI additionally shows that specific test's console output in isolation, without it mixing with the output of parallel tests, a problem that commonly occurs with plain terminal output under parallelized test runs.

4. Module graph: understanding a test's dependencies

A feature plain terminal reporters simply cannot offer is the module graph in Vitest UI. For every test, a dedicated tab shows which modules were actually imported and executed, including transitive dependencies. That surfaces cases where a supposedly isolated composable test accidentally imports an entire Pinia store or an HTTP client, needlessly increasing test runtime and undermining the test's isolation.

For Vue projects with many barrel exports, that is, index files bundling several modules together, the module graph is particularly revealing. A single import from such an index file often unintentionally pulls the entire module tree of a feature folder into a test, something the graph visualization in Vitest UI reveals but plain test runtime in the terminal does not.


// composables/useCart.spec.ts — an isolated composable test
import { describe, it, expect } from 'vitest'
import { useCart } from './useCart'

describe('useCart', () => {
  it('adds an item and updates the total', () => {
    const { items, total, addItem } = useCart()
    addItem({ id: 1, price: 19.99, quantity: 2 })

    expect(items.value).toHaveLength(1)
    expect(total.value).toBe(39.98)
  })
})

// If useCart imports from a barrel file like "@/composables",
// the Vitest UI module graph reveals every sibling composable
// that gets pulled in as a side effect, not just useCart itself.

5. Coverage visualization right in the dashboard

When Vitest is started with coverage enabled, vitest --ui --coverage, Vitest UI integrates coverage data directly into its own tab, without needing to open a separate HTML report. Every file appears with percentages for lines, branches, functions and statements, and clicking a file shows the source code with color highlighting for which lines are covered by tests and which are not.

For Vue single file components this is especially valuable, because coverage gaps often sit in specific v-if branches in the template or in rarely tested error paths inside the script setup block. The color highlighting right in the Vitest UI dashboard makes such gaps instantly visible, without having to manually load a separate coverage tool like Istanbul in the browser, Vitest UI shows the same report inline.

6. Snapshot diffs and failure details in the browser

For snapshot tests, for example against rendered Vue components with @vue/test-utils and expect(wrapper.html()).toMatchSnapshot(), Vitest UI shows the diff between saved and current snapshot with color highlighting right in the browser, instead of green and red text lines in the terminal. For large HTML snapshots that is far more readable, and a button lets you update the snapshot directly from the dashboard, without running a separate terminal command with -u.

For asynchronous tests that fail with a timeout, Vitest UI also shows the full stack trace including the line in the test code where the timeout was triggered, together with the console output up to that point. That makes debugging easier for tests caused by a missing API mock or a missing await before an asynchronous Vue reactivity change.

7. Watch mode and rerun workflow in daily use

Vitest UI runs in watch mode by default, changes to a test file or an imported source file automatically trigger a rerun, visible directly in the dashboard without a manual refresh. For daily work on a Vue composable, that means: save the file, watch the open Vitest UI tab to see if the matching test stays green, without switching between editor and terminal window.

A practical workflow benefit is rerunning individual tests on demand with a click, without restarting the entire test suite. In a suite with several hundred tests, that noticeably saves time compared with repeatedly running the full terminal suite, especially when a single, isolated component test needs to be adjusted and rechecked several times before the full run is finally confirmed.


// vitest.config.ts — reasonable defaults for the Vitest UI workflow
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'jsdom',
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html'],
    },
    // Re-run only affected tests on file change, shown live in the UI
    watch: true,
  },
})

8. Vitest UI in CI pipelines as a report

For continuous integration, the interactive watch mode of Vitest UI is not directly relevant, since CI runs happen once and non interactively. Vitest offers vitest run --reporter=html for this, which generates a static HTML report in the same visual style as Vitest UI, including test tree, coverage and snapshot diffs, just without the local live server. This report can be uploaded as a CI artifact and opened in a browser afterwards.

For teams that use Vitest UI in local daily development, the HTML report is the natural next step: a failed pipeline run delivers the same familiar interface as local debugging, just as a static artifact instead of a live dashboard. That significantly reduces the friction of switching between local and CI debugging, because the visual language stays identical.

9. Vitest UI compared to terminal output

Vitest's terminal output remains sufficient for quick CI runs and simple projects, but reaches its limits with larger Vue test suites. The following table compares Vitest UI with classic terminal output.

Task Terminal Output Vitest UI Benefit
Find a specific test Scrolling through console log Search field in the test tree Instant filtering, no scrolling
Check coverage Open a separate HTML report Embedded coverage tab No tool switching needed
Read a snapshot diff Colored text lines in the terminal Visual side by side diff Much more readable for HTML snapshots
Rerun a single test Pass test name manually with -t Click the rerun button No terminal command needed
Document CI results Plain text log as artifact HTML report in UI style Same view locally and in CI

In practice, both forms are not mutually exclusive. For quick CI checks, text output remains efficient, for daily local work on a Vue test suite with many cases, Vitest UI delivers the decisive speed advantage when tracking down failures.

Mironsoft

Vue 3, Vitest and durable test infrastructure

A Vue test suite with no clear view of coverage and outliers?

We set up Vitest UI in existing Vue projects, analyze module graphs for hidden test dependencies, and build CI pipelines with HTML reports in the same visual style as the local dashboard.

Test dashboard setup

Integrate Vitest UI into existing Vue projects

Coverage analysis

Find untested code paths through coverage visualization

CI report integration

Set up HTML reports as a pipeline artifact

10. Summary

Vitest UI makes test results in Vue projects far more accessible than plain terminal output, through a searchable test tree, a module graph, embedded coverage visualization and visual snapshot diffs. Watch mode with targeted reruns of individual tests noticeably speeds up daily work on component and composable tests, without installing any additional external tool.

For CI pipelines, Vitest's static HTML report replaces the interactive live version but keeps the same visual language, so local debugging with Vitest UI and tracing a failed pipeline run stay consistent. Anyone maintaining a larger Vue test suite should make Vitest UI a fixed part of their daily workflow.

Vitest UI, the essentials at a glance

Installation

npm install -D @vitest/ui, started with the --ui flag, no extra config needed.

Test tree & module graph

Searchable test tree and module graph reveal hidden test dependencies.

Coverage & snapshots

Coverage highlighted directly in source, snapshot diffs shown visually instead of as text.

CI integration

vitest run --reporter=html produces the same report as a static pipeline artifact.

11. FAQ: Vitest UI for Vue Projects

1What is Vitest UI?
The browser based interface for the Vitest test runner, with test tree, module graph and coverage visualization.
2How do you install it?
npm install -D @vitest/ui, then npx vitest --ui to start the dashboard.
3Does it replace terminal output?
No, it complements it for local development with a visual interface.
4What does the module graph show?
Every module imported by a test, including hidden dependencies from barrel files.
5Does coverage need extra config?
No, the existing coverage config is shown directly in the dashboard.
6How are snapshot diffs shown?
As a visual side by side comparison with a button to update the snapshot directly.
7Rerun individual tests?
Yes, with a click, without restarting the entire test suite.
8Does it work in CI?
Not the interactive mode, but vitest run --reporter=html produces a static report as an artifact.
9Needs its own config?
No, the existing vitest.config.ts is reused directly.
10Worth it for small projects?
Yes, even a few tests benefit from visual coverage highlighting to spot gaps.