shieldmycode-vite-plugin
v0.1.0
Published
Vite / Rollup plugin for Shield (shieldmycode.com) — protect your bundle on every vite build.
Maintainers
Readme
shieldmycode-vite-plugin
Drop-in Shield protection for Vite (and Rollup).
Every vite build ships an obfuscated bundle without any manual upload.
Install
npm install --save-dev shieldmycode-vite-pluginRequires Vite 4+ and Node 18+. Rollup users can use the same plugin directly.
Authenticate
Create an API key at shield.shieldmycode.com/dashboard/api-keys (Business plan and up):
export SHIELD_API_KEY=shield_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQuick start
// vite.config.js
import { defineConfig } from 'vite';
import shield from 'shieldmycode-vite-plugin';
export default defineConfig({
plugins: [
shield({
apiKey: process.env.SHIELD_API_KEY,
options: {
level: 'hard',
antiLlm: true,
domainLock: 'mycompany.com'
}
})
]
});That's it. Run vite build and Vite will:
- Resolve, transform, and bundle as usual.
- Run its built-in minifier (esbuild or terser).
- Hand each
.js/.htmloutput to Shield. - Write the protected files to
dist/.
The plugin only runs during vite build (apply: 'build'). It never
fires in vite dev, so HMR stays instant.
TypeScript
The plugin ships its own types:
import shield, { ShieldPluginOptions } from 'shieldmycode-vite-plugin';With React / Vue / Svelte / Astro
Add Shield after your framework plugin so it sees the framework's finished chunks rather than its source-level intermediate transforms:
import react from '@vitejs/plugin-react';
import shield from 'shieldmycode-vite-plugin';
export default defineConfig({
plugins: [
react(),
shield({ apiKey: process.env.SHIELD_API_KEY })
]
});(The plugin internally sets enforce: 'post', so even without ordering
care it will end up at the end of the pipeline. The explicit ordering
above is just clearer.)
Configuration
shield({
// Auth
apiKey?: string; // falls back to $SHIELD_API_KEY
endpoint?: string; // default https://shield.shieldmycode.com
// Engine options (same shape as the dashboard / API)
options?: {
level?: 'soft' | 'medium' | 'hard'; // default 'hard'
antiLlm?: boolean; // default true
encodeStrings?: boolean;
obfuscateNumbers?: boolean;
mangleLocals?: boolean;
integrity?: boolean;
debuggerTrap?: boolean;
devToolsCheck?: boolean;
headlessCheck?: boolean;
deadCode?: boolean;
stealth?: boolean;
noscriptFallback?: boolean;
domainLock?: string;
expiresAt?: string;
geoAllow?: string;
browserBlocklist?: string;
osBlocklist?: string;
ipBlocklist?: string;
telemetryUrl?: string;
heartbeatMs?: number;
};
// Filtering
include?: RegExp | ((name: string) => boolean); // default /\.(m?js|cjs|html?)$/
exclude?: RegExp | ((name: string) => boolean); // default /\.map$/
// Behavior
concurrency?: number; // default 5, max 20
verbose?: boolean; // default true
silence?: boolean; // skip Shield entirely
continueOnError?: boolean; // default true
});Skip on preview / SSR builds
If you want to protect only the client bundle and skip the SSR bundle,
gate the plugin on command / ssrBuild:
export default defineConfig(({ command, isSsrBuild }) => ({
plugins: [
shield({
apiKey: process.env.SHIELD_API_KEY,
silence: command !== 'build' || isSsrBuild
})
]
}));Each chunk = one obfuscation against your quota
The plugin makes one /api/v1/obfuscate call per output chunk. A typical
React+Vite SPA emits ~5–20 chunks; an Astro site emits more (one per
island). Plan for that:
| Plan | Quota | Typical builds that fit | |---|---|---| | Pro | 1,000/mo | ~50 production builds with 20 chunks each | | Business | 10,000/mo | ~500 production builds with 20 chunks each | | Enterprise | Custom | Unbounded |
License
MIT. The Shield engine itself runs server-side at shieldmycode.com.
Issues, feedback: https://shieldmycode.com/support
