diff --git a/docs/guide/open-telemetry.md b/docs/guide/open-telemetry.md
index 4f54c832b..46397042b 100644
--- a/docs/guide/open-telemetry.md
+++ b/docs/guide/open-telemetry.md
@@ -1,5 +1,11 @@
# Open Telemetry Support {#open-telemetry-support}
+::: tip Example Project
+
+[GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/opentelemetry)
+
+:::
+
[OpenTelemetry](https://opentelemetry.io/) traces can be a useful tool to debug the performance and behavior of your application inside tests.
If enabled, Vitest integration generates spans that are scoped to your test's worker.
diff --git a/examples/opentelemetry/README.md b/examples/opentelemetry/README.md
new file mode 100644
index 000000000..bcdc09d91
--- /dev/null
+++ b/examples/opentelemetry/README.md
@@ -0,0 +1,20 @@
+# Vitest Opentelemtry Example
+
+- **Documentation**: https://vitest.dev/guide/open-telemetry.html
+
+## Usage
+
+```sh
+# Start Jaeger service to receive otlp traces over http
+# and serve Web UI at http://localhost:16686
+docker compose up -d
+
+# Run tests (exports with OTLP HTTP by deafult)
+pnpm test --experimental.openTelemetry.enabled
+
+# Use console exporter for quick debugging
+OTEL_TRACES_EXPORTER=console pnpm test --experimental.openTelemetry.enabled
+
+# Run browser mode
+pnpm test --experimental.openTelemetry.enabled --browser.enabled
+```
diff --git a/examples/opentelemetry/docker-compose.yaml b/examples/opentelemetry/docker-compose.yaml
new file mode 100644
index 000000000..dcfffb12c
--- /dev/null
+++ b/examples/opentelemetry/docker-compose.yaml
@@ -0,0 +1,27 @@
+services:
+ # for testing open-telemetry integration locally
+ # https://www.jaegertracing.io/docs/2.12/getting-started/
+ jaeger:
+ image: cr.jaegertracing.io/jaegertracing/jaeger:2.12.0
+ # Assign ports for Jaeger UI and OTLP receiver
+ ports:
+ # UI http://localhost:16686
+ - 16686:16686
+ # OTLP over HTTP (default for NodeSDK)
+ - 4318:4318
+ # Optional: uncomment if needed
+ # - 4317:4317 # OTLP over gRPC
+ # - 5778:5778 # Jaeger sampling strategies
+ # - 9411:9411 # Zipkin compatibility
+
+ # Use volume to persist data across container restarts.
+ # This can be commented out if persistence is not needed.
+ # https://www.jaegertracing.io/docs/2.12/storage/badger/
+ user: '0:0'
+ command: --config /etc/jaeger/config.yml
+ volumes:
+ - ./jaeger-config.yml:/etc/jaeger/config.yml:ro
+ - jaeger-data:/tmp/badger
+
+volumes:
+ jaeger-data:
diff --git a/examples/opentelemetry/jaeger-config.yml b/examples/opentelemetry/jaeger-config.yml
new file mode 100644
index 000000000..bb629b7d1
--- /dev/null
+++ b/examples/opentelemetry/jaeger-config.yml
@@ -0,0 +1,38 @@
+# https://www.jaegertracing.io/docs/2.12/deployment/configuration/
+extensions:
+ jaeger_storage:
+ backends:
+ main_storage:
+ badger:
+ directories:
+ keys: /tmp/badger/keys
+ values: /tmp/badger/data
+ ephemeral: false
+ consistency: true
+ maintenance_interval: 5m
+ jaeger_query:
+ storage:
+ traces: main_storage
+
+receivers:
+ otlp:
+ protocols:
+ grpc:
+ endpoint: 0.0.0.0:4317
+ http:
+ endpoint: 0.0.0.0:4318
+
+processors:
+ batch:
+
+exporters:
+ jaeger_storage_exporter:
+ trace_storage: main_storage
+
+service:
+ extensions: [jaeger_storage, jaeger_query]
+ pipelines:
+ traces:
+ receivers: [otlp]
+ processors: [batch]
+ exporters: [jaeger_storage_exporter]
diff --git a/examples/opentelemetry/otel.js b/examples/opentelemetry/otel.js
new file mode 100644
index 000000000..7b5037963
--- /dev/null
+++ b/examples/opentelemetry/otel.js
@@ -0,0 +1,16 @@
+// @ts-check
+import { NodeSDK } from '@opentelemetry/sdk-node'
+
+const sdk = new NodeSDK({
+ serviceName: 'vitest',
+
+ // NodeSDK uses "@opentelemetry/exporter-trace-otlp-proto" by default.
+ // you can override it via `traceExporter` options.
+ // traceExporter: ...,
+
+ // you can configure additional instrumentations such as `@opentelemetry/auto-instrumentations-node`
+ // via `instrumentations` options.
+ // instrumentations: ...
+})
+sdk.start()
+export default sdk
diff --git a/examples/opentelemetry/package.json b/examples/opentelemetry/package.json
new file mode 100644
index 000000000..0a9cbaca6
--- /dev/null
+++ b/examples/opentelemetry/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@vitest/example-opentelemetry",
+ "type": "module",
+ "private": true,
+ "license": "MIT",
+ "scripts": {
+ "compose": "docker compose",
+ "test": "vitest"
+ },
+ "devDependencies": {
+ "@opentelemetry/sdk-node": "^0.208.0",
+ "@vitest/browser-playwright": "latest",
+ "vite": "latest",
+ "vitest": "latest"
+ }
+}
diff --git a/examples/opentelemetry/src/basic.test.ts b/examples/opentelemetry/src/basic.test.ts
new file mode 100644
index 000000000..f5d6ed57e
--- /dev/null
+++ b/examples/opentelemetry/src/basic.test.ts
@@ -0,0 +1,11 @@
+import { expect, test } from 'vitest'
+import { sleep } from './basic'
+
+test('one plus one', async () => {
+ await sleep(100)
+ expect(1 + 1).toBe(2)
+})
+
+test('one plus two', async () => {
+ expect(1 + 2).toBe(3)
+})
diff --git a/examples/opentelemetry/src/basic.ts b/examples/opentelemetry/src/basic.ts
new file mode 100644
index 000000000..cbacad03e
--- /dev/null
+++ b/examples/opentelemetry/src/basic.ts
@@ -0,0 +1,3 @@
+export function sleep(ms: number): Promise {
+ return new Promise(resolve => setTimeout(resolve, ms))
+}
diff --git a/examples/opentelemetry/vite.config.ts b/examples/opentelemetry/vite.config.ts
new file mode 100644
index 000000000..969493536
--- /dev/null
+++ b/examples/opentelemetry/vite.config.ts
@@ -0,0 +1,20 @@
+import { playwright } from '@vitest/browser-playwright'
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ experimental: {
+ openTelemetry: {
+ // enable via CLI flag --experimental.openTelemetry.enabled=true
+ enabled: false,
+ sdkPath: './otel.js',
+ },
+ },
+ browser: {
+ // enable via CLI flag --browser.enabled=true
+ enabled: false,
+ provider: playwright(),
+ instances: [{ browser: 'chromium' }],
+ },
+ },
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0650ab607..bab87d437 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -370,6 +370,21 @@ importers:
specifier: workspace:*
version: link:../../packages/vitest
+ examples/opentelemetry:
+ devDependencies:
+ '@opentelemetry/sdk-node':
+ specifier: ^0.208.0
+ version: 0.208.0(@opentelemetry/api@1.9.0)
+ '@vitest/browser-playwright':
+ specifier: workspace:*
+ version: link:../../packages/browser-playwright
+ vite:
+ specifier: ^7.1.5
+ version: 7.1.5(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.1)(sass-embedded@1.93.3)(sass@1.93.3)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)
+ vitest:
+ specifier: workspace:*
+ version: link:../../packages/vitest
+
examples/profiling:
devDependencies:
vite: