Skip to content

@autotracer/plugin-vite-flow ​

Vite plugin for function flow tracing with dormant mode.

Build-time plugin that instruments functions to track entry, exit, parameters, return values, and exceptions. Integrates with Vite and can start FlowTracer for you in browser apps.

Use @autotracer/plugin-vite-flow for build-time instrumentation and decide whether the plugin is active with inject.

Leave runtimeControlled at its default true when you want dormant startup. Provide dashboardConfig when you want the standard dashboard control workflow on the Vite path.

If you add @autotracer/* imports outside the plugin, gate those imports with the same build condition.

For browser-based targeted runtime control, use the Dashboard workflow.

When the dashboard is not available, use the lower-level commands in @autotracer/flow.

Installation ​

bash
# Install runtime and plugin
pnpm add @autotracer/flow
pnpm add -D @autotracer/plugin-vite-flow @babel/core @babel/preset-typescript

# Using npm
npm install @autotracer/flow
npm install --save-dev @autotracer/plugin-vite-flow @babel/core @babel/preset-typescript

# Using yarn
yarn add @autotracer/flow
yarn add -D @autotracer/plugin-vite-flow @babel/core @babel/preset-typescript

Note: @autotracer/logger installs automatically with @autotracer/flow. @babel/core and @babel/preset-typescript are peer dependencies required for code transformation.

For pnpm users: Add to .npmrc:

ini
# .npmrc
auto-install-peers=true

Entry Point ​

Import this package from its root entry:

typescript
import { flowTracer } from "@autotracer/plugin-vite-flow";

The same root entry also exports the FlowTracerViteOptions TypeScript type.

Quick Start ​

Tracing is instrumented but disabled until activated later:

typescript
// vite.config.ts
import { defineConfig } from "vite";
import { flowTracer } from "@autotracer/plugin-vite-flow";

export default defineConfig(({ mode }) => {
  const enableTracing = mode === "development";

  return {
    plugins: [
      flowTracer({
        inject: enableTracing,
        runtimeControlled: true, // Start dormant (explicit; also the default)
        dashboardConfig: {},
        include: {
          paths: ["**/src/**"],
          functions: ["handle*", "on*", "process*"],
        },
      }),
    ],
  };
});

In browser apps, prefer the dashboard for targeted control. For lower-level start, stop, and status commands, see @autotracer/flow.

Always-On Mode ​

Tracing starts immediately:

typescript
const enableTracing = process.env.INTERNAL_QA === "true";

flowTracer({
  inject: enableTracing,
  runtimeControlled: false,
  include: {
    paths: ["**/src/**"],
    functions: ["*"], // Trace all functions
  },
});

API Reference ​

flowTracer(options) ​

Create Vite plugin instance.

Type Signature:

typescript
function flowTracer(options?: FlowTracerViteOptions): Plugin;

Parameters:

  • options - Optional configuration object

Returns:

Vite plugin object

FlowTracerViteOptions ​

Configuration interface for the Vite plugin.

typescript
interface FlowTracerViteOptions {
  /**
   * Enable or disable code injection
   * @default true
   */
  inject?: boolean;

  /**
   * Runtime-controlled activation (dormant mode)
   * When true, tracing stays off until it is started at runtime
   * @default true
   */
  runtimeControlled?: boolean;

  /**
   * Dashboard widget configuration for browser runtime control.
   * @default undefined
   */
  dashboardConfig?: {
    enabled?: boolean;
    hideByDefault?: boolean;
    position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
    hotkeys?: {
      toggleTracing?: string;
      toggleDashboard?: string;
    };
  };

  /**
   * Include exception logging in catch blocks
   * @default true
   */
  logExceptions?: boolean;

  /**
   * Log level for exception logging
   * @default 'debug'
   */
  exceptionLogLevel?: "debug" | "warn" | "error";

  /**
   * Name of global tracer instance variable
   * @default '__flowTracer'
   */
  tracerName?: string;

  /**
   * Include configuration
   */
  include?: {
    /**
     * File path patterns (glob patterns)
     * @default ["**/*.{js,jsx,mjs,ts,tsx,mts}"]
     */
    paths?: string[];

    /**
     * Function name patterns (glob, regex, or exact strings)
     * @default [] (all functions included)
     */
    functions?: Array<string | RegExp>;
  };

  /**
   * Exclude configuration
   */
  exclude?: {
    /**
     * File path patterns (glob patterns)
     * @default ["**/*.test.*", "**/*.spec.*", "**/node_modules/**", "**/dist/**", "**/build/**", "**/.next/**", "**/coverage/**", "**/tests/**", "**/test/**", "**/__tests__/**"]
     */
    paths?: string[];

    /**
     * Function name patterns (glob, regex, or exact strings)
     * @default []
     */
    functions?: Array<string | RegExp>;
  };

  /**
   * Prefix prepended to every logged function name.
   *
   * Useful in islands or micro-frontend architectures where multiple independent
   * bundles share the same DevTools console, making it clear which app a log belongs to.
   *
   * Example: `prefix: "Island1"` logs `"Island1:processData"` instead of `"processData"`.
   *
   * **Filtering is not affected** — `include`/`exclude` patterns always match against
   * the original, un-prefixed function name.
   *
  * **Runtime start/stop is not affected** — the lower-level runtime commands
  * are global on/off switches; the prefix is a build-time label with no runtime
   * routing or gating effect.
   */
  prefix?: string;

  /**
   * Instrumentation mode.
   * - 'opt-in': Only instrument when `@trace` pragma is present on an eligible function
   * - 'opt-out': Instrument all eligible functions unless `@trace-disable` is present
   * @default 'opt-out'
   */
  mode?: "opt-in" | "opt-out";
}

