Free, open-source Photoshop plugin for ComfyUI. Generate, inpaint, upscale, and split a flat image back into layers — all on your own GPU. Results arrive as real, editable Photoshop layers. No cloud, no subscription, no account.
14
stars
410
commits
TypeScript
primary language
Sep 3, 2026
updated
OpenLayer is an open-source Photoshop ComfyUI plugin for local AI layers.
OpenLayer is an open-source Adobe Photoshop UXP plugin that connects Photoshop to a locally running ComfyUI server for text-to-image, image-to-image, sketch-to-image, preview, and importing AI results into the active Photoshop document as editable layers.
v0.19.0-alpha is the current public alpha checkpoint. It is intended for testing the core local workflows in Photoshop UXP, not for production work yet.
New in v0.19.0-alpha:
Multi-Reference Composition (experimental). Give the panel a list of captured Photoshop layers instead of one, and it builds a single image out of all of them — a background, a person, an object, however many you add. Add Active Layer or Add Canvas repeatedly to grow the list; each entry gets Up, Down, and Remove. Order is not cosmetic: the first reference sets the output canvas size, and moving an object earlier in the list is the fix if it comes back duplicated or distorted. Built on FLUX.2 Klein's own ReferenceLatent conditioning, chained once per reference onto both the positive and negative branches — every node is core ComfyUI, so it shares the Klein 4B stack the other Klein presets already need and downloads nothing extra.
Answered with 48 live generations before any of the screen was built, recorded in docs/multi-reference-gate-findings.md: identity held with no measured ceiling on reference count; prompt phrasing barely matters, because the model matches references to the prompt by what they are rather than by position; masking or cutting out a reference's background makes no difference, because Klein already isolates the subject on its own. The one finding that shapes what this tool can honestly claim: clothing, props, setting, and lighting carry across from a reference; a specific person's face does not. A face from a real photograph comes back as a plausible stranger, not the person photographed — even from a clean, frontal studio portrait. So this composes a scene; it does not place someone recognisable into one, and nothing in the panel or this README claims otherwise.
The AI assistant can compose too. multi_reference joins the seven tools already reachable over MCP, with the same "requires layers captured in the panel first, only the parameters you pass are changed" boundary every other bridged tool has, and the likeness limit stated directly in the tool description an agent reads before running it.
Also new in v0.18.0-alpha:
Also new in v0.16.0-alpha:
inpaint-flux2-klein. The first inpaint preset that is not a Flux Fill model. It reuses the Klein 4B stack you already have for Text to Image — no extra model download — and repaints a selection at four steps, using the same comfyui-inpaint-cropandstitch node pack as the crop-and-stitch Flux Fill preset. Experimental; strongest at adding to a small selection or replacing a large region.214748.36. A UXP number input cannot hold a value that large, so any seed wider than six digits — including every seed loaded from History — came back mangled and then failed the run with "Seed must be a whole number". The seed fields are plain numeric text fields now and hold the full range.Also new in v0.15.0-alpha:
An AI assistant can drive OpenLayer's tools. Ask Claude — or Codex, or anything else that speaks the Model Context Protocol — to generate an image, upscale a layer or caption a selection, and it works the panel's own buttons in your open document. All seven tools are reachable. It runs entirely on your machine and is off until you turn it on, in Setup → Agent Bridge.
The bridge contains no Photoshop code: it can only run a tool the panel already has and read back what the panel said happened. An agent-driven generation and a clicked one are the same code path, so the same safety rules apply to both.
The bridge is not in the download. A Photoshop plugin package cannot install or start a Node program, so it lives in the repository: clone or download it, then cd bridge && npm install && npm run hub. bridge/README.md covers the setup and the one line that registers it with your AI client.
Ask the Agent for a Prompt, under the Text to Image prompt box — the panel asking the assistant for once. Needs an AI client that supports MCP sampling; see the boundaries below.
Version drift is a test failure now. v0.14.0-alpha displayed v0.13.0 in the panel footer, in both diagnostics lines, and in the version recorded against every session-history entry, because the number lives in eight places and one of them moved file. npm test now names whichever file disagrees.
FLUX.2 Klein 4B, text-to-image, image-to-image, and instruction editing. Three new presets — txt2img-flux2-klein, img2img-flux2-klein, and edit-flux2-klein — run Black Forest Labs' distilled Klein 4B at 4 steps, CFG 1. A 1024x1024 generation completed in 11.6 seconds on a 4070 Ti. The download is 4.07 GB (flux-2-klein-4b-fp8.safetensors) plus a 336 MB VAE; the 8 GB qwen_3_4b.safetensors text encoder is the same file the Z_image_Turbo presets already use. Every node is core ComfyUI — no new custom-node packages — and Klein is Apache-2.0 and ungated.
Instruction editing is not image-to-image. edit-flux2-klein tells the model what to change ("make the jacket red", "turn the sky to dusk") instead of describing the whole picture. It starts from an empty latent at denoise 1 and supplies your layer as conditioning through ReferenceLatent, so the model follows the instruction while seeing what the scene is. Denoise is hidden because it is fixed at 1 — that is the technique, not a default.
Context-aware Inpaint: inpaint-flux-fill-cropstitch. A second Flux Fill preset that crops to your mask plus context, samples that at 1024x1024, and stitches the patch back with a blended seam, using lquesada's ComfyUI-Inpaint-CropAndStitch. A small mask on a large document no longer samples a few hundred pixels, and a large one no longer samples several thousand. It ships alongside inpaint-flux-fill-basic rather than replacing it, because the custom-node dependency is optional.
Image to Image results land where they came from. The imported layer could arrive offset from the layer it was generated from. Capture now records where in the document it read from, and the import moves the layer there explicitly.
Also new in v0.14.0-alpha:
Also new in v0.13.0-alpha:
.gguf file and pressing Generate failed outright. Both were reported by a tester on the release.Also new in v0.11.0-alpha:
txt2img-krea2-turbo and inpaint-flux-fill-basic, and the status badge is now one squared label used on both screens.Also new in v0.10.0-alpha:
unzip unpacks as a flat directory with no assets/ folder, so the panel could not render. If an earlier release gave you a blank panel on macOS, this was why — use this one.Also new in v0.9.0-alpha:
Also new in the 0.8 series:
img2img-z-image-turbo's editable source workflow is correct. It previously held the vendor's text-to-image demo graph, so opening it to learn the workflow showed a graph that cannot do image to image. Generation was never affected.TextEncoder and TextDecoder that Node provides but Photoshop UXP does not.App.ts has been reduced from 6,112 lines at v0.7.0 to 4,922 — down from a peak of 8,149 — by extracting error messages, status handling, and DOM event wiring. A separate CSS audit measures consolidation work without changing styles in this release.Included in this alpha:
Compact Adobe Dark as the default and Classic v0.4 as an optional legacy visual styletxt2img-basic presetimg2img-basic presetsketch2img-linecn-basic LINECN preset/system_statsImagePadForOutpaintImport Automatically toggle for sending generated results straight back into Photoshopupscale-basic workflow using LoadImage, UpscaleModelLoader, ImageUpscaleWithModel, and SaveImageinpaint-basic workflow with source image and mask upload to ComfyUI
The v0.6 dashboard is denser, clearer about tool availability, and designed for narrow Photoshop panels. The accepted UXP layout adds sticky tool headers, determinate generation progress, larger prompt editors, and consistent spacing without changing the local workflow engine.


