Skip to content

Overview

This guide shows you how to integrate Vibenv into a React 19 application using Webpack. The integration uses a custom webpack configuration that injects Vibenv metadata into your React components and mounts the Vibenv dev server routes alongside your webpack dev server.

Prerequisites

Before you begin, make sure you have:

  • A React 19 project with Webpack 5
  • TypeScript configured (recommended but not required)
  • Node.js 18 or higher
  • Access to the Vibenv npm registry

1) Configure .npmrc for Vibenv packages

Vibenv ships as scoped packages from the Vibenv registry. Add this to your project-level .npmrc:

ini
@vibenv:registry=https://npm.vibenv.net/

Then authenticate with the Vibenv registry:

bash
npm login --scope @vibenv

Login details will be provided by the Vibenv team.

2) Install dev dependencies

Install the required Vibenv packages and development dependencies:

bash
npm install --save-dev @vibenv/webpack-plugins @vibenv/transpiler-plugins @vibenv/vibe-server @vibenv/logger

If you're using TypeScript (recommended), ensure you have:

bash
npm install --save-dev @babel/core @babel/preset-react @babel/preset-typescript babel-loader typescript

3) Configure webpack

Create or update your webpack.config.js to include the Vibenv plugins and babel transpiler plugin:

js
import path from "path";
import webpack from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import ESLintPlugin from "eslint-webpack-plugin";
import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin";
import express from "express";
import packageJson from "./package.json" with { type: "json" };

// Vibenv imports
import { DevAgentWebpackPlugin } from "@vibenv/webpack-plugins/dev-agent-webpack-plugin.js";
import babelPluginVibenvJsxAttribute from "@vibenv/transpiler-plugins/babelPluginVibenvJsxAttribute.js";
import { routes } from "@vibenv/vibe-server/routes.js";
import { logger } from "@vibenv/logger/serverLogger.js";

const webpackConfig = (env) => ({
  entry: "./src/index.tsx",

  // Source maps for development
  ...(env.production || !env.development ? {} : { devtool: "eval-source-map" }),

  resolve: {
    extensions: [".ts", ".tsx", ".js"],
    plugins: [new TsconfigPathsPlugin()]
  },

  output: {
    path: path.join(import.meta.dirname, "/dist"),
    filename: "build.js"
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /dist/,
        use: [
          {
            loader: "babel-loader",
            options: {
              babelrc: false,
              configFile: false,
              cacheDirectory: true,
              parserOpts: {
                plugins: [
                  ["typescript", {
                    isTSX: true,
                    allowDeclareFields: true,
                    disallowAmbiguousJSXLike: true
                  }],
                  "jsx"
                ]
              },
              presets: [
                ["@babel/preset-react", { runtime: "automatic" }],
                ["@babel/preset-typescript", { isTSX: true, allExtensions: true }]
              ],
              // Vibenv Babel plugin for JSX attribute injection
              plugins: [babelPluginVibenvJsxAttribute],
            },
          }
        ]
      }
    ]
  },

  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      const { app } = devServer;
      app.use(express.json());
      // Mount Vibenv server routes
      app.use("/_vibe-agent", routes(logger));
      return middlewares;
    }
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html"
    }),
    new webpack.DefinePlugin({
      "process.env.PRODUCTION": env.production || !env.development,
      "process.env.NAME": JSON.stringify(packageJson.name),
      "process.env.VERSION": JSON.stringify(packageJson.version)
    }),
    new ForkTsCheckerWebpackPlugin(),
    new ESLintPlugin({ files: "./src/**/*.{ts,tsx,js,jsx}" }),
    // Vibenv DevAgent plugin
    new DevAgentWebpackPlugin(),
  ]
});

export default webpackConfig;

What this configuration does:

  • Babel Plugin (babelPluginVibenvJsxAttribute): Injects Vibenv metadata attributes into your JSX elements during transpilation
  • DevAgentWebpackPlugin: Automatically injects the Vibenv agent script into your application
  • DevServer Routes: Mounts the Vibenv server at /_vibe-agent endpoint for communication with the Vibenv agent

4) Update TypeScript configuration

If you're using TypeScript, ensure your tsconfig.json has the following configuration:

json
{
  "compilerOptions": {
    "sourceMap": true,
    "noImplicitAny": false,
    "module": "esnext",
    "target": "es5",
    "lib": ["esnext", "dom", "dom.iterable"],
    "removeComments": true,
    "allowSyntheticDefaultImports": true,
    "jsx": "react-jsx",
    "allowJs": true,
    "baseUrl": "./",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "moduleResolution": "node",
    "downlevelIteration": true
  },
  "include": ["./src", "./webpack.config.ts"]
}

