Open-source project
lohriialo/photoshop-scripting-python avatar
lohriialo/photoshop-scripting-python

photoshop-scripting-python drives Photoshop from Python on both platforms

Scripting in Photoshop is used to automate a wide variety of repetitive task or as complex as an entire new feature

529 stars94 forksPythonNOASSERTION

At a glance

What is it?
photoshop-scripting-python is a collection of examples, helper modules, command line recipes and a PySide6 desktop toolkit for automating Photoshop with Python, using COM on Windows and appscript on macOS. It suits studios and template pipelines, and it is the wrong tool for anyone who needs Photoshop without a desktop session.
Who is it for?
photoshop-scripting-python is worth adopting for studios that already run Photoshop on a desktop, for template pipelines that need batch export or text replacement, and for people who want to keep working in Python instead of moving to Adobe's own JavaScript. It is the wrong tool for headless batch work, for work on a machine where Photoshop is not installed and running, and for cross-platform teams that do not want to maintain two spellings of every script.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 93 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two different automation stacks behind one Python API

photoshop-scripting-python exists to answer a narrow question: can the repetitive work in Photoshop be done in Python instead of in one of Adobe's own scripting languages? Adobe ships JavaScript, AppleScript for Mac and VBScript for Windows. The README frames the project as doing the same kinds of jobs in Python, for the benefit of people who already use Python for data, tooling and AI coding assistants.

The connection mechanism differs by platform, and the README is upfront about it. On Windows the script attaches to a running or newly launched Photoshop through Microsoft's automation interface, commonly called COM, using libraries such as pywin32 or comtypes. On macOS the same job is done through Apple's automation bridge via appscript. The underlying object model is the same tree Adobe's JavaScript sees: the application, open documents, layers, selections, colors. The Python spelling changes, the target does not.

The project also carries Action Manager and JavaScript bridge examples, optional COM type dumps under api_reference, and an interop_assemblies directory, so it is as much a reference collection as a library.

Installing per platform with extras, not one universal install

The install is a normal editable install of the repository, and the platform specific dependencies are selected through extras rather than pulled in unconditionally. The README's clone and install step looks like this:

bash
git clone https://github.com/lohriialo/photoshop-scripting-python.git
cd photoshop-scripting-python

# Windows
pip install -e ".[windows]"

# macOS
pip install -e ".[macos]"

# Optional desktop toolkit UI
pip install -e ".[windows,gui]"

What those extras contain is defined in pyproject.toml. The windows extra is pywin32>=306 and comtypes>=1.2.0, the macos extra is appscript>=1.2.0, and the gui extra is PySide6>=6.5.0. There is also an all extra that installs the Windows libraries conditionally on platform_system=='Windows', appscript on platform_system=='Darwin', and PySide6 everywhere.

The base package declares no dependencies at all, requires Python 3.9 or newer, and is versioned 2.0.0 in pyproject.toml. The classifiers list only Windows and MacOS, which matches the badge in the README, and the project status is given as 4 - Beta.

The Windows hello world and what get_app returns

The README's first example starts Photoshop and then runs a script from the sample_scripts folder:

bash
python sample_scripts/windows/HelloWorld.py

The script itself shows the shape of the Windows API. The photoshop_scripting package exposes a LayerKind enum and a get_app function, and the returned application object exposes Documents.Add, ArtLayers.Add, and the familiar TextItem interface:

python
from photoshop_scripting import LayerKind, get_app

app = get_app()
doc = app.Documents.Add(320, 240)
layer = doc.ArtLayers.Add()
layer.Kind = int(LayerKind.TEXT)
layer.TextItem.Contents = "HELLO WORLD!"
layer.TextItem.Position = (120, 120)

Note the explicit int() cast around LayerKind.TEXT. That is the kind of small friction that comes from bridging a strongly typed language to a COM automation interface, and it is the kind of detail that the sample scripts exist to show.

The Windows scripts are Windows only. The README says that running one on a Mac stops with a short message pointing at the macOS folder, which is a nicer failure mode than a confusing COM import error.

The macOS spelling of the same three lines

The macOS example is the same job in appscript terms, and the README shows both the install and the run:

bash
pip install -e ".[macos]"   # or: pip install appscript
python sample_scripts/mac_scripting/HelloWorld.py

The code uses the appscript `k` constant for enumerators and a local ps_connect helper to reach the application:

python
from appscript import k
from ps_connect import photoshop  # when running inside sample_scripts/mac_scripting/

ps = photoshop()  # connects to your installed Photoshop app
doc = ps.make(new=k.document, with_properties={k.width: 320, k.height: 240})
layer = doc.make(new=k.art_layer, with_properties={k.kind: k.text_layer})
layer.text_object.contents.set("HELLO WORLD")
layer.text_object.position.set([120, 120])

The object model is recognisably the same document, art layer, text contents and position, expressed with make and with_properties rather than method calls.

One environment variable resolves a real ambiguity. If a machine has more than one Photoshop installed, for example a release build and a Beta, the README says to pick one explicitly:

bash
export PHOTOSHOP_APP_PATH="/Applications/Adobe Photoshop 2026/Adobe Photoshop 2026.app"

Without it, the connection code has to guess, and on a machine used for testing pre-release builds, guessing is exactly the wrong behaviour.