The earlier card-based dashboard established OpenLayer's honest available/experimental/coming-soon model. v0.6 keeps that information architecture while using less space and fitting Photoshop more naturally.
v0.19.0-alpha tester focus:
v0.19.0. It read the wrong version for the whole of v0.14.0-alpha, so this is worth a glance before anything else.Also worth rechecking from v0.18.0-alpha:
214748.36. Then load an entry from session History and generate from it — its seed must load and run, not fail with "Seed must be a whole number". That failure hit every History load before this release.inpaint-flux2-klein, and generate. Confirm the repaint blends into the surrounding image. It is strongest at adding something to a small selection — try that, and try replacing a larger region. It needs the comfyui-inpaint-cropandstitch node pack; if it is missing, Workflow Health should name it.Also worth rechecking from v0.15.0-alpha:
txt2img-flux2-klein. It should complete in under 15 seconds on a 4070 Ti at 1024x1024. Confirm the result is coherent and the prompt was followed.img2img-flux2-klein, capture a layer, and generate. The result should follow your layer. Then switch to edit-flux2-klein, enter a change instruction ("make the sky orange"), and generate again — the edit should apply the instruction while keeping the rest of the scene.inpaint-flux-fill-cropstitch. Generate and confirm the inpainted area blends into the surrounding image. Compare with inpaint-flux-fill-basic at the same selection — crop-and-stitch should produce sharper detail on small selections in large documents.cd bridge && npm install && npm run hub), then turn the toggle on. It should connect without any AI client running at all — the hub is independent of them.bridge/README.md has the line), then ask it to call get_panel_state. It should report connected: true and list all seven tools.Also worth rechecking from v0.14.0-alpha:
z_image_turbo_bf16.safetensors.Also worth rechecking from v0.13.0-alpha:
txt2img-krea2-turbo, and confirm a LoRA (optional) row appears with None selected and no strength field. Generate once with None — it must succeed — then pick a LoRA and generate again at the same seed. The two images must differ.(name suggests another model), and generating should succeed with a visibly unchanged image — that is the silent failure the warning describes, not a bug.Also worth rechecking from v0.11.0-alpha:
Open Setup from Home before starting ComfyUI. Confirm every model and node package is still listed with its folder, size and links, that the three tallies show a dash rather than 0, and that nothing claims you are set up.
Start ComfyUI, click Check Again, and confirm the list splits into what you have and what you are missing, with the installed rows collapsed. The remaining download figure should count each file once even though several presets share it — and should say "Nothing" if you have everything.
Move one model into the wrong folder — a checkpoint into models/diffusion_models/, say — check again, and confirm its row says you already have the file, names the folder it is in, and does not add its size to the remaining download.
Use the filter chips to narrow the list to one tool, and confirm the tallies and the download total keep describing everything rather than only the filtered slice.
Read "What will run well" at the bottom of Setup. Confirm the VRAM figure matches your card, that the order runs best-first, and that the Florence-2 preset is not claimed to be the most comfortable one on the list.
Look at the status badges on both Setup and Check Workflow Health: they should be the same squared uppercase label on both screens, with no text cut off by an ellipsis. The longest ones are NEEDS WORKFLOW JSON and MISSING COMFYUI NODE.
Confirm the filter chips read as flat outlined pills of uniform height — not gold switches, not stretched ovals.
Confirm Workflow Health names presets the way an artist would ("Krea-2 Turbo", "Standard checkpoint") rather than by their internal ids. Also worth rechecking from v0.10.0-alpha:
Unzip the release package and confirm it expands into folders, with an assets/ directory beside index.html — not a flat pile of files with backslashes in their names. On macOS this is the single most useful thing to report.
Put a model in the wrong folder on purpose — move a checkpoint into models/diffusion_models/, say — then run Check Workflow Health and confirm the report names the folder it actually found it in and the folder the workflow wants.
Open Live Painting. Confirm Start and Stop Live Session have a gap between them and are the same height, and that the two explanatory hints read as full paragraphs rather than ending in an ellipsis.
Set a Live Painting negative prompt, start a session, and paint. Then run one session with the field left blank and confirm it behaves as it did before.
Also worth rechecking from v0.9.0-alpha:
input folder under the name the status line reports.npm run setup-pack and confirm it reports no source/API mismatches at all.Known v0.19.0-alpha boundaries:
.ccx/.zip download. A Photoshop plugin package cannot install or start a Node program, so it lives in the repository — see bridge/README.md. It is off by default in the panel either way. "Ask the Agent for a Prompt" additionally depends on your AI client supporting MCP sampling, which is optional in the protocol; a client that does not offer it gets a clear, instant refusal rather than the button working.sketch2img-zimage-fun-controlnet (lite, 2.0 GB, faster) and sketch2img-zimage-fun-controlnet-full (6.7 GB, slower). Neither Z_image_Turbo preset replaced the other, because they measured as complementary rather than ranked: the full weights render shaded or densely drawn work more photographically, while the lite weights hold bold sparse line art that the full weights flatten into a filled shape at any control strength. Their default control strengths differ for the same reason -- 1.0 for lite, 0.6 for full, which patches five times as many layer blocks. The SD 1.x presets are tested with epicrealism_naturalSinRC1VAE.safetensors and their respective control_v11p_sd15_* ControlNets; the Z_image_Turbo presets with z_image_turbo_bf16.safetensors and, respectively, Z-Image-Turbo-Fun-Controlnet-Union-2.1-lite-2602-8steps.safetensors and Z-Image-Turbo-Fun-Controlnet-Union-2.1.safetensors.inpaint-basic workflow when ComfyUI has the required nodes.inpaint-basic (SD 1.x), inpaint-flux-fill-basic (Flux Fill), and inpaint-flux-fill-cropstitch (Flux Fill with crop-and-stitch). The crop-and-stitch preset requires lquesada's comfyui-inpaint-cropandstitch custom-node package; without it the preset is unavailable and the original Flux Fill preset still works.img2img-basic is the default SD 1.x/SDXL preset. SD3, SD3.5, and Flux checkpoints remain visible but are marked experimental because they usually need dedicated future workflow presets.UNETLoader, CLIPLoader, and VAELoader instead of the checkpoint loader.txt2img-flux1-dev-fp8 is an experimental checkpoint-style Flux Text to Image preset for flux1-dev-fp8.safetensors.txt2img-flux2-klein, img2img-flux2-klein, edit-flux2-klein) use flux-2-klein-4b-fp8.safetensors (4.07 GB), qwen_3_4b.safetensors (8 GB, shared with Z_image_Turbo), and ae.safetensors (336 MB). Klein is Apache-2.0 and ungated. edit-flux2-klein is structurally different from image-to-image: it uses ReferenceLatent conditioning at denoise 1, not a starting latent at partial denoise.txt2img-flux1-dev-fp8 already covers Flux Text to Image. Every preset the panel lists is now one you can actually run.comfyui-florence2 and Florence-2-base-PromptGen-v2.0. The comfyui-custom-scripts pack is no longer needed.outpaint-flux-fill-basic with flux1-fill-dev.safetensors, clip_l.safetensors, t5xxl_fp16.safetensors or the accepted T5 fp8 fallback, and ae.safetensors.UpscaleModelLoader and ImageUpscaleWithModel nodes plus an installed upscale model such as 4x-UltraSharp.pth or RealESRGAN_x4plus.pth.input folder. It does not build or run a workflow for you — you reference the uploaded file from a workflow yourself.--preview-method auto, and the preview panel may flicker between steps until a future UI polish pass.The static landing page is in:
docs/index.html
For GitHub Pages, publish from the docs folder on the main branch.
OpenLayer includes a beginner-friendly guide for local model choices, VRAM tiers, and why diffusion model stacks such as Z_image_Turbo do not appear in the checkpoint selector:
docs/model-guide.md
The current experimental inpainting status and next debugging checklist are documented in:
docs/inpainting.md
Key technical decisions for the project are tracked in:
docs/technical-decisions.md
Working foundation:
txt2img-basic workflow generationtxt2img-z-image-turbo workflow generationimg2img-basic workflow generation foundationimg2img-z-image-turbo workflow generation foundationsketch2img-linecn-basic Sketch to Image generation foundationprompt-from-layer-florence2 text workflow with Task and Num beams controlsupscale-basic pixel/model upscale workflowinpaint-basic/prompt submission/history/{prompt_id} polling/view image retrievalFuture placeholders are included for regional import alignment and selection preservation.
To use the plugin:
.ccx by double-clickhttp://127.0.0.1:8190To build from source instead:
The UXP Developer Tool is no longer needed just to run OpenLayer — see One-click install.
OpenLayer is local-first. The Photoshop UXP manifest currently requests filesystem and network access because:
OpenLayer does not send diagnostics, images, prompts, or model information anywhere automatically.
npm install
Build the plugin:
npm run build
Load the generated dist folder in Adobe UXP Developer Tool.
Run local checks:
npm run typecheck
npm test
These checks do not require Photoshop or ComfyUI.
For fast UI iteration outside Photoshop, you can run:
npm run dev
The dev server is useful for panel layout work, but the Photoshop-specific APIs only run inside Photoshop through UXP.
npm run package
This creates a zip package from dist in the packages folder. For the current alpha, the expected package name is:
packages/openlayer-v0.19.0-alpha.zip
npm run package also writes packages/openlayer-v0.19.0-alpha.ccx beside it, from the same files.
Every release attaches a .ccx. Double-click it and Creative Cloud installs the panel — no UXP
Developer Tool, no developer mode. Photoshop then lists it under Plugins > OpenLayer like any
other installed plugin.
This was an open question across three releases and is now answered. What was checked, on Windows 11
with Photoshop 2025 (26.1.0): the package installs, Adobe's Unified Plugin Installer Agent reports it
as Enabled OpenLayer 0.13.0 under Photoshop 2025 64, it unpacks to
%APPDATA%\Adobe\UXP\Plugins\External\com.openlayer.photoshop_<version>\ with no debug.json — a
packaged install rather than a developer load — and the panel opens and works in Photoshop.
Two things worth knowing before you try it:
.ccx on the same drive as Photoshop and Creative Cloud. The installer only searches
the drive the file is sitting on, so a .ccx on D: with Photoshop on C: fails.If double-clicking does nothing at all — a known Windows 11 quirk where Creative Cloud opens with no progress and no error — install it directly instead:
"C:\Program Files\Common Files\Adobe\Adobe Desktop Common\RemoteComponents\UPI\UnifiedPluginInstallerAgent\UnifiedPluginInstallerAgent.exe" /install "path\to\openlayer-vX.Y.Z-alpha.ccx"
UnifiedPluginInstallerAgent.exe /list all shows what is installed, and /remove OpenLayer uninstalls
it. Note that /list needs all or the exact product display name ("Photoshop 2025 64"); a partial
name like "Photoshop" prints nothing and no error, which looks exactly like "nothing installed".
Still unverified: macOS, and any Photoshop other than 2025. Reports either way are welcome.
The UXP Developer Tool route below still works and is what you want when building from source.
Add Plugin.dist/manifest.json after running npm run build.Load.Start ComfyUI locally using your normal ComfyUI launch command. Confirm the server is reachable:
curl http://127.0.0.1:8190/system_stats
In OpenLayer, keep the default server URL or enter your own:
http://127.0.0.1:8190
OpenLayer uses port 8190 by default so it does not interfere with another tool that may already be
using ComfyUI on port 8188.
You do not have to move your server to 8190. If ComfyUI is already running somewhere else — 8188
or anywhere — open Settings and click Find ComfyUI Active Port. OpenLayer scans for the running
server, connects to it, and reports Ready. Use your normal launch command and leave it where it is.
Starting a dedicated instance on 8190 is the other option, not the required one:
python main.py --listen 127.0.0.1 --port 8190 --preview-method auto
--preview-method auto is optional but recommended: it makes ComfyUI stream live KSampler step previews into the OpenLayer result preview while generating.
Click Check ComfyUI before generating.
Find ComfyUI Active Port or Check ComfyUI to load the available checkpoints.Detect GPU & Recommend Models to see hardware-aware model suggestions.txt2img-basic.Generate.Import Result as New Layer, or enable Import Result Automatically before generating.The imported layer is named like:
OpenLayer_Generated_YYYYMMDD_HHMM
Image to Image.Capture Active Layer, or click Capture Canvas to use the visible document.img2img-basic.Generate Image to Image.Import to Layers.The imported layer is named like:
OpenLayer_Img2Img_YYYYMMDD_HHMM
epicrealism_naturalSinRC1VAE.safetensors
control_v11p_sd15_lineart_fp16.safetensors
Sketch to Image.Capture Active Layer, or click Capture Canvas.sketch2img-linecn-basic.epicrealism_naturalSinRC1VAE.safetensors.Generate Sketch to Image.Import to Layers.The imported layer is named like:
OpenLayer_Sketch_YYYYMMDD_HHMM
This alpha includes the first experimental SD 1.x mask-based inpainting path.
Inpaint.Capture Selection.Generate Inpaint.Import to Layers.The first inpaint-basic preset is experimental and intended for SD 1.x inpaint checkpoints first. inpaint-flux-fill-basic is also available as an experimental Flux Fill path when your local ComfyUI exposes the required Flux Fill model stack. inpaint-flux-fill-cropstitch adds crop-and-stitch sampling at 1024 on top of the same Flux Fill stack, and needs lquesada's comfyui-inpaint-cropandstitch node package.
Inpaint output quality, mask interpretation, and Photoshop alignment are still being tested. Use this path for debugging and feedback rather than production work.
Use this quick pass before reporting a v0.19.0-alpha test result:
http://127.0.0.1:8190.dist/manifest.json in Adobe UXP Developer Tool.Check ComfyUI; confirm checkpoints load.Check Workflow Health; confirm each registered preset shows Ready, Experimental, Missing model, Missing ComfyUI node, Needs workflow JSON, or Setup required, under its artist-facing name.Copy Diagnostics; confirm the report is copied or appears in the read-only diagnostics box.txt2img-basic image and import it as a new layer; confirm the determinate progress bar advances cleanly.txt2img-flux1-dev-fp8 with flux1-dev-fp8.safetensors if available, generate once, and confirm the result preview appears.Cancel Generation; confirm the status changes to Generation cancelled. and the next generation still works.Image to Image, capture either the active layer or canvas, generate with img2img-basic, and click Import to Layers.Import Automatically, generate once, and confirm the result imports as a new Photoshop layer.Upscale, capture either the active layer or canvas, choose 4x-UltraSharp.pth or another listed upscale model, generate, and click Import to Layers.Sketch to Image, capture either the active layer or canvas, generate with sketch2img-linecn-basic, and click Import to Layers.Inpaint, make a Photoshop selection, click Capture Selection, and confirm the selected-region preview and mask preview appear.inpaint-flux-fill-basic if your Flux Fill stack is installed, then click Import to Layers; keep inpaint-basic as experimental/debug-only if it does not match the source.For a step-by-step beginner smoke test, see:
docs/testing-v0.1-alpha.md
The included workflows are realistic starter ComfyUI workflows using common built-in nodes:
src/workflows/api/txt2img-basic.jsonsrc/workflows/api/txt2img-flux1-dev-fp8.jsonsrc/workflows/api/prompt-from-layer-florence2.jsonsrc/workflows/api/img2img-basic.jsonsrc/workflows/api/sketch2img-linecn-basic.jsonsrc/workflows/api/inpaint-basic.jsonsrc/workflows/api/inpaint-flux-fill-basic.jsonYou may need to replace the checkpoint name and node IDs for your own ComfyUI setup.
OpenLayer now keeps workflow files in two folders:
src/workflows/api/ for runnable API workflows submitted to ComfyUIsrc/workflows/source/ for GUI-editable ComfyUI source workflowsSee docs/workflow-files.md, docs/custom-workflows.md, and docs/comfyui-object-info-audit-v0.2.2.md for the workflow file structure, custom workflow mapping requirements, and the local node schema audit used by the workflow compatibility foundation.
The workflow builder injects:
Image to Image and Sketch to Image use Photoshop's UXP Imaging API to capture the active layer or canvas, encode the raw pixels as PNG, then send the source image to ComfyUI using /upload/image. JPEG source capture has been removed from this path so clean edges, masks, transparency, and linework are not degraded by lossy compression.
Inpaint uses the same PNG/lossless Imaging API path, clipped to a padded context around the active Photoshop selection when Photoshop exposes selection bounds. In v0.4.1-alpha, OpenLayer also creates a temporary white-filled selection layer, captures it as a grayscale PNG mask, deletes the temporary layer, and uploads both source and mask to ComfyUI.
The first inpaint-basic preset requires ComfyUI's standard LoadImage, ImageToMask, InpaintModelConditioning, KSampler, VAEDecode, ImageCompositeMasked, and SaveImage nodes. It is currently aimed at SD 1.x inpaint checkpoints.
The experimental inpaint-flux-fill-basic preset requires:
flux1-fill-dev.safetensors through UNETLoader from models/diffusion_modelsclip_l.safetensors through DualCLIPLoader.clip_name1 from models/text_encoderst5xxl_fp16.safetensors through DualCLIPLoader.clip_name2 from models/text_encoderst5xxl_fp8_e4m3fn.safetensors as an accepted T5 fallback when the fp16 file is not installedae.safetensors through VAELoader from models/vaeDifferentialDiffusion, FluxGuidance, ConditioningZeroOut, InpaintModelConditioning, KSampler, VAEDecode, and SaveImageFlux Fill follows the reference-style graph in src/workflows/source/inpaint-flux-fill-basic.workflow.json. That graph expects one LoadImage node whose alpha channel becomes the mask. OpenLayer preserves the Photoshop source PNG and embeds the white repaint mask into the uploaded PNG alpha channel before submission. Inpaint import currently uses aligned context import only. The earlier transparent outside-mask PNG experiment is disabled because Photoshop UXP canvas/blob compositing is not trusted yet. Output quality, mask polarity, and alignment are not confirmed stable yet, and Photoshop-native layer mask import remains planned future work.
For debugging, OpenLayer records source, mask, raw result dimensions, import mode, and temporary local debug copies of the source PNG, mask PNG, and raw generated PNG after an Inpaint run.
img2img-basic is intended for SD 1.x and SDXL-style checkpoints. SD3, SD3.5, and Flux checkpoints are shown in the selector for transparency, but OpenLayer warns before running them because those model families often need different loader, text encoder, and VAE nodes.
Sketch to Image uses the same Photoshop capture and ComfyUI upload path, then runs sketch2img-linecn-basic. This preset requires:
epicrealism_naturalSinRC1VAE.safetensorscontrol_v11p_sd15_lineart_fp16.safetensorsLineartStandardPreprocessorControlNetLoaderControlNetApplyAdvancedThe first LINECN preset is intentionally narrow. It is a working SD 1.x foundation, not a universal sketch workflow for SDXL, SD3, Flux, or Z_image_Turbo.
If you export a different workflow from ComfyUI, update the node IDs in src/comfy/presetRegistry.ts.
Make sure GitHub Pages is configured to publish from:
main / docs
The landing page entry file is docs/index.html.
Run npm run build, then load:
dist/manifest.json
in Adobe UXP Developer Tool. After loading, open Photoshop and use the Plugins menu to open OpenLayer.
Confirm ComfyUI is running on:
http://127.0.0.1:8190
You can test it in a browser or terminal:
curl http://127.0.0.1:8190/system_stats
If another local tool is already using 8188, keep OpenLayer on 8190 and start a separate ComfyUI instance for OpenLayer.
Click Check ComfyUI after ComfyUI is fully started. If it is still empty, confirm your models are installed in ComfyUI and that the server URL in OpenLayer matches the running ComfyUI port.
Check that the selected checkpoint exists in ComfyUI and that the selected workflow node IDs still match the starter workflow. Custom workflows currently require manual mapping in:
src/comfy/presetRegistry.ts
See docs/custom-workflows.md for the current custom workflow process.
Use an SD 1.x or SDXL checkpoint with img2img-basic first. If you select SD3, SD3.5, Flux, or another newer model family, OpenLayer will keep it visible but warn that it is experimental for this preset. Those checkpoints usually need a dedicated workflow preset before they can run reliably.
Open a Photoshop document before importing. OpenLayer imports into the active document and will show an error if no document is open.
.
|-- docs/
|-- scripts/
|-- src/
| |-- comfy/
| |-- photoshop/
| |-- ui/
| |-- utils/
| |-- workflows/
| |-- index.html
| |-- main.ts
| |-- manifest.json
| `-- styles.css
|-- package.json
|-- tsconfig.json
`-- vite.config.ts
MIT
OpenLayer™ — the OpenLayer name and logo may not be used by derivative works without permission.
See also: Privacy Policy and Terms of Service.
410 commits
TypeScript
85.2%
CSS
9.6%
JavaScript
5.2%
Free, open-source Photoshop plugin for ComfyUI. Generate, inpaint, upscale, and split a flat image back into layers — all on your own GPU. Results arrive as real, editable Photoshop layers. No cloud, no subscription, no account.
14
stars
410
commits
TypeScript
primary language
Sep 3, 2026
updated
OpenLayer is an open-source Photoshop ComfyUI plugin for local AI layers.
OpenLayer is an open-source Adobe Photoshop UXP plugin that connects Photoshop to a locally running ComfyUI server for text-to-image, image-to-image, sketch-to-image, preview, and importing AI results into the active Photoshop document as editable layers.
v0.19.0-alpha is the current public alpha checkpoint. It is intended for testing the core local workflows in Photoshop UXP, not for production work yet.
New in v0.19.0-alpha:
Multi-Reference Composition (experimental). Give the panel a list of captured Photoshop layers instead of one, and it builds a single image out of all of them — a background, a person, an object, however many you add. Add Active Layer or Add Canvas repeatedly to grow the list; each entry gets Up, Down, and Remove. Order is not cosmetic: the first reference sets the output canvas size, and moving an object earlier in the list is the fix if it comes back duplicated or distorted. Built on FLUX.2 Klein's own ReferenceLatent conditioning, chained once per reference onto both the positive and negative branches — every node is core ComfyUI, so it shares the Klein 4B stack the other Klein presets already need and downloads nothing extra.
Answered with 48 live generations before any of the screen was built, recorded in docs/multi-reference-gate-findings.md: identity held with no measured ceiling on reference count; prompt phrasing barely matters, because the model matches references to the prompt by what they are rather than by position; masking or cutting out a reference's background makes no difference, because Klein already isolates the subject on its own. The one finding that shapes what this tool can honestly claim: clothing, props, setting, and lighting carry across from a reference; a specific person's face does not. A face from a real photograph comes back as a plausible stranger, not the person photographed — even from a clean, frontal studio portrait. So this composes a scene; it does not place someone recognisable into one, and nothing in the panel or this README claims otherwise.
The AI assistant can compose too. multi_reference joins the seven tools already reachable over MCP, with the same "requires layers captured in the panel first, only the parameters you pass are changed" boundary every other bridged tool has, and the likeness limit stated directly in the tool description an agent reads before running it.
Also new in v0.18.0-alpha:
Also new in v0.16.0-alpha:
inpaint-flux2-klein. The first inpaint preset that is not a Flux Fill model. It reuses the Klein 4B stack you already have for Text to Image — no extra model download — and repaints a selection at four steps, using the same comfyui-inpaint-cropandstitch node pack as the crop-and-stitch Flux Fill preset. Experimental; strongest at adding to a small selection or replacing a large region.214748.36. A UXP number input cannot hold a value that large, so any seed wider than six digits — including every seed loaded from History — came back mangled and then failed the run with "Seed must be a whole number". The seed fields are plain numeric text fields now and hold the full range.Also new in v0.15.0-alpha:
An AI assistant can drive OpenLayer's tools. Ask Claude — or Codex, or anything else that speaks the Model Context Protocol — to generate an image, upscale a layer or caption a selection, and it works the panel's own buttons in your open document. All seven tools are reachable. It runs entirely on your machine and is off until you turn it on, in Setup → Agent Bridge.
The bridge contains no Photoshop code: it can only run a tool the panel already has and read back what the panel said happened. An agent-driven generation and a clicked one are the same code path, so the same safety rules apply to both.
The bridge is not in the download. A Photoshop plugin package cannot install or start a Node program, so it lives in the repository: clone or download it, then cd bridge && npm install && npm run hub. bridge/README.md covers the setup and the one line that registers it with your AI client.
Ask the Agent for a Prompt, under the Text to Image prompt box — the panel asking the assistant for once. Needs an AI client that supports MCP sampling; see the boundaries below.
Version drift is a test failure now. v0.14.0-alpha displayed v0.13.0 in the panel footer, in both diagnostics lines, and in the version recorded against every session-history entry, because the number lives in eight places and one of them moved file. npm test now names whichever file disagrees.
FLUX.2 Klein 4B, text-to-image, image-to-image, and instruction editing. Three new presets — txt2img-flux2-klein, img2img-flux2-klein, and edit-flux2-klein — run Black Forest Labs' distilled Klein 4B at 4 steps, CFG 1. A 1024x1024 generation completed in 11.6 seconds on a 4070 Ti. The download is 4.07 GB (flux-2-klein-4b-fp8.safetensors) plus a 336 MB VAE; the 8 GB qwen_3_4b.safetensors text encoder is the same file the Z_image_Turbo presets already use. Every node is core ComfyUI — no new custom-node packages — and Klein is Apache-2.0 and ungated.
Instruction editing is not image-to-image. edit-flux2-klein tells the model what to change ("make the jacket red", "turn the sky to dusk") instead of describing the whole picture. It starts from an empty latent at denoise 1 and supplies your layer as conditioning through ReferenceLatent, so the model follows the instruction while seeing what the scene is. Denoise is hidden because it is fixed at 1 — that is the technique, not a default.
Context-aware Inpaint: inpaint-flux-fill-cropstitch. A second Flux Fill preset that crops to your mask plus context, samples that at 1024x1024, and stitches the patch back with a blended seam, using lquesada's ComfyUI-Inpaint-CropAndStitch. A small mask on a large document no longer samples a few hundred pixels, and a large one no longer samples several thousand. It ships alongside inpaint-flux-fill-basic rather than replacing it, because the custom-node dependency is optional.
Image to Image results land where they came from. The imported layer could arrive offset from the layer it was generated from. Capture now records where in the document it read from, and the import moves the layer there explicitly.
Also new in v0.14.0-alpha:
Also new in v0.13.0-alpha:
.gguf file and pressing Generate failed outright. Both were reported by a tester on the release.Also new in v0.11.0-alpha:
txt2img-krea2-turbo and inpaint-flux-fill-basic, and the status badge is now one squared label used on both screens.Also new in v0.10.0-alpha:
unzip unpacks as a flat directory with no assets/ folder, so the panel could not render. If an earlier release gave you a blank panel on macOS, this was why — use this one.Also new in v0.9.0-alpha:
Also new in the 0.8 series:
img2img-z-image-turbo's editable source workflow is correct. It previously held the vendor's text-to-image demo graph, so opening it to learn the workflow showed a graph that cannot do image to image. Generation was never affected.TextEncoder and TextDecoder that Node provides but Photoshop UXP does not.App.ts has been reduced from 6,112 lines at v0.7.0 to 4,922 — down from a peak of 8,149 — by extracting error messages, status handling, and DOM event wiring. A separate CSS audit measures consolidation work without changing styles in this release.Included in this alpha:
Compact Adobe Dark as the default and Classic v0.4 as an optional legacy visual styletxt2img-basic presetimg2img-basic presetsketch2img-linecn-basic LINECN preset/system_statsImagePadForOutpaintImport Automatically toggle for sending generated results straight back into Photoshopupscale-basic workflow using LoadImage, UpscaleModelLoader, ImageUpscaleWithModel, and SaveImageinpaint-basic workflow with source image and mask upload to ComfyUI
The v0.6 dashboard is denser, clearer about tool availability, and designed for narrow Photoshop panels. The accepted UXP layout adds sticky tool headers, determinate generation progress, larger prompt editors, and consistent spacing without changing the local workflow engine.


