Configuring Vitest in a DevContainer

Vitest gives fast unit-test feedback, and running it inside the devcontainer keeps tests on the same toolchain as the build. This page configures Vitest in a container — resolving the same TypeScript path aliases, watching efficiently, and reusing the cached dependency store.

Prerequisites

You need a Node/TypeScript devcontainer with Vitest.

  • A Node Feature pinned and the package manager set.
  • Vitest as a dev dependency.
  • tsconfig path aliases mirrored in the Vitest config.

Vitest prerequisitesYou need Vitest pinned, aliases resolved, watch working, and passing tests.Vitest deppinnedAlias resolvematch tsconfigWatchefficient in containerVerifytests pass

Step-by-Step Implementation

  1. Install Vitest and resolve tsconfig path aliases.
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({ plugins: [tsconfigPaths()] });
  1. Run tests inside the container.
corepack pnpm vitest run
  1. Use watch mode for feedback (polling if file events are flaky on a mount).
pnpm vitest --watch
  1. Verify aliases resolve and tests pass.
pnpm vitest run   # @app/* imports resolve like the build

Vitest setupVitest with the tsconfig-paths plugin resolves aliases and gives fast in-container feedback.Vitest (dev dep)pinned test runnertsconfigPaths pluginaliases resolveWatch modefast feedbackCached storequick installs

Common Pitfalls

Vitest issues are unresolved aliases or flaky watch on a bind mount.

Vitest triageA triage path from failing aliases or watch to fast in-container tests.Do @app/* imports resolve in tests?NOAdd the tsconfig-paths pluginDoes watch pick up changes?YESStore cached for fast installsFast in-container tests

SymptomRoot CauseRemediation
@app/* fails only in testsVitest doesn't read tsconfig pathsAdd vite-tsconfig-paths plugin
Watch mode misses changesBind-mount file events flakyEnable polling in watch
Tests differ from CIUnpinned Vitest/runtimePin Vitest and the Node version
Slow installs before testsStore not cachedCache the pnpm/npm store on a volume

Conclusion

Run Vitest inside the container so tests use the same toolchain as the build, resolve TypeScript path aliases with the tsconfig-paths plugin so imports match, and enable polling if a bind mount makes file events flaky. Fast, faithful test feedback in the environment developers actually use.

Configure and gainConfiguring aliases and watch gives fast tests that resolve like the build.Configuretsconfig-paths pluginWatch (polling)Pinned VitestSo testsResolve like buildGive fast feedbackMatch CI

FAQ

Why do my Vitest imports fail on path aliases? Because Vitest doesn't automatically read tsconfig.json paths. Add the vite-tsconfig-paths plugin to vitest.config.ts so the test runner resolves @app/* the same way the type-checker and build do, and the imports work in tests.

Why does watch mode miss my changes in a container? Native file-system events can be unreliable across a bind mount. Enable polling in Vitest's watch configuration so it detects changes by polling the filesystem, which is more reliable in a mounted workspace at the cost of slightly more CPU.

How do I keep Vitest results consistent with CI? Pin Vitest as a dev dependency and pin the Node version via the Feature, so the container and CI run identical versions. Run tests inside the container in both places (locally and via devcontainer exec in CI) for the same toolchain.