Where the code lives: samples, a helper package, recipes and a toolkit

The repository is organised by how much you want to take on. The README provides a table that maps intent to directory. Short examples live in sample_scripts/. The reusable connect, path and constant helpers are packaged as photoshop_scripting. Common studio batch jobs that can be run from the command line sit in recipes/. A point-and-click batch application is in tools/photoshop_toolkit.

The toolkit is the piece aimed at users who do not want to write Python at all. It is described as a dark, production-style multi-tool, and it covers nine jobs in one table: Batch Resize for folder resize with aspect lock and resample methods, Batch Export for turning PSD and TIFF files into JPEG and PNG delivery folders, Layer Comps to export each comp to its own file, Run Actions to apply Actions-panel macros across a folder, Export Layers to write each art layer to a file, Watermark for copyright text across image folders, Convert sRGB for web-safe delivery color, Canvas Border for padding and mockup frames, and Text Replace for bulk find and replace inside PSD templates.

It installs with the gui extra and runs either as a module or through a console script named photoshop-toolkit:

bash
pip install -e ".[windows,gui]"
python -m tools.photoshop_toolkit
# or: photoshop-toolkit

Why you cannot skip the running Photoshop

The binding constraint of this project is that it is not a standalone image processor. The connection attaches to a running or newly launched Photoshop, which means a desktop session, a licensed install and the application actually starting up. The Windows examples are documented as starting Photoshop first and then running the script, and the macOS helper is described as connecting to your installed Photoshop app.

That rules out several otherwise attractive uses. A container with no GUI, a CI runner without a display, a server-side batch job, and any workflow that needs to scale across many machines without a human at each one all hit the same wall. The project does not claim to solve them, and nothing in the README suggests a headless mode exists.

The other constraint is that the two platforms are not interchangeable. A Windows script on a Mac stops with a pointer to the macOS folder, and the macOS and Windows object spellings differ enough that a script written on one platform does not transfer to the other. For a team that ships on both, the practical cost is maintaining two versions of the same automation logic, which is worth weighing against the benefit of staying in Python.

Licence, packaging and the maintenance picture

Licensing needs a careful reading rather than a summary. The pyproject.toml declares the project licence as MIT and the classifiers include the MIT licence classifier, and the README refers to MIT-licensed project code. The repository also has a LICENSE file at its root that GitHub does not classify, and the packaging metadata is what an installer will read, so anyone redistributing this inside a studio toolchain should read that file directly rather than rely on the badge.

Packaging itself is plain setuptools. The build system requires setuptools>=61 and wheel, packages are found with an include list of photoshop_scripting* and tools*, and a single console script is declared for the toolkit. A setup.py shim is present with a comment describing it as backward-compatible editable installs for older pip and setuptools, and requirements.txt holds convenience pins for local development rather than being the primary install path. Ruff is the linter, configured with a line length of 100 and a py39 target version.

On maintenance, the repository is not archived and the last push was on 2026-07-22. It has no GitHub releases, so there is no tagged version history to pin to, only the version field in pyproject.toml, which reads 2.0.0.

Editorial conclusion

photoshop-scripting-python is worth adopting for studios that already run Photoshop on a desktop, for template pipelines that need batch export or text replacement, and for people who want to keep working in Python instead of moving to Adobe's own JavaScript. It is the wrong tool for headless batch work, for work on a machine where Photoshop is not installed and running, and for cross-platform teams that do not want to maintain two spellings of every script. Before adopting, check the pyproject.toml extras for your platform, since the Windows and macOS paths pull in different libraries, and confirm that the tool list in tools/photoshop_toolkit covers the job you actually need, because that package depends on PySide6 and is installed with the gui extra.

Frequently asked questions

How do I install photoshop-scripting-python on Windows?

Clone the repository and run pip install -e ".[windows]", which pulls in pywin32 and comtypes for the COM automation interface. Adding the gui extra installs PySide6 for the desktop toolkit.

How does Python connect to Photoshop on macOS?

On macOS the connection goes through Apple's automation bridge using appscript, which the macos extra installs. The README's example uses the appscript `k` constant and a local ps_connect helper to reach the running Photoshop app.

Can I run the Windows sample scripts on a Mac?

No. The README says scripts under sample_scripts/windows/ are for Windows only, and on a Mac they stop with a short message pointing to sample_scripts/mac_scripting/.

What does the Photoshop Toolkit app do?

It is a point-and-click batch tool covering Batch Resize, Batch Export, Layer Comps, Run Actions, Export Layers, Watermark, Convert sRGB, Canvas Border and Text Replace, installed with the gui extra and run with python -m tools.photoshop_toolkit or the photoshop-toolkit command.

How do I choose between two installed versions of Photoshop?

Set the PHOTOSHOP_APP_PATH environment variable to the application bundle you want, for example export PHOTOSHOP_APP_PATH="/Applications/Adobe Photoshop 2026/Adobe Photoshop 2026.app", which matters when a release build and a Beta are both installed.

Official sources

  1. Issues
  2. lohriialo/photoshop-scripting-python on GitHub
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lohriialo-photoshop-scripting-python.svg)](https://hysenlabs.com/projects/lohriialo-photoshop-scripting-python)

Was this useful?