The earlier card-based dashboard established OpenLayer's honest available/experimental/coming-soon model. v0.6 keeps that information architecture while using less space and fitting Photoshop more naturally.
v0.19.0-alpha tester focus:
v0.19.0. It read the wrong version for the whole of v0.14.0-alpha, so this is worth a glance before anything else.Also worth rechecking from v0.18.0-alpha:
214748.36. Then load an entry from session History and generate from it — its seed must load and run, not fail with "Seed must be a whole number". That failure hit every History load before this release.inpaint-flux2-klein, and generate. Confirm the repaint blends into the surrounding image. It is strongest at adding something to a small selection — try that, and try replacing a larger region. It needs the comfyui-inpaint-cropandstitch node pack; if it is missing, Workflow Health should name it.Also worth rechecking from v0.15.0-alpha:
txt2img-flux2-klein. It should complete in under 15 seconds on a 4070 Ti at 1024x1024. Confirm the result is coherent and the prompt was followed.img2img-flux2-klein, capture a layer, and generate. The result should follow your layer. Then switch to edit-flux2-klein, enter a change instruction ("make the sky orange"), and generate again — the edit should apply the instruction while keeping the rest of the scene.inpaint-flux-fill-cropstitch. Generate and confirm the inpainted area blends into the surrounding image. Compare with inpaint-flux-fill-basic at the same selection — crop-and-stitch should produce sharper detail on small selections in large documents.cd bridge && npm install && npm run hub), then turn the toggle on. It should connect without any AI client running at all — the hub is independent of them.bridge/README.md has the line), then ask it to call get_panel_state. It should report connected: true and list all seven tools.Also worth rechecking from v0.14.0-alpha:
z_image_turbo_bf16.safetensors.Also worth rechecking from v0.13.0-alpha:
txt2img-krea2-turbo, and confirm a LoRA (optional) row appears with None selected and no strength field. Generate once with None — it must succeed — then pick a LoRA and generate again at the same seed. The two images must differ.(name suggests another model), and generating should succeed with a visibly unchanged image — that is the silent failure the warning describes, not a bug.Also worth rechecking from v0.11.0-alpha:
Open Setup from Home before starting ComfyUI. Confirm every model and node package is still listed with its folder, size and links, that the three tallies show a dash rather than 0, and that nothing claims you are set up.
Start ComfyUI, click Check Again, and confirm the list splits into what you have and what you are missing, with the installed rows collapsed. The remaining download figure should count each file once even though several presets share it — and should say "Nothing" if you have everything.
Move one model into the wrong folder — a checkpoint into models/diffusion_models/, say — check again, and confirm its row says you already have the file, names the folder it is in, and does not add its size to the remaining download.
Use the filter chips to narrow the list to one tool, and confirm the tallies and the download total keep describing everything rather than only the filtered slice.
Read "What will run well" at the bottom of Setup. Confirm the VRAM figure matches your card, that the order runs best-first, and that the Florence-2 preset is not claimed to be the most comfortable one on the list.
Look at the status badges on both Setup and Check Workflow Health: they should be the same squared uppercase label on both screens, with no text cut off by an ellipsis. The longest ones are NEEDS WORKFLOW JSON and MISSING COMFYUI NODE.
Confirm the filter chips read as flat outlined pills of uniform height — not gold switches, not stretched ovals.
Confirm Workflow Health names presets the way an artist would ("Krea-2 Turbo", "Standard checkpoint") rather than by their internal ids. Also worth rechecking from v0.10.0-alpha:
Unzip the release package and confirm it expands into folders, with an assets/ directory beside index.html — not a flat pile of files with backslashes in their names. On macOS this is the single most useful thing to report.
Put a model in the wrong folder on purpose — move a checkpoint into models/diffusion_models/, say — then run Check Workflow Health and confirm the report names the folder it actually found it in and the folder the workflow wants.
Open Live Painting. Confirm Start and Stop Live Session have a gap between them and are the same height, and that the two explanatory hints read as full paragraphs rather than ending in an ellipsis.
Set a Live Painting negative prompt, start a session, and paint. Then run one session with the field left blank and confirm it behaves as it did before.
Also worth rechecking from v0.9.0-alpha:
input folder under the name the status line reports.npm run setup-pack and confirm it reports no source/API mismatches at all.Known v0.19.0-alpha boundaries:
.ccx/.zip download. A Photoshop plugin package cannot install or start a Node program, so it lives in the repository — see bridge/README.md. It is off by default in the panel either way. "Ask the Agent for a Prompt" additionally depends on your AI client supporting MCP sampling, which is optional in the protocol; a client that does not offer it gets a clear, instant refusal rather than the button working.sketch2img-zimage-fun-controlnet (lite, 2.0 GB, faster) and sketch2img-zimage-fun-controlnet-full (6.7 GB, slower). Neither Z_image_Turbo preset replaced the other, because they measured as complementary rather than ranked: the full weights render shaded or densely drawn work more photographically, while the lite weights hold bold sparse line art that the full weights flatten into a filled shape at any control strength. Their default control strengths differ for the same reason -- 1.0 for lite, 0.6 for full, which patches five times as many layer blocks. The SD 1.x presets are tested with epicrealism_naturalSinRC1VAE.safetensors and their respective control_v11p_sd15_* ControlNets; the Z_image_Turbo presets with z_image_turbo_bf16.safetensors and, respectively, Z-Image-Turbo-Fun-Controlnet-Union-2.1-lite-2602-8steps.safetensors and Z-Image-Turbo-Fun-Controlnet-Union-2.1.safetensors.inpaint-basic workflow when ComfyUI has the required nodes.inpaint-basic (SD 1.x), inpaint-flux-fill-basic (Flux Fill), and inpaint-flux-fill-cropstitch (Flux Fill with crop-and-stitch). The crop-and-stitch preset requires lquesada's comfyui-inpaint-cropandstitch custom-node package; without it the preset is unavailable and the original Flux Fill preset still works.img2img-basic is the default SD 1.x/SDXL preset. SD3, SD3.5, and Flux checkpoints remain visible but are marked experimental because they usually need dedicated future workflow presets.UNETLoader, CLIPLoader, and VAELoader instead of the checkpoint loader.txt2img-flux1-dev-fp8 is an experimental checkpoint-style Flux Text to Image preset for flux1-dev-fp8.safetensors.txt2img-flux2-klein, img2img-flux2-klein, edit-flux2-klein) use flux-2-klein-4b-fp8.safetensors (4.07 GB), qwen_3_4b.safetensors (8 GB, shared with Z_image_Turbo), and ae.safetensors (336 MB). Klein is Apache-2.0 and ungated. edit-flux2-klein is structurally different from image-to-image: it uses ReferenceLatent conditioning at denoise 1, not a starting latent at partial denoise.txt2img-flux1-dev-fp8 already covers Flux Text to Image. Every preset the panel lists is now one you can actually run.comfyui-florence2 and Florence-2-base-PromptGen-v2.0. The comfyui-custom-scripts pack is no longer needed.outpaint-flux-fill-basic with flux1-fill-dev.safetensors, clip_l.safetensors, t5xxl_fp16.safetensors or the accepted T5 fp8 fallback, and ae.safetensors.UpscaleModelLoader and ImageUpscaleWithModel nodes plus an installed upscale model such as 4x-UltraSharp.pth or RealESRGAN_x4plus.pth.input folder. It does not build or run a workflow for you — you reference the uploaded file from a workflow yourself.--preview-method auto, and the preview panel may flicker between steps until a future UI polish pass.The static landing page is in:
docs/index.html
For GitHub Pages, publish from the docs folder on the main branch.
OpenLayer includes a beginner-friendly guide for local model choices, VRAM tiers, and why diffusion model stacks such as Z_image_Turbo do not appear in the checkpoint selector:
docs/model-guide.md
The current experimental inpainting status and next debugging checklist are documented in:
docs/inpainting.md
Key technical decisions for the project are tracked in:
docs/technical-decisions.md
Working foundation:
txt2img-basic workflow generationtxt2img-z-image-turbo workflow generationimg2img-basic workflow generation foundationimg2img-z-image-turbo workflow generation foundationsketch2img-linecn-basic Sketch to Image generation foundationprompt-from-layer-florence2 text workflow with Task and Num beams controlsupscale-basic pixel/model upscale workflowinpaint-basic/prompt submission/history/{prompt_id} polling/view image retrievalFuture placeholders are included for regional import alignment and selection preservation.
To use the plugin:
.ccx by double-clickhttp://127.0.0.1:8190To build from source instead:
The UXP Developer Tool is no longer needed just to run OpenLayer — see One-click install.
OpenLayer is local-first. The Photoshop UXP manifest currently requests filesystem and network access because:
OpenLayer does not send diagnostics, images, prompts, or model information anywhere automatically.
npm install
Build the plugin:
npm run build
Load the generated dist folder in Adobe UXP Developer Tool.
Run local checks:
npm run typecheck
npm test
These checks do not require Photoshop or ComfyUI.
For fast UI iteration outside Photoshop, you can run:
npm run dev
The dev server is useful for panel layout work, but the Photoshop-specific APIs only run inside Photoshop through UXP.
npm run package
This creates a zip package from dist in the packages folder. For the current alpha, the expected package name is:
packages/openlayer-v0.19.0-alpha.zip
npm run package also writes packages/openlayer-v0.19.0-alpha.ccx beside it, from the same files.
Every release attaches a .ccx. Double-click it and Creative Cloud installs the panel — no UXP
Developer Tool, no developer mode. Photoshop then lists it under Plugins > OpenLayer like any
other installed plugin.
This was an open question across three releases and is now answered. What was checked, on Windows 11
with Photoshop 2025 (26.1.0): the package installs, Adobe's Unified Plugin Installer Agent reports it
as Enabled OpenLayer 0.13.0 under Photoshop 2025 64, it unpacks to
%APPDATA%\Adobe\UXP\Plugins\External\com.openlayer.photoshop_<version>\ with no debug.json — a
packaged install rather than a developer load — and the panel opens and works in Photoshop.
Two things worth knowing before you try it:
.ccx on the same drive as Photoshop and Creative Cloud. The installer only searches
the drive the file is sitting on, so a .ccx on D: with Photoshop on C: fails.If double-clicking does nothing at all — a known Windows 11 quirk where Creative Cloud opens with no progress and no error — install it directly instead:
"C:\Program Files\Common Files\Adobe\Adobe Desktop Common\RemoteComponents\UPI\UnifiedPluginInstallerAgent\UnifiedPluginInstallerAgent.exe" /install "path\to\openlayer-vX.Y.Z-alpha.ccx"
UnifiedPluginInstallerAgent.exe /list all shows what is installed, and /remove OpenLayer uninstalls
it. Note that /list needs all or the exact product display name ("Photoshop 2025 64"); a partial
name like "Photoshop" prints nothing and no error, which looks exactly like "nothing installed".
Still unverified: macOS, and any Photoshop other than 2025. Reports either way are welcome.
The UXP Developer Tool route below still works and is what you want when building from source.
Add Plugin.dist/manifest.json after running npm run build.Load.Start ComfyUI locally using your normal ComfyUI launch command. Confirm the server is reachable:
curl http://127.0.0.1:8190/system_stats
In OpenLayer, keep the default server URL or enter your own:
http://127.0.0.1:8190
OpenLayer uses port 8190 by default so it does not interfere with another tool that may already be
using ComfyUI on port 8188.
You do not have to move your server to 8190. If ComfyUI is already running somewhere else — 8188
or anywhere — open Settings and click Find ComfyUI Active Port. OpenLayer scans for the running
server, connects to it, and reports Ready. Use your normal launch command and leave it where it is.
Starting a dedicated instance on 8190 is the other option, not the required one:
python main.py --listen 127.0.0.1 --port 8190 --preview-method auto
--preview-method auto is optional but recommended: it makes ComfyUI stream live KSampler step previews into the OpenLayer result preview while generating.
Click Check ComfyUI before generating.
Find ComfyUI Active Port or Check ComfyUI to load the available checkpoints.Detect GPU & Recommend Models to see hardware-aware model suggestions.txt2img-basic.Generate.Import Result as New Layer, or enable Import Result Automatically before generating.The imported layer is named like:
OpenLayer_Generated_YYYYMMDD_HHMM
Image to Image.Capture Active Layer, or click Capture Canvas to use the visible document.img2img-basic.Generate Image to Image.Import to Layers.The imported layer is named like:
OpenLayer_Img2Img_YYYYMMDD_HHMM
epicrealism_naturalSinRC1VAE.safetensors
control_v11p_sd15_lineart_fp16.safetensors
Sketch to Image.Capture Active Layer, or click Capture Canvas.sketch2img-linecn-basic.epicrealism_naturalSinRC1VAE.safetensors.Generate Sketch to Image.Import to Layers.The imported layer is named like:
OpenLayer_Sketch_YYYYMMDD_HHMM
This alpha includes the first experimental SD 1.x mask-based inpainting path.
Inpaint.Capture Selection.Generate Inpaint.Import to Layers.The first inpaint-basic preset is experimental and intended for SD 1.x inpaint checkpoints first. inpaint-flux-fill-basic is also available as an experimental Flux Fill path when your local ComfyUI exposes the required Flux Fill model stack. inpaint-flux-fill-cropstitch adds crop-and-stitch sampling at 1024 on top of the same Flux Fill stack, and needs lquesada's comfyui-inpaint-cropandstitch node package.
Inpaint output quality, mask interpretation, and Photoshop alignment are still being tested. Use this path for debugging and feedback rather than production work.
Use this quick pass before reporting a v0.19.0-alpha test result:
http://127.0.0.1:8190.dist/manifest.json in Adobe UXP Developer Tool.Check ComfyUI; confirm checkpoints load.Check Workflow Health; confirm each registered preset shows Ready, Experimental, Missing model, Missing ComfyUI node, Needs workflow JSON, or Setup required, under its artist-facing name.Copy Diagnostics; confirm the report is copied or appears in the read-only diagnostics box.txt2img-basic image and import it as a new layer; confirm the determinate progress bar advances cleanly.txt2img-flux1-dev-fp8 with flux1-dev-fp8.safetensors if available, generate once, and confirm the result preview appears.Cancel Generation; confirm the status changes to Generation cancelled. and the next generation still works.Image to Image, capture either the active layer or canvas, generate with img2img-basic, and click Import to Layers.Import Automatically, generate once, and confirm the result imports as a new Photoshop layer.Upscale, capture either the active layer or canvas, choose 4x-UltraSharp.pth or another listed upscale model, generate, and click Import to Layers.Sketch to Image, capture either the active layer or canvas, generate with sketch2img-linecn-basic, and click Import to Layers.Inpaint, make a Photoshop selection, click Capture Selection, and confirm the selected-region preview and mask preview appear.inpaint-flux-fill-basic if your Flux Fill stack is installed, then click Import to Layers; keep inpaint-basic as experimental/debug-only if it does not match the source.For a step-by-step beginner smoke test, see:
docs/testing-v0.1-alpha.md
The included workflows are realistic starter ComfyUI workflows using common built-in nodes:
src/workflows/api/txt2img-basic.jsonsrc/workflows/api/txt2img-flux1-dev-fp8.jsonsrc/workflows/api/prompt-from-layer-florence2.jsonsrc/workflows/api/img2img-basic.jsonsrc/workflows/api/sketch2img-linecn-basic.jsonsrc/workflows/api/inpaint-basic.jsonsrc/workflows/api/inpaint-flux-fill-basic.jsonYou may need to replace the checkpoint name and node IDs for your own ComfyUI setup.
OpenLayer now keeps workflow files in two folders:
src/workflows/api/ for runnable API workflows submitted to ComfyUIsrc/workflows/source/ for GUI-editable ComfyUI source workflowsSee docs/workflow-files.md, docs/custom-workflows.md, and docs/comfyui-object-info-audit-v0.2.2.md for the workflow file structure, custom workflow mapping requirements, and the local node schema audit used by the workflow compatibility foundation.
The workflow builder injects:
Image to Image and Sketch to Image use Photoshop's UXP Imaging API to capture the active layer or canvas, encode the raw pixels as PNG, then send the source image to ComfyUI using /upload/image. JPEG source capture has been removed from this path so clean edges, masks, transparency, and linework are not degraded by lossy compression.
Inpaint uses the same PNG/lossless Imaging API path, clipped to a padded context around the active Photoshop selection when Photoshop exposes selection bounds. In v0.4.1-alpha, OpenLayer also creates a temporary white-filled selection layer, captures it as a grayscale PNG mask, deletes the temporary layer, and uploads both source and mask to ComfyUI.
The first inpaint-basic preset requires ComfyUI's standard LoadImage, ImageToMask, InpaintModelConditioning, KSampler, VAEDecode, ImageCompositeMasked, and SaveImage nodes. It is currently aimed at SD 1.x inpaint checkpoints.
The experimental inpaint-flux-fill-basic preset requires:
flux1-fill-dev.safetensors through UNETLoader from models/diffusion_modelsclip_l.safetensors through DualCLIPLoader.clip_name1 from models/text_encoderst5xxl_fp16.safetensors through DualCLIPLoader.clip_name2 from models/text_encoderst5xxl_fp8_e4m3fn.safetensors as an accepted T5 fallback when the fp16 file is not installedae.safetensors through VAELoader from models/vaeDifferentialDiffusion, FluxGuidance, ConditioningZeroOut, InpaintModelConditioning, KSampler, VAEDecode, and SaveImageFlux Fill follows the reference-style graph in src/workflows/source/inpaint-flux-fill-basic.workflow.json. That graph expects one LoadImage node whose alpha channel becomes the mask. OpenLayer preserves the Photoshop source PNG and embeds the white repaint mask into the uploaded PNG alpha channel before submission. Inpaint import currently uses aligned context import only. The earlier transparent outside-mask PNG experiment is disabled because Photoshop UXP canvas/blob compositing is not trusted yet. Output quality, mask polarity, and alignment are not confirmed stable yet, and Photoshop-native layer mask import remains planned future work.
For debugging, OpenLayer records source, mask, raw result dimensions, import mode, and temporary local debug copies of the source PNG, mask PNG, and raw generated PNG after an Inpaint run.
img2img-basic is intended for SD 1.x and SDXL-style checkpoints. SD3, SD3.5, and Flux checkpoints are shown in the selector for transparency, but OpenLayer warns before running them because those model families often need different loader, text encoder, and VAE nodes.
Sketch to Image uses the same Photoshop capture and ComfyUI upload path, then runs sketch2img-linecn-basic. This preset requires:
epicrealism_naturalSinRC1VAE.safetensorscontrol_v11p_sd15_lineart_fp16.safetensorsLineartStandardPreprocessorControlNetLoaderControlNetApplyAdvancedThe first LINECN preset is intentionally narrow. It is a working SD 1.x foundation, not a universal sketch workflow for SDXL, SD3, Flux, or Z_image_Turbo.
If you export a different workflow from ComfyUI, update the node IDs in src/comfy/presetRegistry.ts.
Make sure GitHub Pages is configured to publish from:
main / docs
The landing page entry file is docs/index.html.
Run npm run build, then load:
dist/manifest.json
in Adobe UXP Developer Tool. After loading, open Photoshop and use the Plugins menu to open OpenLayer.
Confirm ComfyUI is running on:
http://127.0.0.1:8190
You can test it in a browser or terminal:
curl http://127.0.0.1:8190/system_stats
If another local tool is already using 8188, keep OpenLayer on 8190 and start a separate ComfyUI instance for OpenLayer.
Click Check ComfyUI after ComfyUI is fully started. If it is still empty, confirm your models are installed in ComfyUI and that the server URL in OpenLayer matches the running ComfyUI port.
Check that the selected checkpoint exists in ComfyUI and that the selected workflow node IDs still match the starter workflow. Custom workflows currently require manual mapping in:
src/comfy/presetRegistry.ts
See docs/custom-workflows.md for the current custom workflow process.
Use an SD 1.x or SDXL checkpoint with img2img-basic first. If you select SD3, SD3.5, Flux, or another newer model family, OpenLayer will keep it visible but warn that it is experimental for this preset. Those checkpoints usually need a dedicated workflow preset before they can run reliably.
Open a Photoshop document before importing. OpenLayer imports into the active document and will show an error if no document is open.
.
|-- docs/
|-- scripts/
|-- src/
| |-- comfy/
| |-- photoshop/
| |-- ui/
| |-- utils/
| |-- workflows/
| |-- index.html
| |-- main.ts
| |-- manifest.json
| `-- styles.css
|-- package.json
|-- tsconfig.json
`-- vite.config.ts
MIT
OpenLayer™ — the OpenLayer name and logo may not be used by derivative works without permission.
See also: Privacy Policy and Terms of Service.
410 commits
TypeScript
85.2%
CSS
9.6%
JavaScript
5.2%