5) Update package.json scripts

Ensure your package.json has the necessary scripts:

json
{
  "scripts": {
    "start": "webpack-cli serve --mode=development --env development --hot",
    "build": "webpack --mode=production --env production --progress",
    "lint": "eslint \"src/**/*.{ts,tsx,js,jsx}\"",
    "lint:fix": "eslint \"src/**/*.{ts,tsx,js,jsx}\" --fix"
  }
}

6) Create your React application

Here's a simple example React component with TypeScript:

tsx
// src/App.tsx
import React from "react";
import HelloWorld from "components/HelloWorld";

const App: React.FC = () => <HelloWorld />;

export default App;
tsx
// src/index.tsx
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";

const container = document.getElementById("root");
const root = createRoot(container!);
root.render(<App />);
tsx
// src/components/TodoList.tsx
import { TodoItem } from "./TodoItem";
import React from "react";

export function TodoList() {
  const items = [
    { id: 1, title: "Buy groceries", completed: false },
    { id: 2, title: "Buy a car", completed: false },
    { id: 3, title: "Buy a house", completed: false }
  ];

  return (
    <div>
      <h1>Todo List</h1>
      {items.map((item) => (
        <TodoItem
          key={item.id}
          id={item.id.toString()}
          title={item.title}
          completed={item.completed}
        />
      ))}
    </div>
  );
}
tsx
// src/components/TodoItem.tsx
import React from "react";

interface TodoItemProps {
  id: string;
  title: string;
  completed: boolean;
}

export function TodoItem(props: TodoItemProps) {
  return (
    <div>
      <input type="checkbox" checked={props.completed} />
      <span>{props.title}</span>
    </div>
  );
}

7) Run the development server

Start your development server:

bash
npm run start

You should see:

  • Webpack compiling your application
  • Vibenv logs in the console during compilation
  • The Vibenv overlay should connect once the page loads

Optional: Set the CLI agent via .vibenv.js

Create .vibenv.js in your project root to control which CLI agent Vibenv uses:

js
module.exports = {
  "cli-agent": "claude" // or "copilot"
};

This file is read from the current working directory when Vibenv starts.

Troubleshooting

Vibenv overlay not appearing

  1. Check that the DevAgentWebpackPlugin is properly imported and added to the plugins array
  2. Verify that babelPluginVibenvJsxAttribute is included in your Babel configuration
  3. Ensure the dev server is running and accessible
  4. Check browser console for any errors

Component metadata not being injected

  1. Verify that the babel plugin is correctly configured in your webpack config
  2. Make sure the babel-loader is processing your .tsx files
  3. Check that the test pattern /\.tsx?$/ matches your component files

TypeScript errors

  1. Ensure @types/react and @types/react-dom are installed
  2. Verify your tsconfig.json has the correct jsx setting: "jsx": "react-jsx"
  3. Make sure the include array in tsconfig.json covers your source files

Dev server routes not working

  1. Verify that express is imported and the routes are mounted correctly
  2. Check that setupMiddlewares is properly configured in the devServer options
  3. Ensure @vibenv/vibe-server and @vibenv/logger are installed

Dependencies Reference

Core dependencies for React 19:

json
{
  "dependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}

Required dev dependencies:

json
{
  "devDependencies": {
    "@vibenv/webpack-plugins": "latest",
    "@vibenv/transpiler-plugins": "latest",
    "@vibenv/vibe-server": "latest",
    "@vibenv/logger": "latest",
    "@babel/core": "^7.26.0",
    "@babel/preset-react": "^7.26.3",
    "@babel/preset-typescript": "^7.26.0",
    "babel-loader": "^9.2.1",
    "typescript": "^5.7.2",
    "webpack": "^5.97.1",
    "webpack-cli": "^6.0.1",
    "webpack-dev-server": "^5.2.0",
    "express": "^4.21.2"
  }
}

Notes

  • The babel transpiler plugin (babelPluginVibenvJsxAttribute) adds metadata attributes to JSX elements, which the Vibenv agent uses for component identification and interaction
  • The DevAgentWebpackPlugin handles automatic script injection and setup
  • The dev server integration allows the Vibenv agent to communicate with your development environment
  • This configuration supports hot module replacement (HMR) for a better development experience
  • TypeScript path mapping is supported via tsconfig-paths-webpack-plugin