Script Kit
Scripting isn't so bad y'all
Hey hey; I’m back again and today I wanna talk about Script Kit; I heard about it from Kent (in passing) whilst attending Epic Conf! In short, it’s primary purpose is to help developers automate tedious parts of their workflows with an easy to use scripting platform. All the scripts you write are in JS and TS (see ya later bash) and by virtue of making JS + TS first class citizens, you can do some real nifty things.
There are 4 reasons why I like Script Kit
and I’ll be elaborating on each. If
you’re too busy or too lazy to read the rest of the article (both of which are
fine reasons to not read anything), here’s the tldr:
- It allows you to automate tedious tasks with its nifty scripting features.
- It’s super fun to learn (if you’re into that kinda thing, which I am).
- It lowers the barrier to entry for scripting to include people who mostly us JS + TS and not things like bash or python.
- Your scripts can run in a GUI or the CLI; great because you can’t really drag and drop things in the CLI.
Automate All the Things
I once heard of a developer that would automate any task that he had to repeat more than twice in a given week (or something to that effect). This man wrote a script that would send out a text to his wife at 5:00 pm if he has not logged off his work computer, giving her some randomized excuse for why he was running late. I mean, I’m not saying I would do that but I’m not saying that I wouldn’t either — although my script would give her the honest reason (work has been chaotic and chances are something is most likely on fire 😆). While I don’t think I’d ever go as far as automating something if I had to do it more than twice in a week, there is something to be said about the spirit of automating tedious tasks that have to get done but aren’t necessarily a good use of our time!
In my case, whenever we do a release to production at work, I, like a lot of
folks, need to wait for our cache to invalidate before I can tell our QA
Engineers to kick off regression tests. Ideally, there would be some sort of
webhook that gets fired once the cache has been invalidated in our CI process
but, like a lot of companies, we’ve got bigger fish to fry than improving our CI
process and improving our developer experience. Prior to Script Kit
, I would
wait around for 10ish minutes and check the version manually because within that
10ish minutes, there was a pretty good chance (not an absolute chance) that the
version would update. Essentially the flow looked like the below:
However, it was equally likely that the version could update within one minute or within ten minutes so the ten minutes I listed above is the upper bound for the longest time estimate. My coworker Daniele didn’t like that we had to manually check and you can imagine why: one can’t enter flow state because they’ve got the looming release on their mind and if they do enter flow state, they might accidentally forget to notify folks that the production release is ready for testing — I’m guilty of the latter where the cache invalidates within 5 minutes but because I was busy writing code for another feature, I ended up not telling folks until 30ish minutes later 😅.
Daniele wrote up a quick node script (him and Copilot I presume) that would ping
the prod server for ten minutes and upon either timeout or successful version
change, he’d get a notification on his phone (and apple watch) about the status
of the change. I personally didn’t use his script — not because it wasn’t good
but because it seemed like a hassle to set up another alias on my bash profile
to execute some random node script. I’m lazy, I know 🙈. However, after
Epic Conf, I decided to give Script Kit
a try and
tweaked his version checker script for Script Kit
— which was pretty easy
since his code was already written in JS. Not only did his script work, but I
was also able to improve on it by removing some verbosity around fetch calls as
Script Kit
has nice little helpers like get
and open
available in the
runtime! You can see the example here:
// Name: Version pinger
// Author: Taran Bains
import "@johnlindquist/kit";
const url = await arg("Set URL:", []);
// I use ntfy to subscribe to messages
const topic = await arg("Set ntfy topic:", [""]);
async function sendNotify(msg: string) {
try {
await $`curl -d "${msg}" ntfy.sh/${topic}`;
} catch (error) {
console.error("Notification Error:", error.message);
}
}
let firstVersion = (await get(url))?.data?.version;
let lastVersion = firstVersion;
const startTime = Date.now();
const timeLimit = 10 * 60 * 1000;
async function checkVersionChange() {
try {
const response = await get(url);
const newVersion = response.data.version;
if (newVersion !== lastVersion) {
await sendNotify(`Version changed from ${lastVersion} to ${newVersion}`);
lastVersion = newVersion;
return false; // Stop checking after version change
}
return true; // Continue checking
} catch (error) {
console.error("Error fetching version:", error.message);
}
}
async function startPinging() {
const interval = setInterval(async () => {
if (Date.now() - startTime > timeLimit) {
clearInterval(interval);
await sendNotify("Timed out checking version");
} else {
const shouldContinue = await checkVersionChange();
// log the date in a human readable way
let prettyDate = new Date().toLocaleString();
console.log(
`${prettyDate} - Pinging ${url}. Old Version: ${firstVersion}`,
);
if (!shouldContinue) {
clearInterval(interval);
notify("Finished running script");
}
}
}, 3000);
}
startPinging();
I’ll be honest, after creating that first script, I got a little trigger happy and automated a few more tasks 😳. I automated opening up the URL for my deployed feature branches, I automated querying my open pull requests by Jira ticket number, and I automated opening the current running CI pipeline for specific feature branches — all these things were easy enough to do manually but they’d require me clicking around the browser a handful of times, which while not bad in and of itself, was definitely annoying.
Super Fun
If it isn’t abundantly clear to you by now, I absolutely love to learn (I also
curse like a sailor). So when I say it was fun to learn about scripting and
Script Kit
, you shouldn’t be surprised.
What made it fun, at least for me, was that I had found a new way to improve
upon my life! I’m constantly chasing progress and improvement — not because I’m
not content, I am, but because getting better is incredibly invigorating. That
feeling of being level 1 and getting to level 5, oof, it just hits different.
Also, as y’all know, I am a Sikh
and the world Sikh
in Punjabi literally
translates into to learn
, so there’s a certain fulfillment I feel when I learn
something new, irrespective of whether or not it’s related to faith.
ਵਿਦਿਆ ਵੀਚਾਰੀ ਤਾਂ ਪਰਉਪਕਾਰੀ ॥ Consider and contemplate upon knowledge, and you will become a benefactor to others.
-Guru Nanak Dev Ji
Plus, and I’ve said this before, variety is the spice of life! Try something new! Whether that’s scripting or trying to do a backflip, don’t allow yourself to fall into a rut — invoke that beginners mindset and what’s an easier way than, you know, trying something new 😃!
Scripting for All
Scripting felt like this magical far away skill reserved for linux system admins
who had a profound and intimate knowledge of bash
— not a full stack (but
mostly frontend) developer such as myself. It legitimately felt like it was
going to be way too much effort to get started learning how to script
properly because it required me to learn bash and other tools. And yes, I
know, I write TypeScript
for a living (script is in the name) and yes, I know,
tools like google/zx exist to help make
scripting easier, but still, it didn’t feel like the friction I was going to
face when getting started was going to be worth the eventual payoff. Unlike the
traditional meme developer, I don’t like to spend 6 hours of my life automating
a task that only takes me a minute to do.
Another thing about scripting and this is unrelated to anything really to do
with the tooling, but I didn’t feel empowered
to easily share my
scripts/automations with my coworkers. As I mentioned above, the whole reason I
didn’t want to use my coworkers node script is because I was lazy and not in
the right way (but I guess maybe in the right way, because if I wasn’t this kind
of lazy, then Scriptkit wouldn’t be a thing). But another reason is that I
didn’t want to have to deal with the whole “well it works on my machine and my
version of node” issue if I ever shared a script with a colleague. The whole
point of scripting was to help make my life easier — not make it harder by
having me answer and provide help to my colleagues when my tiny script to ping
our prod server failed to work for them 😥.
Look how easy and small the script to empty your trash is! After the set up of
Script Kit
, it’s as easy as running empty-trash
from the terminal to empty
my Mac’s trash (or Windows Recycle Bin)!
// Name: Empty Trash
// Author: Ricardo Gonçalves Bassete
import "@johnlindquist/kit"
import emptyTrash from 'empty-trash'
await emptyTrash()
A Gui + Terminal Interface
Alright, y’all know it, I know it, my family even knows it — I love the
terminal! I picked up neovim
2 years ago and haven’t looked back! However,
that isn’t to say that I don’t use GUIs — GUIs definitely have their place in
my toolbelt. GUIs are great… and that’s why it’s awesome that Script Kit
includes a GUI and a CLI for us to use.
One script I use pretty often is cloudinary upload. I already tried using it from the terminal and it doesn’t work 😅 since we don’t have a drag and drop interface for the terminal (at least not one that I’m aware of). That’s why it’s super great to have the GUI — if there are certain elements that require a GUI, we get that.
However, the chrome-bookmark script that I wrote can run in the terminal (it has no dependency on GUI elements) so I lovingly use it in the terminal. Check it out when you get a chance! Isn’t that so cool; You get the best of both worlds!
Closing Thoughts
Okay so, automation is great. Script Kit is great. However, if you’re not careful and don’t understand the inherent risks of scripting, hold off and ask for help! We don’t want to be willy nilly installing packages to our machines and executing the code.
Check it out and publish your scripts to the community; if you have any cool scripts that you’ve written, send them my way!