A Vite plugin that compiles JavaScript to V8 bytecode for Node.js and Electron applications, protecting your source code while maintaining performance.
- 🔒 Source Code Protection - Compiles JavaScript to V8 bytecode, making reverse engineering significantly harder
- ⚡ Native Performance - Uses Node.js's built-in
vm.ScriptAPI for bytecode generation - 🎯 Selective Compilation - Choose specific chunks to compile or compile everything
- 🔐 String Obfuscation - Extra protection layer for sensitive strings (API keys, tokens)
- 🚀 Zero Runtime Overhead - Bytecode executes directly in V8
- 📦 Works with Node.js & Electron - Compatible with both runtimes
- 🛠️ Production Only - Automatically disabled in development for faster builds
# npm
npm install vite-plugin-v8-bytecode --save-dev
# yarn
yarn add vite-plugin-v8-bytecode --dev
# pnpm
pnpm add vite-plugin-v8-bytecode -DAdd the plugin to your vite.config.ts:
import { defineConfig } from "vite";
import { bytecodePlugin } from "vite-plugin-v8-bytecode";
export default defineConfig({
plugins: [bytecodePlugin()],
build: {
rollupOptions: {
output: {
format: "cjs", // Required: bytecode only works with CommonJS
},
},
},
});Compile only specific chunks:
bytecodePlugin({
chunkAlias: ["index", "main"], // Only compile these chunks
});Obfuscate sensitive strings for additional security:
bytecodePlugin({
protectedStrings: [
"YOUR_API_KEY",
"SECRET_TOKEN",
"mongodb://connection-string",
],
});Strings in protectedStrings will be converted to String.fromCharCode() calls before bytecode compilation, making them harder to extract even from bytecode.
By default, original .js files are removed. To keep them for debugging:
bytecodePlugin({
removeBundleJS: false, // Keep original JS files (prefixed with _)
});import { defineConfig } from "vite";
import { bytecodePlugin } from "vite-plugin-v8-bytecode";
export default defineConfig({
plugins: [
bytecodePlugin({
chunkAlias: ["index"], // Compile only the index chunk
protectedStrings: ["MY_API_KEY"], // Protect sensitive strings
removeBundleJS: true, // Remove original JS after compilation
}),
],
build: {
rollupOptions: {
output: {
format: "cjs",
},
},
},
});Creates a Vite plugin that compiles JavaScript to V8 bytecode.
interface BytecodeOptions {
/**
* Specify which chunks to compile to bytecode.
* If not specified or empty array, all chunks will be compiled.
* @default []
*/
chunkAlias?: string | string[];
/**
* Whether to remove the original .js files after compilation.
* If false, original files are kept with an underscore prefix.
* @default true
*/
removeBundleJS?: boolean;
/**
* Array of strings to protect by obfuscating them with String.fromCharCode.
* Useful for sensitive strings like API keys or tokens.
* @default []
*/
protectedStrings?: string[];
}- Build Process: During Vite's build process, the plugin intercepts your JavaScript output
- String Protection (optional): Transforms protected strings into
String.fromCharCode()calls using Babel - Bytecode Compilation: Compiles the JavaScript to V8 bytecode using Node.js's
vm.ScriptAPI - Loader Injection: Injects a bytecode loader that registers
.jscfile handlers - Output: Generates
.jsc(JavaScript Compiled) files instead of or alongside.jsfiles
After building, you'll see:
dist/
├── index.js # Entry point that loads bytecode
├── index.jsc # Compiled bytecode
├── bytecode-loader.cjs # Bytecode loader runtime
└── _index.js # Original JS (if removeBundleJS: false)
The entry point (index.js) contains minimal code:
"use strict";
require("./bytecode-loader.cjs");
require("./index.jsc");The plugin automatically injects a bytecode loader (bytecode-loader.cjs) that:
- Registers handlers for
.jscand.cjscfile extensions - Sets proper V8 flags (
--no-lazy,--no-flush-bytecode) - Validates and loads bytecode into the V8 engine
- Handles module exports and requires correctly
- CommonJS Only: The plugin only supports CommonJS output format. ES modules are not supported for bytecode compilation.
- Production Only: Automatically disabled in development mode (when
NODE_ENV !== 'production') - Not for Renderer: Cannot be used with Vite's renderer configuration in Electron apps
- V8 Version Compatibility: Bytecode is V8 version-specific. Bytecode compiled with Node.js 22 may not work with older versions.
While bytecode compilation makes reverse engineering significantly harder, it's not a silver bullet:
- Not Encryption: Bytecode can still be analyzed with specialized tools
- V8 Internals: Anyone with deep V8 knowledge could potentially reverse engineer
- Additional Layers: Combine with other security measures (obfuscation, minification, server-side logic)
- String Protection: Use
protectedStringsfor an extra layer on sensitive data
This plugin is inspired by:
- bytenode - The original bytecode compiler for Node.js
- electron-vite bytecode plugin - Electron-specific implementation
- v8-compile-cache - V8 bytecode caching approach
MIT