UXP Debugger – VS Code ExtensionAttach the VS Code debugger to Adobe UXP plugins (Photoshop, InDesign, XD, …) with full source-map support. Requirements
Setup1. Install the extensionInstall the
2. Patch the UXP Developer Tools (one-time)The extension discovers running plugin sessions via a
The patch is idempotent — safe to run multiple times. A After patching, restart the UXP Developer Tools application. TroubleshootingIf something goes wrong with UDT delete Alternative Method. Load the plugin via UDT CLI (for experts)Show detailsUse the Run in first terminal
And in second terminal
Run this from your plugin directory (where This option is not very ergonomic. Has several disadvantages and I recommend it only for experts if there are special requirements. Attaching the DebuggerOption A — Command Palette
The extension remembers up to 20 recently used targets, sorted by last use. Entries whose Option B —
|
| Symptom | Cause | Fix |
|---|---|---|
| "No running UXP targets found" | Plugin not loaded, or wrong manifest.json |
Start UDT, load plugin and make sure the host app is open |
| "Connected to the relay but no response from the plugin" — session disconnects after 8 s | Plugin load succeeded but the UXP runtime never sent a ready signal | Unload the plugin and load again via "Load button" in UDT and try again |
| "manifest.json not found" | Path in launch.json is wrong |
Check the manifestPath value; make sure ${workspaceFolder} resolves to the right folder |
| "A UXP debug session is already active" | Tried to attach while already debugging | Click Detach and reconnect to replace the existing session, or cancel |
| "Failed to start the JS debug session" | Internal pwa-node attach error |
Check the UXP Debugger output channel for details |
| "Permission denied" during patch | app.asar owned by another user |
Follow patching instructions above |
.uxprc not created after plugin load |
app.asar not yet patched |
Follow patching instructions above |
How It Works
The extension does not implement a custom debug adapter. Instead it:
- Discovers running targets via two methods:
.uxprc— reads the UDT session file and connects viaws://127.0.0.1:14001/socket/cdt/<sessionId>.debug.json— reads a pinned port and probeshttp://127.0.0.1:<port>/json/list
- Starts a lightweight CDP proxy between VS Code and the UXP endpoint, translating protocol quirks (source-map root rewriting,
Runtime.evaluatecontext patching,NodeWorker.enablesuppression). - Delegates to the built-in VS Code JS debugger (
pwa-nodeattach mode) which handles all actual protocol work.
Project Structure
src/
extension.ts Entry point; registers commands and debug provider
debugConfigProvider.ts Handles launch.json "uxp" type; substitutes variables
cdpProxy.ts CDP proxy (WebSocket + HTTP); message rewriting
uiHelpers.ts pickTarget() QuickPick
constants.ts / types.d.ts Shared constants and types
patch-asar.ts ASAR patch logic (idempotent, streaming)
commands/
attach.ts Main attach flow + target history
patchAsar.ts Patch command UI
setManifestPath.ts Manifest path picker
endpointDetection/
discoverViaDebugJson.ts .debug.json → /json/list probe
discoverViaUxpRc.ts .uxprc → UDT relay WebSocket
License
MIT