Module 6 β’ Lesson 1π» JavaScript / UXP Scripting in Depth
Actions replay fixed steps; scripts think. With a little JavaScript you can loop over files, branch on logic, do math, and reach parts of Photoshop no Action can touch. You don't need to be an engineer β you need to read, adapt, and run code, and this lesson makes that concrete.
π What You'll Learn
By the end of this lesson, you will be able to:
- Explain the Photoshop DOM: app β documents β layers β properties
- Tell ExtendScript (.jsx) from modern UXP JavaScript, and when each applies
- Write loops and conditionals β the logic Actions can't express
- Read and adapt a complete script (and run it via File βΈ Scripts)
- Reach for batchPlay when the DOM doesn't expose something
β±οΈ Estimated Time: 60 minutes
π― Project: One adapted, working script that does something an Action can't β a per-file decision or a computed output.
In This Lesson
π€ The Goal: Steps That Think
An Action does the same thing every time; a script decides. On the right, an Action blindly replays fixed steps β it can't ask "is this one landscape?" or "how many layers are there?". On the left, a script loops, checks conditions, and produces different, correct output per file. Logic is the whole difference. Drag the handle:
π§ Mental Model: The DOM
A script drives Photoshop through its Document Object Model β a tree of objects you read and change. At the top is app; it has documents; each document has layers, a width, a color mode; each layer has a name, opacity, blend mode, bounds. Scripting is just walking that tree and setting properties: "for each document, for each layer, if the name starts with 'BG', hide it." If you can describe the task as objects and properties, you can script it.
βοΈ ExtendScript vs UXP
Two scripting worlds coexist. ExtendScript (.jsx) is the legacy engine: old-JavaScript, a mature DOM, run instantly via File βΈ Scripts βΈ Browse β perfect for quick automation and the vast library of existing scripts online. UXP is the modern platform: current JavaScript, async APIs, and the foundation for plugins with real HTML/CSS panels (Lesson 6.2). For a one-off batch job, ExtendScript is often the fastest path; for a tool you'll ship or give a UI, use UXP.
.jsx immediately β the fastest way to run and test automation. The built-ins above (Image Processor, Export Layers) are scripts too.β οΈ Copy-adapt before you write from scratch
You rarely start with a blank file. The web is full of Photoshop scripts for almost any task; the real skill is reading one, changing the values and logic to fit, and testing on a copy. Treat scripting like LUTs or brushes β a library to draw from, not a language to memorize.
π§Ύ A Script That Loops & Decides
Here is a complete, readable ExtendScript that does something no Action can: loop every open document, branch on its orientation, and export each at the right crop and multiple sizes. Read it top to bottom β you can already follow every line.
// smart-export.jsx β File βΈ Scripts βΈ Browse to run
var sizes = [2000, 1000, 500]; // long-edge sizes to export
var outDir = new Folder("~/Desktop/export");
if (!outDir.exists) outDir.create();
for (var d = 0; d < app.documents.length; d++) {
var doc = app.documents[d];
var wide = doc.width.value >= doc.height.value; // a decision Actions can't make
var ratio = wide ? (16/9) : (4/5);
for (var s = 0; s < sizes.length; s++) {
var copy = doc.duplicate(); // work on a throwaway copy
cropToRatio(copy, ratio);
var scale = sizes[s] / Math.max(copy.width.value, copy.height.value);
copy.resizeImage(copy.width * scale, copy.height * scale);
var name = doc.name.replace(/\.[^.]+$/, "") + "_" + sizes[s] + ".jpg";
var opt = new JPEGSaveOptions(); opt.quality = 10;
copy.saveAs(new File(outDir + "/" + name), opt, true);
copy.close(SaveOptions.DONOTSAVECHANGES);
}
}
alert("Exported " + app.documents.length + " docs Γ " + sizes.length + " sizes.");
function cropToRatio(doc, r) { // reusable helper
var w = doc.width.value, h = doc.height.value;
if (w / h > r) { var nw = h * r; doc.crop([ (w-nw)/2, 0, (w+nw)/2, h ]); }
else { var nh = w / r; doc.crop([ 0, (h-nh)/2, w, (h+nh)/2 ]); }
}
β When the DOM can't, batchPlay can
Some features aren't exposed as tidy DOM properties. Both engines let you replay a recorded low-level command β Action Descriptors in ExtendScript, batchPlay in UXP β captured with the ScriptingListener plugin or the UXP alchemist tool. It's less pretty, but it means anything you can do in the UI, you can script.
π οΈ Guided Build: Adapt a Script
Start from the script above (or any script you find) and make it yours.
Step 1: Run it as-is Β· 8 min
- Open a few documents. Save the script as
smart-export.jsxand run it via File βΈ Scripts βΈ Browse. Confirm the export folder fills up.
Step 2: Change the values Β· 8 min
- Edit the
sizesarray and the JPEG quality. Re-run and confirm your changes took effect. You're editing behavior without writing anything from scratch.
Step 3: Add logic Β· 12 min
- Add a condition: skip documents already under a certain size, or add a third ratio for square. One
ifis a capability an Action simply lacks.
Step 4: Make it safe Β· 6 min
- Wrap the work in
try/catchso one bad file doesn't halt the run, and log failures. Now it's a tool, not a toy. π
β Project Completion Checklist
- β Ran an existing script successfully via File βΈ Scripts
- β Edited its values and confirmed the change
- β Added a conditional β logic an Action can't do
- β Wrapped it in try/catch with error logging
- β Understand where batchPlay/descriptors fit
π§ Now You: Solo Variation
π Your challenge
- Write a script that renames or hides layers by a rule (e.g., hide every layer whose name starts with "ref").
- Adapt an "export each layer as a PNG" script you find online, and add a filter so it only exports visible layers.
- Record a UI action with the ScriptingListener, then paste the descriptor into a script β your first taste of scripting the un-exposed.
Going further: read Adobe's UXP scripting docs and port one of your ExtendScripts to UXP JavaScript. The concepts transfer; the syntax modernizes.
π³ Recipe Card: Scripting
Walk the tree, add the logic
- Think in the DOM: app β documents β layers β properties
- ExtendScript (.jsx) for quick jobs; UXP for panels/tools
- Use loops + conditionals for what Actions can't do
- Copy-adapt existing scripts; test on copies
- batchPlay/descriptors for un-exposed commands; wrap in try/catch
Mantra: if you can describe it as objects and decisions, you can script it.
π Learning Journal
Add to your journal after this lesson:
- Key concepts you learned
- Techniques that clicked for you
- Questions or confusion points to revisit
- Ideas you want to try
- Your progress and feelings about learning this
βοΈ This lesson's prompt: What repetitive task in your workflow needs a decision Actions can't make? That's your first real script β describe it as objects and conditions.
π Where This Leads
A script runs from a menu; a tool has a face. Next: Lesson 6.2 β Building a Panel / Plugin, where UXP turns your scripts into a real HTML/CSS panel with buttons, docked inside Photoshop.
Do I have to learn "real" programming for this?
Not to be effective. Reading, adapting, and running scripts covers most professional needs and is a learnable-in-a-weekend skill. Deeper programming unlocks more, but the ROI on "can adapt a script" is enormous on its own.
ExtendScript is old β should I ignore it?
No. It's mature, instantly runnable, and backed by a huge library of existing scripts, so it's often the fastest way to solve a one-off. Learn UXP for anything you'll ship or maintain, but ExtendScript is still a productive tool today.