Hammerspoon maintainer here - I'm enjoying reading all the comments, and hoping that everyone isn't going to be annoyed that I'm mostly working on a v2 atm, which switches from Lua to JavaScript :D
Hammerspoon is basically my only reason to write Lua, a language which I really like. I am sure JavaScript is a more pragmatic choice but I will be slightly saddened by it regardless.
Thank you for your work on Hammerspoon! I’ve been using it for years.
Would you mind elaborating on your vision for v2? Was there a certain limitation in the previous architecture that you’re trying to avoid this time around? Was there something in particular that drew you to choosing JavaScript for this version?
The limitation is entirely on the developer side - for years now there have only really been three of us working on Hammerspoon with any regularity, and that has been significantly dwindling down to mostly just me and Chris Hocking.
Honestly, in 2026, I do not want to be maintaining a 100k line Objective C program.
So, my current experimentation with a v2 is to see how easily I can catch up with where v1 is, just using Swift and JavaScriptCore.
There are lots of things about the Lua APIs that I don't like, and I'm addressing some of those as I go, but I'm currently in a phase where I'm targeting parity with everything I need for my v1 config, at which point I can cut over to running v2 and then see how things are looking and what can be refined/reworked.
Well, I guess the motivation (use a more easily integrated extension language) makes sense but ugh, Javascript is a dirty sack of sewage.
I'd take a minor quibble with one of the Reddit commentators:
> "Lua is a language that was built for people that are not programmers, and Hammerspoon (or at least building it's extensions) is targeted specifically at programmers."
Hammerspoon[0] isn't targeted at programmers because it's abstracting hard things (interfacing with macOS system libraries, etc.) into easier ones (the Lua spoons) where accessibility to non-programmers is surely a goal.
[0] I'm excluding extensions because the included spoons cover many scenarios people would be interesting in using and, to be honest, building "extensions" to something as tricky as Hammerspoon would be beyond many programmers[1], never mind non-programmers.
[1] I'm reasonably experienced and pretty fast at the "huh? <-> search <-> experiment <-> kludge <-> test <-> passable code" cycle even with completely new technologies and I definitely wouldn't be keen on attempting a Hammerspoon extension.
I'll happily agree that JavaScript is not a very nice language, but to be honest, I don't think Lua is a very nice language either. It's easy to embed in C though, which is why we were able to do all of the things that Hammerspoon does.
Where JS massively wins here, to my mind, is that there is so much tooling available for it, to the point that I'm already not actually writing my v2 config in JS at all, I'm writing it in TypeScript and compiling it to JS.
Firstly, thanks for all the Hammerspoon work - it is a marvellous thing (and I'd love Apple to support something like it as an extension to OSA.)
> Where JS massively wins here, to my mind, is that there is so much tooling available for it
Yeah, I can see that being a big win for development and people already invested in the JS ecosystem.
(I'll stick with Hammerspoon v1 until it breaks and then figure something else out because it'll be a cold day in hell before I subject myself to JS/Node/Typescript again. The trauma runs deep and wide.)
> I'm already not actually writing my v2 config in JS at all, I'm writing it in TypeScript
Will give v2 a go with `lua2js`[0] transliteration and see if that's workable.
Well, I have been a long user of Hammerspoon, and Lua, so thanks for the great app, it made a difference for me for a long time .. would be happy to hear why, but don’t feel obliged, the switch to JS over Lua, but anyway, thanks again!
The simple answer is not having to maintain a really complicated language bridge anymore.
The more complex answer is that Hammerspoon is currently about 100k lines of Objective C, and none of us really want to work on it anymore when Swift is the much nicer place to be doing macOS development.
Technically we could slowly convert in-place from ObjC to Swift, but there will always be a need for "LuaSkin", the bridging code we've accumulated over the last 13+ years, and rewriting that in Swift would be significantly complicated.
JavaScript, however, is already bridged for us because WebKit needs it.
Really there's very little that v2 might do, that v1 couldn't. This is almost all about me not wanting to maintain a big pile of Objective C and Lua anymore. I want to be working in Swift, and rather than maintain our own type bridging to/from Lua, we can get that for free from Apple's JavaScriptCore framework.
Beyond my enjoyment/productivity on the developer side though, I think v2 will be a big boost to user enjoyment/productivity, mostly because they'll be able to get much nicer IDE integrations for their config file, and be able to do things like write their config in TypeScript.
Not really any more or less than in v1 - which is to say that it's possible to execute those scripts from Hammerspoon, but there's no rich bridging between them.
Mostly the former, but the latter is also attractive. Once I got the basic core working and a couple of modules implemented, I had Claude build me a script that extracts type information and method signatures, to automatically build a TypeScript definition file.
I have a feeling that letting people do what Hammerspoon can do, but in a TypeScript environment that they're much more likely to know, than Lua, will be huge for the project.
Cljs setup for this case probably would require a bit of scaffolding. While using https://github.com/squint-cljs/squint perhaps would be pretty straightforward. Albeit you're gonna lose the type-safety guarantees - Clojure is strongly typed, and Clojurescript sometimes emits safer code than Typescript does (TS removes all the type-related data from the compiled .js code, while Cljs keeps the runtime checks in place). Squint afaik is much closer to Javascript in that respect.
Have you though of some more modern language agnostic solution like wasm plugins users could write in anything, with the help of typed languages if they like? Or is that not feasible for a scripting project like this?
I expect that is possible, but the specific choice of JavaScript is because Apple ships a framework that bridges types very nicely between native and JS. It's used by WebKit, so it works really well and is very unlikely to disappear.
That means the core of Hammerspoon goes from being incredibly complicated, to really just a protocol conformance.
Things programmers believe. It's interesting how some knowledge fundamentally assumed by default. For whatever reasons, the notion is widespread. You're a programmer? Therefore you must know JS, SQL, Bash and Python. In practice, what I've found after decades working with various teams - most programmers have pretty inadequate knowledge of any of these things.
Or burn them in a furnace. Pretty much any way you can think of to accomplish something on earth, is vastly cheaper, easier, and faster than doing it in space.
Space doesn't really change it though because the effective bandwidth between nodes is reduced by the overall size of the network and how much data they need to relay between each other.
When you absolutely, positively, must find a nice thing to say about Tesla, yes, their 11% revenue decline - their second year in a row of revenue decline, was indeed slightly less bad than analysts expected...
11% revenue decline during a year where the global EV market grew 20% [0]. That's just abysmal, especially for a company which was once the only game in town if you wanted a "serious" EV.
I guess in this case it’s the Apple that dominated an emerging market, then fumbled it and completely lost the market to the IBM PC and ended up as a bit player for the next two decades.
The experience is what you make of it. Personally I'm quite enjoying using AI as a way to generate code I can disagree with and refactor into what I want.