Edit in GitHubLog an issue

Photoshop API

Overview

The following line allows you access to the Photoshop DOM via UXP.

Copied to your clipboard
const app = require('photoshop').app;

From here, you can open documents, modify them, run menu items, and more.

Minimum Version

You will now find minimum version information on properties and methods. This version tag corresponds to the version of Photoshop where the member was introduced or last updated significantly. For properties, you will find a column "MIN VERSION". For methods, the version number appears as a tag to the right of the name.

Synchronous vs Asynchronous

An important difference between ExtendScript (and CEP) and UXP in Photoshop is that all ExtendScript calls to Photoshop were synchronous. This means they blocked the Photoshop UI while they were executing. In UXP, a method call is asynchronous, and does not block the UI thread.

For a smooth transition between the ExtendScript DOM and the UXP DOM, all properties (get and set) in the API were designed to be synchronous and do not need to be awaited. It is worth noting that they are, in the background, asynchronous in nature.

Working with Photoshop Objects

Photoshop Application

Through the app object, you can access the rest of Photoshop's objects and methods.

The currently-active document is obtained like this:

Copied to your clipboard
const doc = app.activeDocument;

And you can get an array of all open documents like this:

Copied to your clipboard
const allDocuments = app.documents;

See more properties and methods in app under Photoshop.

Detour - ExecuteAsModal

A key concept to understand before diving straight into Photoshop UXP plugin development is what we have termed "execute as modal". Any and all commands that may modify the document, or the application state, must utilize executeAsModal.

Copied to your clipboard
1async function makeDefaultDocument(executionContext) {
2 const app = require('photoshop').app;
3 let myDoc = await app.createDocument({preset: "My Web Preset 1"});
4}
5
6await require('photoshop').core.executeAsModal(makeDefaultDocument);

As you may notice, this restriction could encompass much of your plugin's functionality! There are many benefits for this model, however. A more detailed explanation is provided in the Execute as Modal documentation.

Document

Represents a single, open Photoshop document. From this object, you can access the document's layers, dimensions, resolution, etc. You can crop it, add/delete/duplicate layers, resize, rotate, and save it.

Get the dimensions of the active document:

Copied to your clipboard
1const app = require('photoshop').app;
2const myDoc = app.activeDocument;
3const height = myDoc.height;
4const width = myDoc.width;
5const resolution = myDoc.resolution;
6console.log(`Doc size is ${width} x ${height}. Resolution is ${resolution}`);

Flatten all currently open documents:

Copied to your clipboard
1const app = require('photoshop').app;
2const toFlatten = app.documents;
3async function flattenThem(executionContext) {
4 toFlatten.forEach((photoshopDoc) => {
5 photoshopDoc.flatten();
6 });
7};
8
9await require('photoshop').core.executeAsModal(flattenThem);

Create a layer:

Copied to your clipboard
1const app = require('photoshop').app;
2async function newColorDodgeLayer(executionContext) {
3 await app.activeDocument.createLayer({ name: "myLayer", opacity: 80, blendMode: "colorDodge" });
4};
5
6await require('photoshop').core.executeAsModal(newColorDodgeLayer);

See more properties and methods regarding Document under Document and Documents.

Layer

Represents a Layer, or a group of Layers. This object is tied to a particular Document.

Decrease a layer's opacity and bring it to the front:

Copied to your clipboard
1const app = require('photoshop').app;
2const doc = app.activeDocument;
3function bringActiveLayerToFront(executionContext) {
4 const layer = doc.activeLayers[0];
5 layer.opacity = layer.opacity - 10;
6 layer.bringToFront();
7};
8
9await require('photoshop').core.executeAsModal(bringActiveLayerToFront);

Scale down each layer whose name includes 'smaller'

Copied to your clipboard
1const app = require('photoshop').app;
2const doc = app.activeDocument;
3const layers = doc.layers;
4async function scaleLayers(executionContext) {
5 for (layer of layers) {
6 if (layer.name.includes('smaller')) {
7 await layer.scale(80, 80);
8 }
9 }
10};
11
12await require('photoshop').core.executeAsModal(scaleLayers);

Note that a layer's kind property can be GROUP for a Group layer (a layer or folder containing multiple layers). To access the layers in a Group layer, use the layers property, and the parent property to navigate the layer list tree.

See more properties and methods for Layer under Layer and Layers.

Actions and ActionSets

Many Photoshop users make heavy use of the Actions panel. Actions are essentially macros that can be recorded and played back to script commands and tools that you use frequently. Actions are grouped into Action Sets, similar to the way layers can be grouped into Group layers.

The Actions object allows you to delete, duplicate, rename, and play actions. There is no current way to create an action using UXP.

Similarly to Actions, the ActionSet object allows you to delete, duplicate, rename, and play Action Sets. There is no current way to create an Action Set.

Note that Actions and Action Sets exist app-wide; they're not tied to a specific Document.

Here's an example that finds a particular Action in the default Action Set, then plays it if it exists:

Copied to your clipboard
1const app = require('photoshop').app;
2const allActionSets = app.actionTree;
3const firstActionSet = allActionSets[0];
4let actions = new Map(); // a JS Map allows easy "find by name" operations
5firstActionSet.actions.forEach((action) => { actions.set(action.name, action)});
6const myAction = actions.get("Wood Frame - 50 pixel");
7if (myAction) { // user may have deleted this action
8 async function playMyAction(executionContext) {
9 await myAction.play();
10 }
11 await require('photoshop').core.executeAsModal(playMyAction);
12}

See more properties and methods for Action under Action and ActionSet

batchPlay

Photoshop is complex software, with many internal classes and methods. Not all of these are yet exposed via UXP. New interfaces are in development and will be shipped along with each release of Photoshop. In the meantime, if there is something your plugin or script needs to do that is not exposed in the current DOM, you may be able to use batchPlay.

BatchPlay is for accessing Photoshop functionality that has not yet been exposed via APIs. BatchPlay is a way to send multiple actions into the Photoshop event queue and return their results.

ExtendScript has executeAction; this is analagous to UXP's batchPlay. However, whereas executeAction could only play one descriptor at a time, batchPlay accepts an array of action descriptors. If you have multiple Photoshop operations that need to execute in series, using an array of action descriptors in a single batchPlay call is probably what you want.

Unlike ExtendScript where classes were provided to construct action descriptors, references and values, batchPlay accepts plain JSON objects.

The batchPlay documentation contains details on how to construct JSON for batchPlay usage.

UXP Scripting

UXP is not just for plugins anymore. Individual JavaScript files may be developed and executed as detailed in the UXP Scripting section.

  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2023 Adobe. All rights reserved.