Use FlowTracer Vite settings for exact per-option behavior and examples. For the browser control path specifically, start with runtimeControlled, dashboardConfig, and the Dashboard Package Reference.

Pragmas ​

Use line comments to control function-level instrumentation.

  • // @trace enables one eligible function.
  • // @trace-disable disables one eligible function.
  • include and exclude decide the eligible set before pragma signals are applied.

For exact placement rules, precedence, nested-function behavior, and examples, see Flow pragma comments.

Automatic Theme Files ​

When inject is true, the Vite plugin loads FlowTracer theme files from the project root and makes them available to FlowTracer at startup.

Put these files directly in the Vite root folder that the plugin builds from. In a typical app, that is the same folder as vite.config.ts and package.json, not src/ or a nested config folder.

Theme file search order:

  • *flow-theme.json
  • *flow-theme-light.json
  • *flow-theme-dark.json

If multiple files match one step, the first alphabetical match wins for that step.

At runtime, FlowTracer selects the lightMode or darkMode branch from that merged theme using your browser's prefers-color-scheme preference.

FlowTracer merges the loaded theme files over DEFAULT_FLOW_THEME.

For the full category reference and repository examples, see FlowTracer Theme API and FlowTracer Example Themes.

Configuration ​

inject ​

Enable or disable code injection.

typescript
// Development only
flowTracer({
  inject: import.meta.env.DEV,
});

// Environment variable control
flowTracer({
  inject: process.env.ENABLE_FLOW_TRACING === "1",
});

runtimeControlled ​

Dormant mode control.

typescript
// Dormant mode: Instrumented but disabled until activated
flowTracer({
  runtimeControlled: true,
});

// Always-on mode: Tracing starts immediately
flowTracer({
  runtimeControlled: false,
});

runtimeControlled defaults to true. Pass false explicitly when you want tracing to start active.

For browser-based setups, pair runtimeControlled: true with dashboardConfig and use the dashboard as the primary control surface.

For lower-level start, stop, and status commands, see @autotracer/flow.

dashboardConfig ​

dashboardConfig is the plugin-owned build setting for automatic dashboard mounting on the Vite browser path.

Use it together with runtimeControlled: true when you want dormant browser startup plus the standard dashboard control surface.

The plugin only applies dashboardConfig when inject is enabled.

For exact field behavior, including the current enabled caveat, use Flow Vite dashboardConfig. For manual mounting, widget controls, and package-side dashboard settings, use Dashboard Package Reference.

include / exclude ​

Selective function instrumentation.

By default, the plugin includes "**/*.{js,jsx,mjs,ts,tsx,mts}", excludes common noise paths such as tests, build outputs, coverage folders, and dependency folders, and applies no function-name filters.

Partial include and exclude objects use object-key merge. Each key you provide replaces the default for that key only. Arrays are never concatenated.

typescript
flowTracer({
  include: {
    paths: ["**/src/**", "**/app/**"],
    functions: ["calculate*", "process*", "handle*", "fetch*"],
  },
  exclude: {
    functions: ["helper*", "internal*", "_*"],
  },
});

This keeps the default path exclusions while adding function-name exclusions.

Pattern Examples:

  • '*' - All
  • 'handle*' - Starts with "handle"
  • '*Handler' - Ends with "Handler"
  • '*process*' - Contains "process"
  • ['on*', 'handle*'] - Multiple patterns

Features ​

Automatic Function Instrumentation ​

Wraps functions with tracing code at build time:

typescript
// Original
function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// Instrumented (simplified)
function calculateTotal(items) {
  logEntry("calculateTotal", { items });
  try {
    const result = items.reduce((sum, item) => sum + item.price, 0);
    logExit("calculateTotal", result);
    return result;
  } catch (error) {
    logException("calculateTotal", error);
    throw error;
  }
}

Exception Logging ​

Tracks exceptions without breaking existing error handling:

typescript
// Original with try/catch
function riskyOperation() {
  try {
    return dangerousCall();
  } catch (error) {
    console.error("Failed:", error);
    throw error;
  }
}

// Instrumented (preserves original catch)
function riskyOperation() {
  logEntry("riskyOperation", {});
  try {
    const result = dangerousCall();
    logExit("riskyOperation", result);
    return result;
  } catch (error) {
    logException("riskyOperation", error);
    console.error("Failed:", error);
    throw error;
  }
}

Async Function Support ​

Handles promises and async/await automatically:

typescript
// Original
async function fetchUser(id) {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

// Example output format:
// → fetchUser (async started)
// param id: "123"
// returned: Promise
// ← fetchUser (async completed, elapsed: 12.3ms)

Dormant Mode ​

No trace output until activated:

typescript
flowTracer({
  runtimeControlled: true,
});

Use the Dashboard for browser-based control. For lower-level runtime commands, see @autotracer/flow.

Perfect for: QA/staging environments where you want tracing available but not always running.

Automatic Runtime Start ​

No manual runtime import needed in dormant mode:

typescript
// Your code - no imports!
function myFunction() {
  return "result";
}

// The plugin starts FlowTracer automatically

Integration ​

With Vite ​

typescript
// vite.config.ts
import { defineConfig } from "vite";
import { flowTracer } from "@autotracer/plugin-vite-flow";

export default defineConfig(({ mode }) => ({
  plugins: [
    flowTracer({
      inject: mode === "development",
      runtimeControlled: true,
      include: {
        paths: ["src/**"],
        functions: ["*"],
      },
    }),
  ],
}));

With React ​

typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { flowTracer } from "@autotracer/plugin-vite-flow";

export default defineConfig({
  plugins: [
    flowTracer({
      include: {
        paths: ["src/**"],
        functions: ["handle*", "on*"],
      },
    }),
    react(),
  ],
});

With Vue ​

typescript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { flowTracer } from "@autotracer/plugin-vite-flow";

export default defineConfig({
  plugins: [
    flowTracer({
      include: {
        paths: ["src/**"],
        functions: ["*"],
      },
    }),
    vue(),
  ],
});

Monorepo / Workspace ​

Add Vite aliases for local packages:

typescript
import path from "path";

export default defineConfig({
  resolve: {
    alias: {
      "@autotracer/flow/runtime": path.resolve(
        __dirname,
        "../../packages/auto-tracer-flow/dist/runtime.js",
      ),
      "@autotracer/flow": path.resolve(
        __dirname,
        "../../packages/auto-tracer-flow",
      ),
      "@autotracer/logger": path.resolve(
        __dirname,
        "../../packages/auto-tracer-logger",
      ),
    },
  },
  plugins: [
    flowTracer({
      /* ... */
    }),
  ],
});

Important: /runtime alias must come before base @autotracer/flow alias.

Requirements ​

  • Vite 4+
  • Node.js 18+
  • Modern browser with ES2020+ support
  • @babel/core and @babel/preset-typescript (peer dependencies)

Performance ​

  • Dormant mode: Logging starts off; overhead is typically low until you activate tracing.
  • Build-time transformation - All instrumentation during build
  • Selective targeting - Only instruments matched functions
  • Fast HMR - Vite's instant hot module replacement preserved

When tracing is active, overhead is often dominated by console output volume and DevTools rendering.

TypeScript Support ​

Full TypeScript support with exported types:

typescript
import type { FlowTracerViteOptions } from "@autotracer/plugin-vite-flow";

const enableTracing = process.env.INTERNAL_QA === "true";

const options: FlowTracerViteOptions = {
  inject: enableTracing,
  runtimeControlled: true,
  include: {
    paths: ["src/**"],
    functions: ["handle*"],
  },
};

Examples ​

Development Only ​

typescript
export default defineConfig(({ mode }) => ({
  plugins: [
    flowTracer({
      inject: mode === "development",
      runtimeControlled: true,
    }),
  ],
}));

Selective Event Handlers ​

typescript
flowTracer({
  include: {
    paths: ["src/**"],
    functions: ["handle*", "on*"],
  },
  exclude: {
    functions: ["handleInternal*", "_*"],
  },
});

API Call Tracking ​

typescript
flowTracer({
  include: {
    paths: ["src/api/**", "src/services/**"],
    functions: ["fetch*", "get*", "post*", "put*", "delete*"],
  },
});

QA Environment ​

typescript
flowTracer({
  inject: process.env.NODE_ENV === "staging",
  runtimeControlled: true, // QA activates as needed
});

Complete Tracing ​

typescript
const enableTracing = process.env.INTERNAL_QA === "true";

flowTracer({
  inject: enableTracing,
  runtimeControlled: false, // Always on when tracing is enabled
  include: {
    paths: ["src/**"],
    functions: ["*"], // All functions
  },
  exclude: {
    functions: ["helper*"],
  },
});

Troubleshooting ​

Not Instrumenting ​

Check:

  1. inject is true
  2. File matches include.paths pattern
  3. Function name matches include.functions pattern
  4. File/function not in exclude patterns
  5. Babel peer dependencies installed

Dormant Mode Not Working ​

Ensure:

  1. runtimeControlled is true
  2. inject is true (default)
  3. If this setup mounts the Dashboard, confirm tracing is started there
  4. Otherwise use the lower-level start command documented in @autotracer/flow

Monorepo Issues ​

Add Vite aliases with /runtime before base package:

typescript
alias: {
  '@autotracer/flow/runtime': path.resolve(/* runtime path */),
  '@autotracer/flow': path.resolve(/* base path */),
}

Build Errors ​

Install peer dependencies:

bash
pnpm add -D @babel/core @babel/preset-typescript

See Also ​

Released under the MIT License.