Networking Events

Two events you need to note down in your calendar:

  • Adobe Developers Live (June 19 + 20, 2024. Commencing each day from 3:15pm UTC (5:15pm CEST / 11:15am EST / 8:15am PST))
  • Creative Developers Summit (July 10 + 11, 2024, Washington DC, co-located with the CreativeProWeek)

Adobe Developers Live

Join me for ‘Adobe Developers Live’, organized by Adobe for everyone who develops – or would like to develop – add-ons, plugins or integrations for Adobe Express or Creative Cloud.

Whether in San Francisco, New York, Hamburg, or virtually from anywhere, you can be part of the experience. Even if your schedule is tight, register to access the event recordings later on.

New Zealand is far away, so I’ll get out of bed crazy early and will be joining virtually and I’ll present a short segment on day 2.

Creative Developers Summit

Since 2010, I’ve helped organizing our independent Creative Developer Summit, co-located with CreativeProWeek.

The 2024 Creative Developer Summit happens on July 10 and 11, at the Crystal Gateway Marriott hotel in Washington, D.C.

Make sure to read this blog post of mine:

This independent developer get-together is organized by developers for developers. Come and join your tribe!

To register, first contact me (kris at and ask me for the discount code.

Once you have the discount code, head to

and register for July 11 (the main summit) and/or July 10 (a workshop integrating Firefly with Creative Cloud APIs, run by James Lockman or his team from Adobe).

We’ll try to provide options for remote attendance, but unlike last year, we don’t have access to high-end video equipment, so we’ll try to use Teams for remote attendees. Please contact me to be added to the list, so I can send out connection details closer to the time.

PluginInstaller, or ‘getting there’.

It’s been a long, hard slog! Nearly three years ago, I set out to build a technology stack to address the gaps in Adobe’s automation tooling for the Creative Cloud ecosystem.

It seemed like a crazy endeavor for one person, but persistence (and a lot of blood, sweat, and tears) paid off.

I’ve finally reached the ‘minimum viable product’ stage, where I can use and present some of the tools I’ve been working on. There’s still much more to do, but the first tools are now available for use.

I’ve started converting Rorohiko’s automation tools to this new technology stack (currently TextExporter, JSXGetURL, SmokeWordStacks, SizeLabels)

The project, originally called Tightener, has stabilized over the last 6-8 months, and I’m now focusing on building tools for automating Adobe Creative Cloud apps (InDesign, Illustrator, Photoshop, etc.).

This subset of the project is called Creative Developer Tools, with two main components: CRDT_ES (for ExtendScript/CEP) and CRDT_UXP (for UXPScript/UXP).

Another key component built on top of Tightener and CRDT is PluginInstaller.

PluginInstaller aims to be a unified packager and installer for various types of software, including ExtendScript, CEP panels and soon UXPScript, and UXP panels.

It also uses a central registry to track users, machines, activations, and usage without storing personal data. The registry uses SHA-256 hashes, keeping the actual data secure on users’ computers.

Future features

Stuff I have in mind, which might or might be realized:

  • Porting the Rorohiko scripts, extensions and plugins to use PluginInstaller
  • PluginInstaller support for C++ plugins and hybrids
  • PluginInstaller support for UXPScript
  • PluginInstaller support for UXP Plugins
  • CRDT module with a look-similar feature for ScriptUI that can be used with both ExtendScript and UXPScript
  • CRDT module for user-interface development, to replace CEP and UXP for creating user interfaces
  • PluginInstaller search feature in various catalogs/enhancement store
  • Jupyter Notebook for ExtendScript
  • Python for automating Adobe Creative Cloud

Currently Available

Here’s a look at the currently implemented elements of the technology stack, from outer to inner components.


  • Generic Platform: Initially designed for the Adobe ecosystem but adaptable to other environments (e.g. Python ecosystem).

  • Unified Package Format (.tpkg):

    • Text-based format with metadata in the first 1KB, ensuring easy identification.
    • Capable of packaging and installing ExtendScript and CEP solutions. UXP soon.
  • Comprehensive Tool Replacement:

    • JSXBIN and ZXPSignCmd Replacement: Manages self-signed certificate generation and .zxp file creation.
    • ExtensionManager Replacement: Installs .tpkg files directly from URLs or after download.
  • Advanced Features:

    • Facilitates monetization and purchases, with a proof-of-concept integration with PayPal used in our Rorohiko products.
    • Payment processor agnostic. Developers can slot in their own payment processor if desired.
    • Handles activations and selective feature enablement for monetization.
    • Supports demo/trial versions and tracks anonymized usage data, providing insights into tool installations and usage frequency.
    • It’s now easy to experiment with different payment models: donationware, nagware, short subscriptions, long subscriptions…
    • Unified install experience for the end-user
    • Open for use by other developers
    • Pricing is still up in the air, but my intention is to make it totally free for small developers (1- or 2-man bands) with a revenue below a certain level.

Creative Developer Tools

  • CRDT_ES:

    • #include-able library for ExtendScript/CEP
    • Provides useful functions and acts as a JSXBIN replacement.
    • Enables code-signing for ExtendScript.

    • require()-able library for UXP/UXPScript
    • Offers functions that extend beyond the security sandbox.
    • Provides missing features such as environment access, binary file read/write capabilities, and encryption.
  • JSXGetURL:

    • Enhances ExtendScript with CURL features, effectively integrating Tightener capabilities.

Tightener Registry-Enabled Version

  • Dependencies:
    • In addition to Tightener Base also needs OpenSSL, curl, and zlib, to allow communication with the registry.
  • Advanced Features:
    • Unique Identifiers: Generates unique machine, user, and order GUIDs.
    • Central Registry: Uses a registry that stores only hashed data, ensuring no identifiable information or passwords are kept.
    • Distributed Data Storage: Relies on remote nodes (i.e. the user’s computer) for data storage needs.
    • Capability Tracking: Supports activating and managing floating licenses and activations.
    • Persistent Data Handling: Manages persistent local usage data for demo modes, trial versions, etc.
    • License Management: Handles floating licenses, allowing large accounts to allocate seats dynamically without requiring PluginInstaller for each end-user.
  • Availability:
    • Offered in various formats: as a command-line tool, or compiled and statically linked into various apps, as a DLL, or as a plugin for different environments.

Tightener Base Version

  • Core Features:
    • Pure C++ Code: Built entirely in C++ with no dependencies beyond the C++11 standard library.
    • Embedded Glue Language (TQL): Used for bridging; can also provide a scripting DOM into applications, akin to ExtendScript.
    • Messaging Protocol: Facilitates inter-app communication using a star topology, similar to Adobe Bridge’s protocol.
    • Optional Networking: Through gateway apps, multiple computers can be connected into a mesh of stars, enabling cross-network messaging.
  • Availability:
    • Offered in various formats: as a command-line tool, or compiled and statically linked into various apps, as a DLL, or as a plugin for different environments.

CEP: In-Circuit Debugging of a .zxp File

It’s not common knowledge, but you can package a CEP extension into a .zxp file and debug it ‘in-circuit’, without needing to set the CEP debug flag.

My trick is to not use the ZXPSignCmd to package up the .zxp file.

Last time I checked, as far as I could tell, the ZXPSignCmd app takes notice, and will omit the .debug file and will refuse to add it.

However, my new PluginInstaller is able to inject a .debug file into a packaged .zxp.

As it so turns out, that makes the installed extension debuggable, without setting the CEP debug flag.

You would not want to do this in a release version of your extension – but when it comes to diagnosing and debugging difficult-to-catch bugs on someone else’s workstation, this can be invaluable.

Below a little cookbook to demonstrate how you can go about this.

I’ve also made a ‘live video’ about it. The quality of the video is what it is, I think you can tell I am not interested in becoming a ‘Youtuber’. My main concern is the content, not the presentation.

First, download the CEPSparker project.

Click the green Code button and then click the option Download ZIP.

CEPSparker is a framework I made to help me generate ‘starter’ projects for CEP.

Important to note: CEPSparker is not a CEP extension project. It is a precursor to a CEP extension project.

`After downloading, if you’re on a Mac, you MUST right-click the initialSetupConfigApp.command file, select Open, then allow it to run by clicking the Open button.

This de-quarantines the other .command files so they can be double-clicked.

On Windows, expect some blue warning screens (click More Info and run anyway).

You will need to run the .bat files from the command line in an elevated Administrator CMD session; you can double-click sudo.bat to start such a session.

Next, double-click the SparkerConfig or SparkerConfig.exe application. For the demo, change the STARTERCODE dropdown menu and pick IFrameUIServer.

Click Generate.

This will generate a sample CEP project that has a ‘split personality’. The CEP panel is featureless, and only contains an <iframe>.

The content of this <iframe> is pulled from a web server.

The sample code demonstrates how such server-provided code can drive a user-interface inside a CEP panel, and interact with the local host app.

For the demo, we use a small local Node.js application to play the role of the ‘remote server’. The Generate will have created a lot of folders in the CEP project folder.

One of them is IFrameUIServer

Inside you find a little file server.js. You need to have Node.js installed; Google around if you don’t have it installed yet.

All you need to do is open a command line and navigate into this folder, then run

node server.js

and that will run a tiny web server on http://localhost:8001

Next, we will tweak the CRDT manifest for this CEP panel. The CRDT manifest (a file called CRDT_manifest.json) is used by PluginInstaller to determine what it needs to do to package the CEP panel.

Open CRDT_manifest.json in a text editor and change it so it reads:

"injectDebugFile": true,

You can leave the "productCode" entry set to CEPSparkerTest, for the sake of argument – we need this code for creating a product entry in PluginInstaller.

This tell the PluginInstaller to copy the debug file from the CEP Project into the ZXP and rename it to .debug.

If you inspect the debug file in a text editor, you see it configures the debugger to use port 8888:

<?xml version="1.0" encoding="UTF-8"?>
    <Extension Id="com.rorohiko.cepsparker.samplepanel">
            <Host Name="IDSN" Port="8888" /> 

Now run PluginInstaller and switch to developer mode (File – PluginInstaller ModePublisher/Developer). If you don’t have a registered account yet, you need to create one first: after switching to Developer mode, switch to the Accounts window.

Registration is free, but needs to be approved.

To register, you need to click New and fill in a terse bit of detail.

Once you click Register you’ll need to wait for a confirmation email, and after that, I will need to handle your registration request, and I will need to approve it first; if I don’t personally know you I’ll reach out via email.

Once you have a registered developer account, you can create a product entry in the Products window.

For this test, you can just fill in some random details. The only thing that needs to match is the product code which is CEPSparkerTest (unless you changed the "productCode" in CRDT_manifest.json – these names need to match for PluginInstaller to find the manifest).

Once you complete the new product entry, you can click Package… and navigate to the CEP project folder.

Once the packaging completes, you’ll find a .zxp file in the build subfolder.

For the demo, you can now install this .zxp file using a standard CEP installer (for example Anastasiy’s Extension Manager).

Make sure the Adobe CEP debug flag is turned off before trying this out if you want to verify that the debug flag has no influence on the debuggability of this .zxp

With the IFrameUIServer running, start InDesign and open the panel.

The panel should populate and show a UI that has a New Document button. This whole UI is served from the remote web server – if you look at your Node.js terminal window, you’ll see the http requests fly past.

Click New Document to create a new document.

Now start Chrome and access http://localhost:8888 – this will show you the familiar debug interface with two available sessions: one for the panel itself and a second one for the user interface inside the <iframe> on the panel.

Reach out to me if you find this kind of stuff helpful or interesting. I can help you kickstart your automation project and greatly reduce the time needed. In most of my projects, my role is to be a temporary member of the team, and help build the software, by managing, training, designing and coding, as needed.

Creative Developer Tools – status update

I’ve been working hard on Creative Developer Tools (CRDT).

My current focus is to implement a unified packager/installer/license management for third party Adobe scripts/extensions/plug-ins.

PluginInstaller handles the whole developer-to-user chain: packaging, downloading, installing, removing, updating…

I’ve just finished adding support for CEP. PluginInstaller now handles plain ExtendScript as well as CEP extensions. Next up is UXP.

PluginInstaller is part of the growing suite of Creative Developer Tools.

Unified Packager/Installer

PluginInstaller handles both packaging (developer side) and installing (user side) of third party enhancements to the Adobe Creative Cloud apps.

I’ve just released a new version of the PluginInstaller which combines support for plain ExtendScript (.jsx) as well as CEP panels (.zxp).

My plan is to further extend PluginInstaller so the same packager/installer will also handle UXP/UXPScript and C++ plug-ins.

PluginInstaller uses a unified package format (.tpkg) which combines a number of features:

  • Code signing
  • Code encryption
  • Licensing and activation
  • JSON meta-information in the .tpkg file header
  • Support multiple types of solutions (.jsx, .zxp…)

PluginInstaller can be downloaded here:

CEP: no more ZXPSignCmd

I’ve managed to fully integrate all the steps needed for .zxp code signing into CRDT/PluginInstaller.

As we all know, Adobe’s .zxp code signing is both required and ineffective – i.e. it’s just security theater. Just an additional hurdle that developers have to jump.

When packaging a CEP extension using PluginInstaller, it will automatically create and manage the necessary self-signed signing certificates during the packaging operation.

Separate of the Adobe code signing setup, CRDT/PluginInstaller implements a more generic code signing mechanism. This mechanism can handle all kind of project types, including plain ExtendScript script projects.

When PluginInstaller manages a CEP extension, it transparently manages two distinct ‘layers’ of code signing: one as imposed by Adobe, the second layer is handled by CRDT.

PluginInstaller will build both a standard .zxp as well as a .tpkg file when packaging a CEP extension.

The .zxp file is a courtesy file which is not needed nor used by CRDT. It allows the developer to opt for using existing installer tools (e.g. Anastasiy’s Extension Manager) instead of PluginInstaller.

Such .zxp is not protected by CRDT code signing, but it can still have access to the protective CRDT code encryption features as long as the CRDT_ES runtime is included into the package.

The PluginInstaller also handles downloading of .tpkg and handles management of activation files for commercial solutions that need licensing/demo configurations.

CRDT Encryption

CRDT uses two levels of encryption, for two different purposes: an outer level (public/private key) handles code signing, and an inner level (AES-256) handles code protection.

Code signing is there to protect the user: they can verify that the code they are about to run was created by someone they can trust.

Code encryption is there to protect the developer: it blocks malicious users from inspecting and copying the crucial code magic that makes a software solution work.

.tpkg files

.tpkg files are self-identifying. They are structured so they have a human/computer readable JSON header which contains useful meta-info about their content.

This also allows the use of partial downloads: we can download the first 1024 bytes of any .tpkg file and figure out what they are without having to download the whole file.

CRDT Code Signing

When a developer registers a developer account in PluginManager, it will use OpenSSL to automatically generate a public/private key pair and publish the public key in online registry. PluginInstaller handles key generation automatically and there is no cost to creating these keys.

The private key is only stored on the developer’s workstation and used to encrypt anything that gets packaged by the developer.

A package will only work when it is decrypted with the matching public developer key as retrieved from the registry.

The approach was chosen to avoid forcing developers to deal with expensive code-signing certificates.

When a developer creates a .tpkg, the file is encrypted using the developer’s private key.

Then, when the user downloads and installs the .tpkg, the file is decrypted using the developer’s public key as retrieved from the registry.

That way the user can make sure they know who the .tpkg was created by.

Code encryption

When a .tpkg file contains .jsx files, they are encrypted using AES-256.

CRDT_ES comes with a binary runtime in a .dylib/.dll. This runtime is loaded into the ExtendScript engine inside the host app, and it handles on-the-fly decryption and execution. This works for plain .jsx as well as for .jsx embedded inside a CEP solution/.zxp.

CRDT currently does not transparently handle encryption of other file types than .jsx (e.g. .js).

Encryption of .js files (as opposed to .jsx files) would currently not be a strong deterrent for hackers because the decrypted .js code could be inspected by way of a debugger, simply by putting a breakpoint after the decryption call.

.jsx is different: CRDT can execute the encrypted code straight from the CRDT runtime, which is binary C++ code, without making the code easily inspectable in an ExtendScript debugger. By judiciously using closures, the code can be made inaccessible to would-be snoopers that know how to use the ExtendScript debugger.

For .js I cannot do that (yet). I do plan to change this later, but I need to do some research and find Adobe documentation: I need to be able to embed and call a binary runtime from the embedded Node.js or UXP engines. I am eagerly awaiting the ability to call C++ code from a UXP script.

For the time being, if you have .js code that needs to be protected from prying eyes, stash it in a .jsx and call it from .js through CSInterface, or else use the ‘standard’ approach of uglifying the code.


CRDT encryption/decryption is also tied into the tracking/licensing/activation mechanisms. It allows developers to add code to decide whether their plugin/script is active/not active/in demo/paid for mode…

Depending on the situation, their extension can stop working, or be limited in features – whatever they want.

Payment Handling

Currently I don’t have payment handling integrated yet; but I plan to build sample integrations for PayPal and Stripe.

Developers can then decide to either use my integrations or create their own.

For the time being, when using CRDT for licensing, users need to pay the developer via a standard invoicing mechanism, after which can be emailed an activation file generated in PluginInstaller by the developer.

This is a manual process, which should be manageable for small developers.

Eventually this will all be fully automated.

CRDT also has support for sub-licensing, and can handle floating licenses to support licensing a developer’s solutions to larger companies.

Creative Developer Tools Progress

Creative Developer Tools (CRDT) is taking shape!

The ExtendScript version (CRDT_ES) is now quite functional and usable.

I’ve used one of my old ‘free’ ExtendScripts (SizeLabels) as a real-life test, and wrapped it up as a CRDT package, using a lot of the code-signing, encryption, licensing, trialware, installer… features of CRDT to make it into a ‘real’ project that could start generating some revenue.

A more in-depth developer perspective on how I used CRDT to repackage SizeLabels in this YouTube video:

CEP Extensions: Packaging/Code Signing/Encrypting in CRDT

The next subproject I’ll be tackling in CRDT are CEP extensions.

All the CRDT for ExtendScript features are already available in CEP extensions – so the monetization and other features offered by CRDT can already be integrated and used.

But there is more work to do.

The next goal is to reduce the friction related to code signing, packaging and encrypting CEP extensions

If all goes according to plan, PluginInstaller will handle both the packaging (by the developer) and installing (by the end-user) of CEP extensions.

It will transparently handle both the ‘mock’ code signing (CEP code signing) enforced by Adobe as part of its security theater, and will add a layer of ‘real’ code signing on top of that (CRDT code signing).

And of course, CRDT will provide a developer with the features they need to monetize their work.

CEP Code Signing – ucf.jar

PluginInstaller needs to handle the CEP code signing, so I’ve been doing some research, and I’ve discovered that the good old ucf.jar in the crusty old Adobe signingtoolkit can be made to work and can jpackage-d with a recent Java JDK.

I’ve got it working on my M2 Mac, and will now integrate it into PluginInstaller.

I am hopeful this will allow me to enhance PluginInstaller to transparently manage CEP code signing

PluginInstaller will then automatically create the self-signed key and sign your extension, making the creation of a package just a little bit easier.

CEP Extensions: Packaging/Code Signing/Encrypting

The aim is for PluginInstaller to transparently handle two types of code-signing, and a layer of encryption.

  • on one hand handle the Adobe-enforced CEP code signing
  • additionally, and independently, it will handle CRDT code signing, which depends on a registry of public keys to keep track of developers and their signatures.
  • it will also handle CRDT code encryption which is an AES-256-based encryption meant to replace JSXBIN.

CEP Code Signing

The whole bother with Adobe enforcing developers to sign CEP extensions is nothing but security theater. By making PluginInstaller handle this, I can remove another hurdle for CEP extension developers.

These signing keys are not verified in any which way by the Creative Cloud apps, so anyone can create their own key and sign anything and the Creative Cloud software will accept it, sight unseen.

Any hacker can claim to be anyone else, and create a self-signed key to ‘prove’ it to the Creative Cloud apps, and the Creative Cloud apps will happily take them at their word.

Nothing stops a malicious hacker from unzipping someone’s genuine .zxp, adding some malware to it, and re-package it with their own self-signed key.

CRDT Code Signing

CRDT code signing requires developers register their identity in a registry, so the PluginInstaller can verify their signature.

When a developer creates a developer account in PluginInstaller, a public/private key pair is automatically generated and the public key is published in the registry.

Developers retain their own private key locally, and PluginInstaller will use the private key to code-sign their scripts and data files when it packages the software.

CRDT Code Encryption

Additionally, CRDT also implements CRDT code encryption. This allows developers to protect their code from prying eyes. This is a replacement for JSXBIN as provided by ExtendScript.

What’s ahead

There is still a lot of work to be done on CRDT. Important things that are on my to-do list:

  • integrate payment processors like PayPal and Stripe. At the moment, payments are still handled manually.
  • handle packaging and installing of UXP plugins the same way ExtendScript and CEP Extensions are handled, so PluginInstaller can be a one-stop shop both for packaging (developerland) and installing (userland)

Creative Developer Tools

The first public alpha versions of Creative Developer Tools for the Adobe eco-system are now becoming available.

UXP and UXPScript are great, but for software solutions that are running in a ‘clean room’, having to fight the UXP security sandboxes can make a developer’s life miserable.

Also, handling activation/licensing for commercial software can be a pain. Creative Developer Tools can handle that for you.

Creative Developer Tools for UXP currently works with Photoshop and InDesign and provides a growing set of APIs, including APIs for reading/writing binary files and text files without artificial limitations imposed by the UXP sandbox.


for more info.

The crdtuxp module contains a mix of synchronous and asynchronous functions.

Some functionality is written in JavaScript as part of crdtuxp.js, and is synchronous.

Other functions are delegated to a daemon process which is able to operate outside of the UXP sandbox, but still within the confines of the logged-in user. These functions are always asynchronous.

Important note: crdtuxp steps out of the UXP security sandbox – which means that, as a developer, you need to be judicious how and when to use this.

The reality is that every software system operates in a unique context.

UXP security measures have their place and can be helpful in keeping things secure when it comes to UXP development.

However, for many software systems, these measures are too strict and overbearing and don’t account for the actual operating environment. It’s an all-or-nothing approach.

In my opinion, it should be up to the user/developer/IT department to decide how to handle security.

Sometimes a particular workflow system will be living inside a walled garden, on a disconnected network, without any contact with the outside world and will not be allowed to run any unvetted software. Or othertimes the OS security is safe enough for the particular workflow at hand.

In those cases, the UXP security measures are counter-productive: they represent unnecessary hurdles to the software development, and often make the user interface clunky and user-unfriendly.

Using UXP sandboxing should be a developer-selectable option, not an enforced ‘always-on’ requirement, and it should be up to the developer and/or the IT department to decide what is appropriate and what not.

Creative Developer Tools puts the power back into the hands of the developer, the end-user and the I.T. department, and leaves it up to them to opt-in or opt-out of the UXP security sandbox.

JSXGetURL now live

JSXGetURL enhances ExtendScript to make it easy to access servers using httphttps, sftp… – e.g. to download assets from a remote server, straight from ExtendScript. It supports InDesign, Illustrator, Photoshop,… – any Adobe software with ExtendScript support.

There is nothing to install – all you need to do is add a single //@include line to your script.

I’ve further enhanced the License Manager, and JSXGetURL 1.0.4 is now live on the Rorohiko web site.

I’ve added a feature that allows ‘sublicensing’, where you can embed an activation code for JSXGetURL into your own solution, so your end-user does not have to deal with activations.

Have a look at


Tightener is our answer to a growing gap in automating Adobe Creative Cloud applications.

Remember the days when scripting Adobe apps didn’t require a CS degree? When people with a passion for printing, photography, or design could just jump in and start scripting? Those days seem far gone with the advent of UXP and UXPScript.

That’s where Tightener steps in. We’re gradually winding back the clock, making scripting approachable again, especially for those who have the domain knowledge and the know-how but don’t feel compelled to get a degree in computer science as well.

Tightener is a toolbox for developers, easing everything from script writing to monetization, from inter-app communication to usage tracking. It’s a diverse platform, and we’re just scratching the surface.

And for small developers and not-for-profit: Tightener is free for you! We’re all about empowering small developers, handling the nitty-gritty of activations and metrics, so you can focus on what you do best.

The goal is to make other small developers successful and let Tightener rise along with them.

This release marks the debut of the licensing/activation module in the Tightener toolkit.

It’s fresh off the press and in a ‘stable alpha’ state. Yes, there are a few rough edges, but it’s ready for action.

I have integrated Tightener’s activation/licensing logic into JSXGetURL. From 2024 onwards, JSXGetURL will be a commercial product:

Note 12-Feb-2024: the next in line is Creative Developer Tools:

Why am I using JSXGetURL for the debut of Tightener? JSXGetURL is the perfect test bed – a modest user base, all fellow developers.

In the coming months, I’ll be converting some more of the commercial Rorohiko tools and scripts to incorporate the Tightener activation/licensing system.

I invite you to take JSXGetURL for a spin. Without activation, it starts in demo mode, so you can explore without cost.

If you hit a snag or have suggestions, drop me a line.

Curious about Tightener? More (currently somewhat outdated) info on github:

In the coming months I’ll be updating and expanding the wiki, writing a lot of new and updated documentation here – for example, how to use the licensing/activation features in your own scripts.

JSXGetURL 2024 Update


I’ve just rolled out JSXGetURL 1.x.x; it’s now stepping into the commercial arena.

JSXGetURL enhances ExtendScript to make it easy to access servers using httphttps, sftp… – e.g. to download assets from a remote server, straight from ExtendScript.

There is nothing to install – all you need to do is add a single //@include line to your script.

You can get more info and download JSXGetURL from the Rorohiko web site:

JSXGetURL works with any Adobe Creative Cloud application that has ExtendScript support – InDesign, InDesign Server, InCopy, Illustrator, Photoshop…

You can obtain individual JSXGetURL seats for US$49/year.

To purchase and activate, you need to use the License Manager which is included in the Helpers subfolder.

Create an account by clicking the New button, lower right-hand corner, and choose an unlock code.

Register the account, then use the Store window to access the JSXGetURL catalog entry.

Save and then email a purchase order to [email protected].

Payments are not handled automatically yet – you need to manually send the amount by way of PayPal, to recipient [email protected].

If you get stuck, please reach out to [email protected] or [email protected]!

JSXGetURL 0.1.0

Note 12-Feb-2024: This post is outdated. Read about the latest JSXGetURL here:

JSXGetURL enhances ExtendScript to make it easy to access servers using http, https, sftp… – e.g. to download assets from a remote server.

JSXGetURL is meant to work with any Adobe Creative Cloud application that has ExtendScript support – InDesign, InDesign Server, InCopy, Illustrator, Photoshop…

JSXGetURL is implemented as an ExtendScript DLL/framework, written in C/C++.

This DLL allows you to access URLs (including https: or ftp:) straight from ExtendScript.

There is nothing to install – all you need to do is //@include a .jsx file which then loads the DLL.

Sample code:

//@include "JSXGetURL/JSXGetURLLoader.jsx"
var getURL = JSXGetURL();

getURL.addRequestHeader("Accept: */*");
var s = getURL.get("") + "";


var headers = getURL.getResponseHeaders();

// Some random FTP file for testing

var f = new File("~/Desktop/sha512.sum");
var s = getURL.get("", f.fsName);

// Some zip file to test binary file download

var f = new File("~/Desktop/");
getURL.get("", f.fsName);

The previous 0.0.9 version was time-bombed for June 30, 2023 – which is 6 days from now, as of this writing.

Version 0.1.0 runs until Dec 31, 2023 and can be downloaded here:

I am still working on the licensing functionality in Tightener, which will ultimately be used to elevate JSXGetURL to a commercial product.

No firm decisions have been made yet, but come 2024, the licensing model for JSXGetURL will probably be a yearly recurring per-workstation fee, somewhere around US$30.

JSXGetURL versions for InDesign Server will be a fair bit more expensive.

Unlimited licenses will probably also be available, based on some yearly fee of a low multiple of US$1000.

All of this is still very much undecided – more later!