Appearance
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 @vibenvLogin 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/loggerIf you're using TypeScript (recommended), ensure you have:
bash
npm install --save-dev @babel/core @babel/preset-react @babel/preset-typescript babel-loader typescript3) 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-agentendpoint 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 startYou 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
- Check that the
DevAgentWebpackPluginis properly imported and added to the plugins array - Verify that
babelPluginVibenvJsxAttributeis included in your Babel configuration - Ensure the dev server is running and accessible
- Check browser console for any errors
Component metadata not being injected
- Verify that the babel plugin is correctly configured in your webpack config
- Make sure the
babel-loaderis processing your.tsxfiles - Check that the test pattern
/\.tsx?$/matches your component files
TypeScript errors
- Ensure
@types/reactand@types/react-domare installed - Verify your
tsconfig.jsonhas the correctjsxsetting:"jsx": "react-jsx" - Make sure the
includearray intsconfig.jsoncovers your source files
Dev server routes not working
- Verify that express is imported and the routes are mounted correctly
- Check that
setupMiddlewaresis properly configured in the devServer options - Ensure
@vibenv/vibe-serverand@vibenv/loggerare 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
DevAgentWebpackPluginhandles 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