# Where Are Custom Renderer Scripts Loaded From in Wand-Enhancer? A Technical Deep Dive

> Discover where Wand-Enhancer loads custom renderer scripts from. This technical deep dive explains script loading paths including the renderer-scripts directory and PatchConfig.CustomScriptScripts.

- Repository: [k1tbyte/Wand-Enhancer](https://github.com/k1tbyte/Wand-Enhancer)
- Tags: deep-dive
- Published: 2026-09-01

---

**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`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/WandEnhancer/Core/Enhancer.cs) (lines 344-418) prepares the script directory. According to the Wand-Enhancer source code, scripts are gathered from two sources:

1. **Configuration-based paths**: Absolute file paths specified in `PatchConfig.CustomScriptPaths` are copied into the target directory
2. **Local discovery**: If a folder named `renderer-scripts` exists adjacent to the Wand-Enhancer executable, all `.js` files 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`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/wand/renderer-scripts.ts). This function calls `loadRendererScripts(panelRoot, options.scriptsRoot)`, which defaults to:

```typescript
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 `CustomScriptPaths` property of the patch configuration
- **Local `renderer-scripts` folder**: A directory named exactly `renderer-scripts` placed 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:

```csharp
// 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`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/wand/renderer-scripts.ts):

```typescript
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:

```typescript
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`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/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.CustomScriptPaths` and a local `renderer-scripts` folder next to the executable
- File reading and injection are handled by `loadRendererScripts` and `installRendererScripts` in the TypeScript bridge
- Scripts are wrapped and executed via `contents.executeJavaScript` in 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.