The first time I spent an entire workday doing the same crop-and-resize task 200 times, I told myself it was a one-off. It wasn’t. Three weeks later I was back in the same chair, same file naming convention, same repetitive hand motion, watching the clock. That afternoon I opened Google and typed “how to automate Photoshop.” It took me about 48 hours of fumbling through forums to write something useful. That was fifteen years ago, and I have not manually repeated a batch task since.

Most people stop at Photoshop Actions. They record a sequence, bind it to a function key, and call themselves automated. Actions are genuinely useful, and I still use them constantly. But if you have ever had an action fail silently on file number 47 of 300 because one image had a slightly different color profile, you already know their ceiling. Scripts do not have that ceiling.

What Actions Can’t See

Photoshop Actions are essentially a recording of your mouse clicks and menu selections. They play back in sequence, and they do not evaluate conditions. If the canvas size changes, if a layer is missing, if a file comes in as 16-bit instead of 8-bit, the action either crashes or plows ahead and produces garbage output. It has no way to ask “is this what I expected?”

JSX scripts, which is the scripting language Photoshop has supported since CS2, actually communicate with Photoshop’s object model. A script can read the document’s current color mode, check whether a specific layer exists by name, measure the pixel dimensions of the canvas, and branch into different behavior based on what it finds. It is not replaying your clicks. It is giving Photoshop instructions that Photoshop then executes against the actual state of the file.

The practical difference is enormous. An action resizes a canvas to 2000x2000 pixels regardless of what it started as. A script can check the aspect ratio first, calculate the correct resize to hit a long-edge of 2000 pixels without distorting the image, apply a specific output sharpening profile depending on whether the result is under or over 1500 pixels on the short side, and then save to a subfolder named after the source file’s embedded metadata. That is not a hypothetical. That is a script I built for an e-commerce client who was delivering to three different retailers with three different spec sheets.

The Architecture of a Useful Batch Script

The scripts I write for clients follow a structure I settled on after a lot of trial and error. Every script has four parts: a source folder declaration, a validation pass, the processing loop, and an error log.

The validation pass is the piece most tutorials skip. Before touching a single pixel, the script iterates through the source folder and checks that every file meets the expected conditions: bit depth, color mode, minimum pixel dimensions. Files that fail get written to a text log and skipped. This means when the script finishes processing 600 files, I have a clean log showing exactly which six images need manual attention and why, instead of a folder full of quietly corrupted outputs.

The processing loop itself is where the actual work happens. For a recent apparel e-commerce project, the loop was doing the following on each file: converting to sRGB if the embedded profile was Adobe RGB or ProPhoto, running a Curves adjustment saved as a preset to correct for the client’s particular studio lighting setup, resizing to 2400 pixels on the long edge at 150 ppi, applying an Unsharp Mask at 85 percent amount / 0.8 pixel radius / 0 threshold, flattening, and saving as a JPEG at quality 10 (roughly 92 percent quality in Photoshop’s internal scale). The entire batch of 500 images ran in about 22 minutes on a machine with 64GB of RAM. The same workflow done manually, even with Actions handling most steps, would have taken the better part of a day.

Building Your First Conditional Script

If you have never written JSX, start with Photoshop’s built-in Script Editor, or use Visual Studio Code with the ExtendScript Debugger extension. The ExtendScript Debugger is free and lets you set breakpoints and inspect variables, which is the only way to learn what is actually happening inside your script.

The single most useful thing to learn first is the app.activeDocument object and how to read properties off it. Open Photoshop’s JavaScript Scripting Reference PDF, which Adobe still hosts and is searchable, and look up Document.colorProfileName and Document.width. Those two properties will handle 80 percent of the validation logic you need for any photography batch workflow.

A conditional that checks color mode looks like this in practice: if the document’s color mode property does not equal RGBColor, convert it before doing anything else. That one check, which takes four lines of code, eliminates an entire category of failures that would otherwise require you to manually sort files before running your batch.

When I Got This Wrong and What It Cost Me

Early in my consultancy I built a batch script for a catalog shoot, tested it on 20 sample files, and handed it to a client’s internal team to run on 1,800 product images. I had not accounted for the fact that their in-house photographer occasionally shot tethered directly into Capture One and exported with a different metadata structure than our test files. The script was reading a specific IPTC field to generate output filenames. When that field was empty, the script saved every file with the same generic fallback name, each one overwriting the last.

They lost about 340 processed files. The RAW originals were fine, but the retouching had to be redone. I rebuilt the script that night with a validation check that flags any file missing the required metadata field before the loop even starts. I have never shipped a batch script without that check since.

The best automation is not the fastest automation. It is the automation that fails loudly instead of silently, and that tells you exactly where and why it stopped.