Vitest Global Setup
Vitest's globalSetup feature runs code once before all tests execute, and optionally a cleanup function after all tests complete.
Ben Houston • November 19, 2025 • 4 min read
Vitest's globalSetup feature runs code once before all tests execute, and optionally a cleanup function after all tests complete. Tested on Vitest 2.x through 4.x.
How Global Setup Works#
Common uses:
- Setting up database connections
- Configuring environment variables
- Starting test servers
- Initializing shared resources
Setting Up the Global Setup File#
Create a file that exports a default async function. Vitest calls it before any tests run. The function receives a TestProject parameter that provides access to Vitest's project configuration.
Basic Structure#
// src/test-utils/beforeTests.ts import type { TestProject } from 'vitest/node'; export default async function setup(project: TestProject): Promise<void> { console.log('Starting global setup for project:', project.name); // Your setup code here console.log('Global setup complete!'); }
With Cleanup Function#
The setup function can return a cleanup function that will be executed after all tests complete:
// src/test-utils/beforeTests.ts import type { TestProject } from 'vitest/node'; import afterTests from './afterTests.js'; // the method name doesn't matter, just that it is the default export export default async function beforeTests(project: TestProject): Promise<() => Promise<void>> { console.log('starting beforeTests for project:', project.name); // Perform setup tasks await new Promise((resolve) => setTimeout(resolve, 1000)); console.log('finished beforeTests'); // Return cleanup function that runs after all tests return afterTests; }
The Teardown File#
Create a separate file for your cleanup logic (or you could combine it with the setup file):
// src/test-utils/afterTests.ts export default async function afterTests(): Promise<void> { console.log('starting afterTests'); // Perform cleanup tasks await new Promise((resolve) => setTimeout(resolve, 1000)); console.log('finished afterTests'); }
Configuring Vitest#
Add the globalSetup option to your vitest.config.ts:
// vitest.config.ts import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, environment: 'node', globalSetup: ['./src/test-utils/beforeTests.ts'], }, });
The globalSetup option accepts an array of file paths. Vitest runs these files in order before any tests start. If a setup file returns a cleanup function, Vitest calls it after all tests complete, in reverse order.
Passing Configuration to Tests#
Use process.env to pass values from global setup to your tests:
// src/test-utils/beforeTests.ts import type { TestProject } from 'vitest/node'; export default async function setup(project: TestProject): Promise<() => Promise<void>> { console.log('Starting global setup for project:', project.name); // Set environment variables that tests can access const DATABASE_URL = 'postgresql://localhost:5432/test'; process.env['DATABASE_URL'] = DATABASE_URL; console.log('DATABASE_URL', DATABASE_URL); // Set other configuration values process.env['API_KEY'] = 'test-api-key'; process.env['NODE_ENV'] = 'test'; // Your setup code here await new Promise((resolve) => setTimeout(resolve, 1000)); console.log('Global setup complete!'); return async () => { // Cleanup: optionally clear environment variables console.log('Cleanup complete!'); }; }
Using Configuration in Tests#
Your tests can now access these environment variables:
// src/database.test.ts import { describe, it, expect } from 'vitest'; describe('Database', () => { it('should connect using DATABASE_URL', () => { const dbUrl = process.env['DATABASE_URL']; expect(dbUrl).toBe('postgresql://localhost:5432/test'); // Use dbUrl in your test... }); });
Common Use Cases#
Database Setup#
export default async function setup(): Promise<() => Promise<void>> { // Connect to test database const db = await connectToDatabase(); process.env['DATABASE_URL'] = db.connectionString; // Run migrations await db.migrate(); return async () => { // Clean up test data await db.cleanup(); await db.close(); }; }
API Server Setup#
export default async function setup(): Promise<() => Promise<void>> { // Start test server const server = await startTestServer(); process.env['API_URL'] = `http://localhost:${server.port}`; return async () => { // Stop server await server.stop(); }; }
Environment Configuration#
export default async function setup(): Promise<() => Promise<void>> { // Set all test environment variables process.env['NODE_ENV'] = 'test'; process.env['LOG_LEVEL'] = 'error'; process.env['API_TIMEOUT'] = '5000'; return async () => { // Optionally restore original values delete process.env['NODE_ENV']; }; }
Conclusion#
Export a default async function from your setup file. Return a cleanup function if you need teardown. Vitest runs the setup before tests start and calls the cleanup when they finish.