A Babel and SWC plugin with development server for visual editing with Codepress. The plugin adds file identifiers to JSX elements, while the development server provides API endpoints for applying code changes from the visual editor.
CodePress Engine now supports both Babel and SWC compilers in a single package:
- Babel Plugin:
@quantfive/codepress-engine/babel- For traditional Babel-based builds - SWC Plugin:
@quantfive/codepress-engine/swc- For Next.js 15+ and other SWC-based tools
npm install --save-dev @quantfive/codepress-engineThis package includes:
- Babel Plugin - Adds file path attributes to JSX elements for visual editing
- SWC Transform - Same functionality as Babel plugin but 20-70x faster using SWC
- Development Server - Processes visual editing requests and applies changes to source files
- CLI Tool - Easy way to start the development server alongside your app
Add the plugin to your Babel configuration:
// babel.config.js
module.exports = {
plugins: ["@quantfive/codepress-engine"],
};// babel.config.js
module.exports = {
plugins: [
[
"@quantfive/codepress-engine",
{
// HTML attribute names (optional - defaults shown below)
attributeName: "codepress-data-fp", // default: 'codepress-data-fp'
repoAttributeName: "codepress-github-repo-name", // default: 'codepress-github-repo-name'
branchAttributeName: "codepress-github-branch", // default: 'codepress-github-branch'
},
],
],
};⚡ For faster builds (20-70x faster than Babel), use the SWC transform instead:
// Build script or webpack loader
const {
transformWithCodePress,
} = require("@quantfive/codepress-engine/swc-plugin");
async function transformFile(code, filePath) {
const result = await transformWithCodePress(code, filePath, {
// Same options as Babel plugin
attributeName: "codepress-data-fp",
repoAttributeName: "codepress-github-repo-name",
branchAttributeName: "codepress-github-branch",
});
return result.code;
}With Webpack:
// webpack.config.js
const {
transformWithCodePress,
} = require("@quantfive/codepress-engine/swc-plugin");
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: [
{
loader: "@swc/loader",
options: {
jsc: {
parser: { syntax: "typescript", tsx: true },
transform: { react: { runtime: "automatic" } },
},
},
},
// Custom loader for CodePress
path.resolve("./codepress-loader.js"),
],
},
],
},
};
// codepress-loader.js
module.exports = function (source) {
const callback = this.async();
transformWithCodePress(source, this.resourcePath)
.then((result) => callback(null, result.code))
.catch((err) => callback(err));
};With Next.js 15 (using SWC):
// next.config.js
const {
transformWithCodePress,
} = require("@quantfive/codepress-engine/swc-plugin");
module.exports = {
webpack: (config) => {
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
use: [
{
loader: path.resolve("./codepress-loader.js"),
},
],
});
return config;
},
};| Tool | Speed | Ease of Use | TypeScript Support |
|---|---|---|---|
| Babel Plugin | 1x (baseline) | ✅ Easy | ✅ Via preset |
| SWC Transform | 20-70x faster | ✅ Easy | ✅ Built-in |
- Use SWC Transform if you want maximum performance and your build tool supports custom transformations
- Use Babel Plugin if you need maximum compatibility or are using a traditional Babel-based setup
| Feature | Babel Plugin | SWC Plugin |
|---|---|---|
| Performance | 1x (baseline) | 20-70x faster |
| Line Numbers | ✅ Accurate source line numbers | ❌ Not included (to avoid WASM serialization issues) |
| Encoding | ✅ Identical XOR + base64 encoding | ✅ Identical XOR + base64 encoding |
| Git Detection | ✅ Auto-detects repo/branch | ✅ Auto-detects repo/branch |
| Output Format | {encodedPath}:{startLine}-{endLine} |
{encodedPath} (no line numbers) |
Both plugins provide identical functionality and output - the choice is about performance vs compatibility.
The Babel plugin transforms your JSX elements during the build process by:
-
Adding File Path Attributes: Each JSX element gets a
codepress-data-fpattribute containing:- An encoded file path (for security)
- Line numbers indicating where the element appears in the source code
- Format:
{encodedPath}:{startLine}-{endLine}(SWC) or{encodedPath}:{startLine}-{endLine}(Babel)
-
Adding Repository Information: Container elements (html, body, div) get:
codepress-github-repo-name- The repository name (e.g., "owner/repo")codepress-github-branch- The git branch name
-
Auto-Detection: The plugin automatically detects:
- Current git branch using
git rev-parse --abbrev-ref HEAD - Repository name from git remote URL (supports HTTPS and SSH formats)
- Production vs development environment from
NODE_ENV
- Current git branch using
Given this JSX code in src/components/Button.jsx:
// Line 1
import React from "react";
// Line 4
const Button = ({ variant, children, ...props }) => {
return (
<button className={`btn btn-${variant}`} {...props}>
{children}
</button>
);
};
// Line 15
export default function ButtonExamples() {
return (
<div className="examples">
<Button variant="primary">Primary Button</Button>
<Button variant="secondary">Secondary Button</Button>
</div>
);
}The plugin transforms it to (showing encoded file paths with line numbers):
// Babel Plugin Output (with line numbers):
const Button = ({ variant, children, ...props }) => {
return (
<button
className={`btn btn-${variant}`}
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ:6-12"
{...props}
>
{children}
</button>
);
};
export default function ButtonExamples() {
return (
<div
className="examples"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ:17-26"
codepress-github-repo-name="owner/repo"
codepress-github-branch="main"
>
<Button
variant="primary"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ:18-20"
>
Primary Button
</Button>
<Button
variant="secondary"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ:22-24"
>
Secondary Button
</Button>
</div>
);
}
// SWC Plugin Output (without line numbers to avoid serialization issues):
const Button = ({ variant, children, ...props }) => {
return (
<button
className={`btn btn-${variant}`}
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ"
{...props}
>
{children}
</button>
);
};
export default function ButtonExamples() {
return (
<div
className="examples"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ"
codepress-github-repo-name="owner/repo"
codepress-github-branch="main"
>
<Button
variant="primary"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ"
>
Primary Button
</Button>
<Button
variant="secondary"
codepress-data-fp="EB0HShMdCAMcQwMHGBYCLhIWWxkQGQ"
>
Secondary Button
</Button>
</div>
);
}This allows the Codepress browser extension to:
- Map any DOM element back to its source file and line numbers
- Automatically detect which repository and branch the code belongs to
- Enable visual editing without manual setup
The plugin automatically detects git information without any configuration needed:
-
Git Branch: Automatically detects the current git branch using
git rev-parse --abbrev-ref HEAD. If git is not available or the command fails, it falls back to usingmainas the default branch. -
Repository Name: Automatically extracts the repository name from your git remote URL. It parses GitHub URLs (both HTTPS and SSH formats) to extract the owner and repository name in the format
owner/repo. Supported URL formats:https://github.com/owner/repo.git[email protected]:owner/repo.git
This information is automatically embedded in your compiled JSX, requiring zero configuration.
This plugin:
- Generates a unique hash for each file processed by Babel
- Adds file hash attributes to all JSX opening elements:
codepress-data-fp- Contains the file's unique hash on each element
- Adds repository information to container elements (html, body, or div):
codepress-github-repo-name- Contains the repository name (owner/repo)codepress-github-branch- Contains the branch name
- Creates a mapping file (codepress-file-hash-map.json) that connects hashes to file paths
- Optionally syncs the file mappings with a CodePress backend server
The repository and branch information is:
- Added to HTML, body or div elements that will actually appear in the DOM
- Only added once per file to keep the DOM clean and efficient
- Added in plain text format for easy access
- Automatically detected by the browser extension without requiring manual selection
Note: In a typical React app, the repo attributes will be added to the first div element encountered because the html and body elements aren't usually processed by Babel directly.
This allows the CodePress extension to identify which React component file corresponds to rendered HTML elements, enabling visual editing capabilities with automatic repository detection.
The plugin includes a utility module for extracting repository and branch information from DOM elements:
// In your browser extension
const {
extractRepositoryInfo,
} = require("@quantfive/codepress-engine/hash-util");
// Automatically detect repository info from the DOM
function detectRepositoryInfo() {
// Check root elements first (html, body, head)
const rootElements = [
document.documentElement, // html
document.body,
document.head,
];
// Look for repo attributes in root elements first
for (const element of rootElements) {
if (!element) continue;
if (element.hasAttribute("codepress-github-repo-name")) {
const repository = element.getAttribute("codepress-github-repo-name");
const branch = element.getAttribute("codepress-github-branch") || "main";
return { repository, branch };
}
}
// Fallback: Look for any elements with repo attributes
const element = document.querySelector("[codepress-github-repo-name]");
if (!element) return null;
const repository = element.getAttribute("codepress-github-repo-name");
const branch = element.getAttribute("codepress-github-branch") || "main";
return { repository, branch };
}
// Use the repository info in your extension
const repoInfo = detectRepositoryInfo();
if (repoInfo) {
console.log(`Repository: ${repoInfo.repository}, Branch: ${repoInfo.branch}`);
// Use this information instead of asking the user to manually select a repository
}This automatic detection enables a seamless experience where the browser extension immediately knows which repository and branch the page is built from, eliminating the need for users to manually select anything.
The plugin uses encoding to protect file paths from being exposed in the DOM:
- File Path Encoding: Original file paths are encoded using XOR encryption with a secret key
- URL-Safe Format: Encoded paths use base64 with URL-safe characters (- and _ instead of + and /)
- Line Number Inclusion: Each attribute includes start and end line numbers for precise mapping
This ensures that:
- Source file structures aren't exposed to end users
- The browser extension can still decode paths when needed
- Visual editing remains secure and performant
The development server processes visual editing requests from the Codepress browser extension and applies code changes to your source files. It automatically starts in development environments and provides API endpoints for the visual editor.
The easiest way to use the Codepress development server is through our CLI:
# Install the package globally (optional)
npm install -g @quantfive/codepress-engine
# Just run the server
npx codepress server
# Run server alongside your app (pass through any command)
npx codepress npm start
npx codepress yarn dev
npx codepress craco startAdd Codepress to your package.json scripts:
{
"scripts": {
"start": "craco start",
"dev": "codepress craco start"
}
}Or use it with npm/yarn start:
{
"scripts": {
"start": "react-scripts start",
"dev": "codepress npm start"
}
}The server can be configured using environment variables:
CODEPRESS_DEV_PORT: Port to run the server on (default: 4321)CODEPRESS_BACKEND_HOST: Backend API host (default: localhost)CODEPRESS_BACKEND_PORT: Backend API port (default: 8000)CODEPRESS_API_TOKEN: API token for backend authenticationNODE_ENV: Must be different from 'production' for the server to start
- Development Only: Runs only when
NODE_ENV !== "production" - Single Instance: Uses file locking to prevent multiple server instances
- Fixed Port: Uses port 4321 by default for predictable addressing
- CORS Enabled: Allows cross-origin requests from the browser extension
- Auto-formatting: Applies Prettier formatting to modified files
- Image Handling: Saves images from visual editor to the public directory
- Backend Integration: Communicates with the Codepress backend API for AI assistance
- GET
/ping- Health check endpoint, returns "pong" - GET
/meta- Server metadata including version and uptime - POST
/visual-editor-api- Main endpoint for processing visual edits - POST
/visual-editor-api-ai- AI-powered editing endpoint
The server provides two main endpoints for processing visual edits:
Processes regular visual edits and agent-mode changes:
POST /visual-editor-api
Content-Type: application/json
{
"encoded_location": "c3JjL2NvbXBvbmVudHMvSGVhZGVyLmpzeg:2-6",
"old_html": "<div>Original HTML content</div>",
"new_html": "<div>Updated HTML content</div>",
"github_repo_name": "owner/repo",
"image_data": "data:image/png;base64,iVBORw0KGgo...",
"filename": "image.png",
"style_changes": ["color: red", "font-size: 16px"],
"text_changes": [{"type": "replace", "old": "Hello", "new": "Hi"}],
"agent_mode": false
}Required Parameters:
encoded_location: Encoded file path with line numbers (from codepress-data-fp attribute)old_html: Original HTML contentnew_html: Updated HTML content
Optional Parameters:
github_repo_name: Repository name for backend APIimage_data: Base64-encoded image datafilename: Filename for saved imagesstyle_changes: Array of CSS style changestext_changes: Array of text modificationsagent_mode: Whether to use agent-based changes (default: false)
Processes AI-powered editing requests:
POST /visual-editor-api-ai
Content-Type: application/json
{
"encoded_location": "c3JjL2NvbXBvbmVudHMvSGVhZGVyLmpzeg:2-6",
"ai_instruction": "Make the text larger and change the color to blue",
"github_repo_name": "owner/repo",
"image_data": "data:image/png;base64,iVBORw0KGgo...",
"filename": "screenshot.png"
}Required Parameters:
encoded_location: Encoded file path with line numbersai_instruction: Natural language instruction for the AI
Optional Parameters:
github_repo_name: Repository name for backend APIimage_data: Screenshot or reference imagefilename: Filename for saved images
When processing visual edits, the server:
- Decodes the file location from the
encoded_locationparameter - Reads the current file content from the source file
- Saves any included images to the public directory
- Calls the backend API to get code changes:
- Regular mode:
/api/code-sync/get-changesor/api/code-sync/get-agent-changes - AI mode:
/api/code-sync/get-ai-changes
- Regular mode:
- Applies the changes using line-based text transformations:
insert: Adds new lines after a specified linedelete: Removes lines between start and end positionsreplace: Replaces lines between start and end positions
- Formats the code with Prettier (TypeScript parser)
- Writes the updated content back to the source file
- Returns success response with details about applied changes
The server supports three types of text changes:
// Insert new content after line 5
{
"type": "insert",
"line": 5,
"codeChange": "console.log('New line');"
}
// Delete lines 10-15
{
"type": "delete",
"startLine": 10,
"endLine": 15
}
// Replace lines 20-25 with new content
{
"type": "replace",
"startLine": 20,
"endLine": 25,
"codeChange": "const newCode = 'replacement';"
}Changes are applied in reverse order (highest line numbers first) to prevent index shifting issues.
For advanced use cases, you can also start the server programmatically:
// Only use this in Node.js environments, not in browser code
const { startServer } = require("@quantfive/codepress-engine/server");
const server = startServer({
port: 5678, // Optional custom port
});Important: The server module uses Node.js specific libraries and should only be imported in a Node.js environment, not in browser code. Use the CLI approach for the simplest integration.
Major Update: Complete rewrite with new architecture
- Simplified Configuration: Removed complex database sync options, focuses on core functionality
- Enhanced File Encoding: Improved security with XOR encryption for file paths
- Line-Based Mapping: Each JSX element includes precise line number ranges
- Auto-Detection: Automatic git branch and repository detection from remote URLs
- Repository Attributes: Clean, unencoded repository and branch information on container elements
- Performance: Optimized for faster build times with minimal configuration
- Complete Rewrite: New Fastify-based server with comprehensive API endpoints
- Visual Editor API: Two specialized endpoints for regular and AI-powered editing
- Text Change Engine: Advanced line-based text transformation system supporting insert, delete, and replace operations
- Backend Integration: Seamless communication with Codepress backend API for change calculations
- Image Handling: Automatic image saving and processing from visual editor
- Auto-Formatting: Prettier integration for consistent code formatting
- Request Validation: Comprehensive input validation and error handling
- Authentication: Support for API tokens and OAuth authentication
- CORS Support: Full cross-origin request support for browser extension integration
- Separation of Concerns: Clear separation between build-time plugin and runtime server
- Production Safety: Server only runs in development environments
- Single Instance: File locking prevents multiple server instances
- Environment Variables: Comprehensive configuration through environment variables
- Error Handling: Robust error handling with detailed logging
- Testing: Complete test suite with 42 passing tests covering all functionality
- Removed database sync functionality (now handled by development server)
- Removed file mapping output (replaced with real-time processing)
- Changed API endpoint structure and request formats
- Updated environment variable names for consistency
- Added new
/get-changesAPI endpoint for applying text-based changes to source files - Implemented file mapping storage for tracking file identifiers
- Added integration with FastAPI backend for determining code changes
- Added Prettier formatting for updated files
- Added CLI tool for running the development server (
codepresscommand) - Added Visual Editor API endpoint (
/visual-editor-api) for file updates from the browser extension - Simplified server port configuration to use a fixed port (4321 by default) for reliability
- Added development server accessible via import '@quantfive/codepress-engine/server'
- Server automatically starts in development environments
- Includes port auto-detection and singleton pattern
- Removed hashing from repository and branch attributes for simpler integration
- Added restriction to only apply repository attributes to container elements (html, body, div)
- Simplified repository detection in the browser extension
MIT