Testing, diagnostics, and observability
Catch project-shape, type, route, hydration, performance, and production failures at the appropriate layer.
Use the fastest useful check
During implementation, start with targeted tests and typechecking. Before shipping, validate the production route graph, SSR output, browser behavior, and route bundle sizes.
bashnpx tavo doctor
npx tavo check
npx tavo routes
npx tavo build --report-json
npx tavo preview --ssrMake runtime failures actionable
Development diagnostics can report runtime errors, mount and patch traces, and hydration mismatches with phase and DOM path context. Use this information to find the first server-client divergence rather than suppressing the warning.
tsimport { configureDevDiagnostics } from "@tavojs/core/dev";
configureDevDiagnostics({
enabled: true,
devMode: true,
onHydrationMismatch: (event) => console.warn(event.path, event.kind),
onError: (error) => console.error(error)
});Instrument lifecycle events without leaking data
Instrumentation emits route resolution, middleware, loader, action, and cache lifecycle events. Events contain route patterns and timing metadata rather than request bodies, cookies, tokens, or loader results.
Framework testing API
Render components and routes with small deterministic helpers before moving to browser tests.
| API / option | Type | Default | Behavior |
|---|---|---|---|
createTestRoot() | TestRoot | new detached div | Requires a DOM environment and exposes render, hydrate, unmount, text, and html. |
flushMicrotasks() | Promise<void> | — | Waits through one queued microtask turn. |
expectTextContent(root, expected) | void | — | Throws with expected and actual text when the values differ. |
captureDiagnostics() | { traces, mismatches, restore } | diagnostics enabled | Captures trace and hydration mismatch events until restore disables and clears callbacks. |
createPagesTestHarness(modules, options) | route harness | — | Exposes runtime, renderPath, and asynchronous resolvePath. Rendering requires a DOM. |
clearServices / unregisterService | test cleanup | — | Resets process-wide service registration between tests. |
tsximport {
captureDiagnostics,
createTestRoot,
expectTextContent,
flushMicrotasks
} from "@tavojs/core/dev";
const diagnostics = captureDiagnostics();
const root = createTestRoot();
root.render(<Counter />);
await flushMicrotasks();
expectTextContent(root, "Count: 0");
root.unmount();
diagnostics.restore();Coded framework errors
keeps a stable code for tools and logs while retaining a human message, optional details, remediation hint, and cause. Use before reading the code and when presenting the hint to a developer.
tsimport { formatTavoError, isTavoError } from "@tavojs/core";
try {
await startApplication();
} catch (error) {
if (isTavoError(error)) console.error(error.code, formatTavoError(error));
}TAVO_PAGES_001: invalid resolved-page cache limit.TAVO_PAGES_002: missing client root element.TAVO_PAGES_003/ 004 / 005: page discovery or server bootstrap failure.TAVO_SSR_001: invalid canonical SSR origin.TAVO_CONFIG_001/ 002: server-only or likely secret code reached a client boundary.TAVO_PLUGIN_001: plugin descriptor targets an unsupported contract.TAVO_HYDRATION_001: strict hydration found a server/client mismatch.
Instrumentation event contract
Build a private observer with , or adapt an OpenTelemetry tracer with . Both produce a value for the SSR configuration.
| API / option | Type | Default | Behavior |
|---|---|---|---|
name | "route.resolve" | "route.middleware" | "route.loader" | "route.action" | "route.cache" | — | Identifies the framework operation. |
phase | "start" | "end" | "error" | "abort" | "hit" | "miss" | "invalidate" | — | Identifies lifecycle state and cache outcomes. |
timing/context | timestamp, durationMs, requestId, route, layer | operation-specific | Correlates work without including request content. |
result/cache | status, count, cacheTags, error | operation-specific | Carries bounded result metadata. Treat custom error objects as potentially sensitive. |
Observer exceptions are isolated and never interrupt framework work.
The
OpenTelemetryadapter pairs start and terminal events into spans.recordErrorsdefaults to false; enable it only after application-level redaction is configured.Request bodies, headers, cookies, tokens, loader data, and store state are not emitted by the framework.
Look up exact public types
Follow linked API names to their canonical TypeScript declarations and package boundaries.