Paul Hammant's Blog: Starting RexxJS
Repo: github.com/RexxJS/RexxJS/
Yes, Mike Cowlishaw’s interpreted language from 1979 that’s line-centric, starts indexes at 1 not 0, where vars are “weak” & global dominant, which isn’t OO or functional, and has a dangerous “eval” equivalent. Yes, I do have reservations, but I wanted an in-the-DOM interpreted “glue language” that also works on the command line (mac, win and lin). I wanted it because have unreleased agentic-ai applications that will be better for having such a language for a use case, and I’m trying to work out whether this is compatible with model-context-protocols, alien to them, competitive, enabling of, etc. It could all be folly of course. In short, a familiar to me language that included a “Control Bus” that could work at distance was my goal.
RexxJS
RexxJS’s innovation: It combines ARexx’s lightweight string-based messaging with modern browser capabilities (iframes, workers, JSON-RPC - via that postMessage see below), plus adds progress monitoring and fault tolerance through a CHECKPOINT system. That’s one run target (pure DOM; connects iFrames). The other is on the command line via NodeJS. Building this I worked toward the iFrame/postMessage goal (with integration tests, and pure specs) and then back to other language and library and tooling ecosystem. It’s all in JavaScript obviously. Unit tests of Rexx can be via JavaScript instantiating the Rexx interpreter and parser, too. Halfway through I thought it was time for tests in Rexx itself, so there’s a test framework and very experimental expectations capability - those are dogfood tests and there will be more and more of them. At some stage I could be rash and migrate much more of the jest tests to rexx tests, but I’m sceptical about my ability to sort out an invitable change-one-line that breaks 3000 highly derived tests. Anyway, this is alpha quality right now - don’t put apps live using it. Of course, ClaudeCode, JulesAgent, OpenAI (via the excellent AiderChat) and Gemini-cli have helped a lot.
Agentic AI concerns
- Will this have a state synchronization complexity? ARexx worked because AmigaOS applications shared memory space. With distributed nodes, we’ll need robust conflict resolution when scripts modify shared context concurrently. How will this handle split-brain scenarios?
- Security surface - Self-sending executable code is possible, powerful but risky. That’s more for something with a shell at the other rather than APIs of some sort. MCP typically uses structured message passing rather than arbitrary code execution. For DOM execution at least I already have it working inside iframe sandboxes.
- Security surface 2 - ARexx ports in 2025 are a hackers dream. Generally available ones for an app would need tokens, cryptographic signature tools, declarative privilege request meta-data.
- Protocol overhead - ARexx’s beauty was its simplicity. Modern LLM interactions involve complex token management, conversation history, and tool calling. Can RexxJS’s scripting model be expressive enough without becoming any more verbose than it already is?
- Testing challenges - distributed systems with progresive state changes are notoriously hard to test deterministically. new classes of integration tests may be needed. Possibly also property-based testing for the coordination logic.
Strengths, otherwise, include the bidirectional progressive reporting which “could” handle streaming responses naturally, (critical for LLM interactions), running in both DOM and CLI gives this flexibility that most MCP implementations lack BUT the ADDRESS fu for command-line has not been built yet.
Rexx history that influenced me
The RexxJS “Control Bus” draws inspiration from ARexx’s revolutionary ADDRESS/PORT model on the Amiga home computer by Commodore, which pioneered lightweight inter-application scripting. 1987 ARexx allowed any application to expose a named “port” that could receive text commands from Rexx scripts, enabling system-wide automation through simple string messaging. William Hawes was the author of ARexx outside Commodore, but it was so good it was subsequently bundled with the OS in 1990/91.
Before ARexx / Prior Art
Of course just because I thought ARexx’s address system was revolutionary did not mean it was without precedent.
IBM Rexx (mainframe / VM CMS exec)
ADDRESS already existed before ARexx — used to send commands to different environments (ADDRESS TSO, ADDRESS ISPEXEC, etc.). Lots of concepts that did not need peer within modern client/server unix-land software engineering.
ARexx extended this idea to user applications and arbitrary “ports.” That was without a TCP/IP subsystem for the Amiga in 1987.
Unix shell + stdin/out pipes (1970s)
Not the same, but the philosophy is similar: treat text as the lingua franca, and let a shell script send commands and collect results. What ARexx innovated was the naming of live applications as endpoints rather than just processes and pipes.
Forth message passing (early 80s)
Forth systems often had message/event words for controlling devices. Not system-wide like ARexx ports, but conceptually related.
Tcl’s send (1990s)
Direct analogue allowing Tcl interpreters to send strings to named targets
Smalltalk image messaging
Everything is a message, but it’s intra-image, not inter-application. However, some Smalltalks apparently had “workspace to morphic world” messaging similar to ARexx’s openness.
Modern Analogues
- AppleScript (1993) - Similar concept but heavier (object models + AppleEvents vs simple strings)
- window.postMessage (2008) - Browser API that essentially recreates ARexx ports for web contexts (my key target)
- Comlink (Google lib, ~2017) - a library for this exact things, that one guesses their own web apps use. “Call methods on remote iframes/workers as if local.” it is said. It is strongly typed (Promises), and less string-oriented.
- WebAssembly runtimes with messaging - Wasm modules talking to host via postMessage. Not standardized for cross-iframe yet, but evolving.
- Electron IPC (2010’s; Node <-> Renderer). Very similar to ARexx ports: each renderer process is a “port” you can send strings to. Structured messages, not always text-based, but philosophically close.
Innovation around IPC keeps happening too. github.com/eclipse-iceoryx/iceoryx2 - “Eclipse iceoryx2 true zero-copy inter-process-communication with a Rust core” - is current, and make me remember those days of the Amiga with an ARexx script controlling multiple full apps.
Other languages that could implement the same iframe/postMessage thing
Languages with potential to emulate ARexx ADDRESS/PORT:
- Lisp/Scheme: (BiwaScheme - current, LispyScript - paused): Very easy to extend the environment with primitives. You could define (send “frame1” “(do-something)”). Since Lisp interpreters already treat strings as code, it maps almost 1:1 to ARexx’s “send command string”.
- Lua: (Fengari - status?): Lua has a built-in concept of coroutines and message loops. Adding postMessage/onmessage as primitives would make iframe scripting natural. You could write something like address(“frame1”, “command”).
- Forth: (tiny Forths in JS): Forth is literally token streaming. Easy to define PORT words that wrap postMessage. Minimal, but you may lose ARexx-style structured results unless you build a return protocol.
- Python (well, a subset of): Skulpt and Brython are Python interpreters in JavaScript. Pyodide too, which I am also delegating to in an “extra”.
- Blasts from the past: Several small BASIC-in-JS interpreters exist (TinyBASIC.js .. current link?). Tau Prolog (paused?) is a Prolog interpreter written in JS.
All of those are more advanced languages than Rexx itself. I need help with this. It is likely only to be interesting to people with prior Rexx and more recent JavaScript framework/library/tool-building experience.
Lastly I’m likely to continue to refer to REXX as Rexx.