Photoshop Extensions with React
I’ve been working on a web-based design tool for a few months. After demoing it today someone asked if they could use it with Photoshop. The quick answer was “no, it's a web app that renders React components”, but I realized I'd been avoiding even exploring Photoshop extension creation, so I took the afternoon and looked into it.
The ecosystem is…interesting…
There are a TON of outdated buzzwords out there, but eventually I found great resources on Davide Barrance’s blog.
Turns out the panels are basically HTML + CSS + JS that communicate with CreativeCloud apps through JSX files (not that kind of JSX. Adobe ExtendScript).
ExtendScript sucks a lot but I figured I could take some of the pain out of the process and at least build the UI how I know best - React, Redux and Ramda.
Figured I'd share in case you’re feeling masochistic…
cd ~/Library/Application Support/Adobe/CEP/extensions git clone firstname.lastname@example.org:jongold/photoshop-react-redux-ramda.git com.yourcompany.yourextension
I couldn't deal with certificate signing just yet. Should you want to distribute
an extension there are resources in the Adobe CEP docs down there
So to enable debug mode in terminal:
defaults write com.adobe.CSXS.6 PlayerDebugMode 1
npm run build # or npm start # to watch
Then open the extension from Photoshop -> Extensions
To debug - open
UI stuff is in
ExtendScript is in
jsx/ - this is not JSX like React-JSX.
You could probably add the dependencies to the package.json but I was being lazy, sorry. They're being pulled from npmcdn in index.html.
After making changes to the UI ⌘-r in the browser.
After making changes to the ExtendScript the quickest way to
reload the page is double clicking on the panel twice to collapse & reopen with
it - should reinitialize it. You'll then have to visit
again to reconnect the debugger.
You can use this boilerplate in other CreativeCloud apps too - just change the targets in
CSXS/manifest.xml and it should show up in whatever app you want. ExtendScript APIs are different per app but they're all in the docs.