Where Are Custom Renderer Scripts Loaded From in Wand-Enhancer? A Technical Deep Dive
Wand-Enhancer loads custom renderer scripts from the renderer-scripts directory inside the unpacked remote-panel package, which is populated from both a local folder next to the executable and user-specified paths in PatchConfig.CustomScriptScripts.
Wand-Enhancer is an Electron-based enhancement tool that allows users to inject custom JavaScript into renderer processes. Understanding exactly where these custom renderer scripts originate and how they reach the final application requires examining both the C# patching layer and the TypeScript bridge runtime.
The Two-Stage Loading Process
Custom script loading happens in distinct phases: first during the application patching stage, then at runtime when Electron web contents are created.
Stage 1: Patching and File Injection (Enhancer.cs)
During the patching phase, the InjectRemotePanelFiles method in WandEnhancer/Core/Enhancer.cs (lines 344-418) prepares the script directory. According to the Wand-Enhancer source code, scripts are gathered from two sources:
- Configuration-based paths: Absolute file paths specified in
PatchConfig.CustomScriptPathsare copied into the target directory - Local discovery: If a folder named
renderer-scriptsexists adjacent to the Wand-Enhancer executable, all.jsfiles within are automatically collected
Both sources are consolidated into:
<unpacked-path>/remote-panel/renderer-scripts/
Here, <unpacked-path> represents the temporary extraction location of app.asar.
Stage 2: Runtime Injection (renderer-scripts.ts)
At runtime, the Electron bridge initializes script injection through installRendererScripts in web-panel/bridge/src/wand/renderer-scripts.ts. This function calls loadRendererScripts(panelRoot, options.scriptsRoot), which defaults to:
panelRoot + "/renderer-scripts"
This path corresponds to the directory populated during Stage 1. The loader reads all .js files, wraps them for execution, and prepares them for injection into renderer processes via contents.executeJavaScript.
Primary Source Locations for Custom Scripts
Wand-Enhancer recognizes custom renderer scripts from two specific locations:
- User-specified paths: Any absolute paths provided in the
CustomScriptPathsproperty of the patch configuration - Local
renderer-scriptsfolder: A directory named exactlyrenderer-scriptsplaced in the same folder as the Wand-Enhancer executable
Files from both locations are merged into the final injection directory during the patching process.
Code Implementation Details
Configuring Custom Script Paths (C#)
To specify scripts via the patch configuration:
// PatchConfig.cs – property definition
public List<string> CustomScriptPaths { get; set; } = new List<string>();
// Usage example – selecting scripts in the UI
var selected = new[] { @"C:\my-scripts\my-renderer.js" };
_config.CustomScriptPaths = selected.ToList();
Local Directory Structure
For automatic discovery without configuration:
WandEnhancer.exe
└─ renderer-scripts
└─ my-local-script.js
Runtime Loading Logic (TypeScript)
The actual file reading occurs in web-panel/bridge/src/wand/renderer-scripts.ts:
function loadRendererScripts(panelRoot, scriptsRoot) {
const root = scriptsRoot || path.join(panelRoot, RENDERER_SCRIPTS_DIR);
if (!fs.existsSync(root)) return [];
return fs.readdirSync(root)
.filter(name => name.endsWith('.js'))
.map(name => ({
name,
source: fs.readFileSync(path.join(root, name), 'utf8')
}));
}
How Scripts Are Injected Into Renderers
Once loaded, scripts are injected into every new renderer process through Electron's web-contents-created event. As implemented in the bridge source code:
electron.app.on('web-contents-created', (_e, contents) => {
const inject = () => {
if (!contents || contents.isDestroyed()) return;
contents.executeJavaScript(
buildRendererBootstrap(runtime.remoteUrl, scripts), true
).catch(err => writeInstallLog('warn', 'Failed to inject renderer scripts.', err));
};
contents.on('dom-ready', inject);
contents.on('did-finish-load', inject);
});
The installWandRuntime function in web-panel/bridge/src/wand/runtime.ts (lines 70-78) orchestrates this setup by calling installRendererScripts during bridge initialization.
Summary
- Custom renderer scripts are ultimately loaded from
<unpacked-path>/remote-panel/renderer-scripts/at runtime - The patching phase copies scripts from both
PatchConfig.CustomScriptPathsand a localrenderer-scriptsfolder next to the executable - File reading and injection are handled by
loadRendererScriptsandinstallRendererScriptsin the TypeScript bridge - Scripts are wrapped and executed via
contents.executeJavaScriptin every new renderer process
Frequently Asked Questions
Where do I place local custom scripts for automatic loading?
Place your .js files in a folder named exactly renderer-scripts in the same directory as the Wand-Enhancer executable. The InjectRemotePanelFiles method automatically discovers and copies these files during the patching phase without requiring configuration changes.
How do I specify custom scripts via configuration?
Add absolute file paths to the CustomScriptPaths list in your PatchConfig object. In C#, this is the public List<string> CustomScriptPaths { get; set; } property. These paths are processed during the InjectRemotePanelFiles call and copied alongside any local scripts.
What file extension must renderer scripts use?
All custom renderer scripts must use the .js extension. The loadRendererScripts function explicitly filters for files ending with .js using name.endsWith('.js'), ignoring all other file types in the renderer-scripts directory.
Are scripts injected into all renderer processes?
Yes. The injection mechanism hooks into Electron's web-contents-created event, ensuring that contents.executeJavaScript fires for every new web content instance. This includes both initial renders and any dynamically created renderer processes during the application lifecycle.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →