Browser Jack-in: is A web browser extension that let’s you inject a Scittle REPL server into the browser page. Chrome and Firefox supported. There’s a non-working extension built for Safari, and maybe someone will figure out how to make it work. I found myself injecting the Scittle REPL into a blog site I am working with, to make it convenient to experiment with the DOM from Calva. Then I thought it may be a useful browser extension. It’s a quite Borky borkdude little project since the extension is written using #squint with Reagami, and #babashka is used to package the extension and also by users when they jack the editor into the #scittle repl. #sci everywhere! 😃 • Repo with the extension distribution and instructions: https://github.com/PEZ/browser-jack-in Please star ⭐ • YouTube demo: https://youtu.be/aJ06tdIjdy0 Please like, subscribe and share around I’m curious if anyone else but me will find this useful. 😃
@pez I am running v0.0.2, using chrome extension . I tried it on a site i dont control, and when i hit the “connect” button I got this error:
scittle.nrepl.js:20 Connecting to '' violates the following Content Security Policy directive: "connect-src 'self' https: :* wss: data: blob:". The action has been blocked.
(anonymous) @ scittle.nrepl.js:20
(anonymous) @ scittle.nrepl.js:22
Any way around this?
I was able to successfully jack-in to a simple site I do control.@chromalchemy Probably this: https://github.com/PEZ/browser-jack-in/issues/1 I am working on a fix. Yet another WebSocket bridge, but seamless, inside the extension. I already have it working and just need to clean things up a bit. Enjoy this diagram for now. 😃
a bridge over troubled CSP directives
We will lay it down. 😃
I will relay me down
Fixed, @chromalchemy https://clojurians.slack.com/archives/C015AL9QYH1/p1767133563770819 At least for Chrome. I still can’t get Firefox to connect on http://github.com things. But at least I haven’t lost hope about that yet.
One more bridge. 😃 This seems to work in both Chrome and Firefox. Safari is still not playing along, but maybe some day we will figure that out too. Need to test this a bit with a rested brain, so no new release yet.
wooooo
love it
Amazing :)
Dude. This is awesome. I wonder if this can be used to grab OAuth tokens from the browser while developing backend services at the REPL. That would be super handy.
Within a prior workflow, I had to copy paste tokens from chrome dev tools into my REPL and I'd love to be done with that.
You can do that by sending an nREPL message from your JVM backend REPL to the front-end nREPL. e.g. using https://github.com/babashka/nrepl-client or any other nREPL stuff
This will go on my backlog 🙂 too many side projects in-flight. Need to narrow my focus.
Very cool. I’ve added Scittle to web pages i dont control, with Tampermonkey browser extension like this. https://blog.exupero.org/live-reloading-tampermonkey-scripts/ But I haven’t tried nrepl with it yet. This Calva integration looks very convenient!
Getting there. 😃 Lots of features still missing, but pattern based userscripts are there. Copilot hacked a party-mode for Github live and then I saved it as a userscript. Lots of Ux questions I am still not clear about, but anyway.
@pez It’s working now on the site I was trying!! 🙌 I was able to use Backseat Driver to hack a simple feature into an old entirprise Angular site. The only kink was that if I or the llm reloaded the page, the nrepl connection did not survive, and I would need to hit the “connect” button again. And the agent didnt really know about this, so it would hang and get confused. Is there a way to be resiliant to page reloads in the working Backseat Driver session?
If i want to package the code that was developed to share with others as a bespoke browser extension.. I could use Tampermonkey.. would i necessarily run into “bridge” issue you worked around? (or is that only for the dynamic repl access feature? ) Any reccomendations?
Please file an issue about the reconnect scenario. It will take some figuring. For now add instructions for the agent so that it understand the situation better.
I’m not sure what the tampermonkey question means. But I am pondering if we can turn this extension into something similar to tampermonkey.
With Tampermonkey I can share an extension feature by having the user download the Tampermonkey extension, and giving them the code to paste in. (minimal config) Maybe this extension can do something similar. Not repl-mode, but still injecting Scittle + cljs into arbitrary sites. Like a bookmarklet on steroids! Maybe it could pull code from github url. I should probably learn how to compile my own browser extensions though. (via shadow-cljs?)
The question is more a general Scittle question. If trying to just run scittle code, would I need the “bridge” workaround on a site I didnt control. Will try it and see if it works.
The bridging is for the repl connection. So your extension should be fine. You may need to patch scittle.js so that ot doesn’t do that eval. You can check the repo of this extension for how it does the patching.
Ok thanks. The code that was generated in Backseat Driver session, i was able to run in Tampermonkey, linking to cljs code in a gist, like this.
// ==UserScript==
// @name Linnworks Order Links
// @namespace
// @version 2025-12-31
// @description Add Bigcommmerce Links to open orders in Linnworks control panel
// @author Ryan
// @match
// @icon
// @require
// @grant none
// ==/UserScript==
(function () {
'use strict';
const url =
'';
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.text();
})
.then(cljsSource => {
// Evaluate the fetched ClojureScript
scittle.core.eval_string(cljsSource);
})
.catch(err => {
console.error('Failed to load or eval CLJS:', err);
alert(err.message);
});
})(); Now works in Safari, and all major browsers work even with strict Content Security Policies. https://clojurians.slack.com/archives/C015AL9QYH1/p1767302878655809
Nice!
Iicu, @chromalchemy , you can just add two lines of injected code to your tamper, and you’ll have a repl server. Just need to run the browser-nrepl server and connect Calva to that.
And now I had great use for this extension! I am managing a Jekyll site for my brother in law. There were some rendering issues I couldn’t quite figure out so I connected the Scittle repl to the page and told Copilot to inspect things. It evaluated some stuff and then told me what was wrong and how to fix it.
wow, that's a great example
Now available on the Chrome Web Store: https://chromewebstore.google.com/detail/bfcbpnmgefiblppimmoncoflmcejdbei
any web page is a stretch. A lot of public pages do not allow eval. Though in practice hopefully not too limiting. The main use case I had in mind is pages you have some control over.
SCI doesn’t require eval :)
scittle.js has globalThis["import"]=eval("(x) => import(x)"); But maybe I can get rid of that…
Hmm right
Not essential anyway
Great. I can jack in to YouTube pages now. 😃 New release in a jiffy.
I guess I could wrap this in a test that tests if eval works on the current page. https://github.com/babashka/scittle/blob/8bd775fd8759f6633456f7f38ca2bc413b497177/src/scittle/core.cljs#L71
https://clojurians.slack.com/archives/C015AL9QYH1/p1766956152862449
Let me know if you do that conditional eval, @borkdude, Then I can remove my patching, right?
I’ve created a channel for this now. And this is changing name to #epupp Not at all ready to announce yet. Too much API to figure out still.
Haha, I installed Tampermonkey to check it’s UI for userscripts. Turns out I have tried to make it dynamic before (as in some three years ago). 😃
I guess you are now building your own tampermonkey with scittle? :)
I haven’t exactly started building. But, yes, that’s what I am looking at. I get a bit stuck in analysis paralysis, so will need to figure out what a good incremental path looks like.