Please say hello to #epupp, a browser extension for scripting web pages with Clojure, using the REPL and/or with userscripts (Tampermonkey style). #scittle powered. Built with #squint. β’ https://github.com/PEZ/epupp β’ Template project for getting started and keeping Epupp available during your days: https://github.com/PEZ/my-epupp-hq You find Epupp on the browser extension stores for Chrome and Firefox. Firefox support is a bit lacking right now, and Safari even more. I intend to fix both gaps. Please let me know where things donβt work for you. My end game with Epupp is to hook more developers on Clojure. I think it really showcases the dynamic workflow of interactive programming. clojure-spin If Epupp reminds you of my Browser Jack-in project, it could be because it is that project that has now become Epupp. If you have Browser Jack-in installed, please update it, and you have Epupp.
https://clojurians.slack.com/archives/C0A8BC4TCH3/p1772967600254769
I am super curious about what use cases you have @0m0cha_slack! And please let me know what rough edges you encounter in porting, as well as when things may be smoother than with TM π
@lambeauxworks, is your use case for general web usage or some dev tooling/intranet stuff? Afaiut you can control windows and tabs using a userscript running in one tab that sends messages: β’ Orchestrating script -> bridge -> worker (aka background in Epupp) -> bridge -> controlled tab script (which can respond) And also: β’ Controlled tab script -> orchestrator script, the same way And you could build a UI for the orchestrator with userscripts. You would probably whitelist what urls can send what type of messages. The infra for this is in place in Epupp. I would consider puling a PR adding this functionality to Epupp, as it would expand the capabilities for dev tooling. Not committing to pulling, though π, it really depends. But if the add is to allow communication between tabs, and some messages for opening and closing tabs, I think it would actually fit quite well.
> Also, Iβm looking into how to keep the web socket connection perpetually open. Epupp tries to do this for as long as the tab stays open. There is some glitch that disconnects anyway. I havenβt been able to focus on fixing that yet. But you are talking about perpetually in some other sense?
Letβs continue this discussion in #epupp, @lambeauxworks π
Yeah this is for general web usage so I can tame my tabs. Going to interact with bookmarks too. I'll start a thread in #epupp for this. Thanks!
The main UIs of Epupp are two views + the REPL: 1. A popup letting you start REPLs for any number of tabs. The popup also lists your installed userscripts, and lets you run the scripts or disable/enable them for auto-run. 2. A devtoools panel letting you create and run scripts, or evaluate parts of them. (A very poor manβs Clojure editor.) 3. Connect your editor or AI harness to the REPL and just hack them pages.
Great idea! π
Hereβs the LinkedIn-announcement, would love help with reposting, commenting and such things. π β€οΈ β’ https://www.linkedin.com/feed/update/urn:li:activity:7434911786253832192/
People with Bluesky are super encourage to help me spread there as well. gratitude
YouTube: β’ https://www.youtube.com/watch?v=CuEWN5yYVa8&t=210s β’ https://www.youtube.com/watch?v=yU6rsjoR7HQ β’ https://www.youtube.com/@CalvaTV Please like and subscribe!
@pez dumb question but is this tampermonkey script but in cljs?
@0m0cha_slack thatβs a very good question! π There is some considerable overlap with Tampermonkey use cases. I describe it like so in the README: > Epupp has two modes of operation: > 1. Live REPL connection from your editor to the web page, letting you inspect and modify the page on the fly, with or without the assistance of an AI agent. > 2. Userscripts: https://www.tampermonkey.net/ style. Target all websites, or any subset of the webβs pages, with prepared scripts that modify or query information from the page. Userscripts can be configured to start before the page loads (`document-start`), when the DOM is ready but resources are still loading (`document-end`), or after everything has settled (`document-idle`). > The two form a powerful pair. The live REPL connection, while happily supporting one-off changes or data extractions, is also a very efficient and fun means to interactively develop userscripts. So the conceptual difference is the REPL, enabled by Clojure. In the comparison with Tampermonkey this impacts how you develop scripts. But there are also tons of use cases outside what TM can help with. Like just jacking in to the web page and look for data, remove or add elements in the dom, inspect styles, etc. I found myself adding Scittle and its repl to non-cljs apps I was building. Now I donβt need to. The Scittle-repl is there on all pages I ever visit. For an LLM Epupp can replace vendor MCP browser tools. The agent can use Epupp to answer its questions ad βseeβ the page, and tamper with it. Again, this gets extra relevant when your app is not built with CLJS.
I now also posted on HN about Epupp. But Iβm a HN noob so probably did it wrong.
I actually was messing with this a few days ago. I built it myself and installed it myself with additional perms, but I need the scripts to run in a worker, not a page (I want to control windows and tabs). Do you think that's feasible? I saw in your code you're bootstrapping a lot of functionality in the worker but that's not where the user's scripts run.
Also, I'm looking into how to keep the web socket connection perpetually open.
@pez thats awesome! Finally time to convert all my tampermonkey scripts π
[ANN] clj-yfinance β Yahoo Finance client for Clojure
Pure Clojure, no Python bridge, no API key, no external HTTP deps β just JDK 11+ and one runtime dependency (charred).
Prices, historical OHLCV, dividends, splits, ticker metadata (stable). Fundamentals, financial statements, analyst data, options chains (experimental, auto-authenticated).
Two-tier API: simple functions return data directly, verbose (`*`) variants return {:ok? :data :error} maps with structured error types. Parallel multi-ticker fetching with bounded concurrency.
First-class integration with tech.ml.dataset, tablecloth, Kindly/Clay, Parquet, DuckDB, and Noj β all opt-in.
com.github.clojure-finance/clj-yfinance {:mvn/version "0.1.5"}
GitHub: https://github.com/clojure-finance/clj-yfinance
Clojars: https://clojars.org/com.github.clojure-finance/clj-yfinance
https://github.com/alekseysotnikov/brepl-opencode-plugin for OpenCode - automatic Clojure syntax validation, auto-fix brackets, and REPL evaluation
https://github.com/seancorfield/deps-new v0.11.0 8629dcc - Create new projects for the Clojure CLI / deps.edn
clojure -Ttools install-latest :lib io.github.seancorfield/deps-new :as new
β’ Add clojure -X:codox to deps.edn so folks can generate API documentation (since cljdoc does not work with source releases on GitHub yet), see PR https://github.com/seancorfield/deps-new/pull/69 from @fmjrey.
β’ License is now retrieved from SPDX library, default EPL-1.0 can easily be changed with the :license/id option, see PR https://github.com/seancorfield/deps-new/pull/68 from @fmjrey.
β’ Update test.check to 1.1.3.
β’ Update tools.build to 0.10.12.
Follow-up in #deps-newhttps://github.com/cognitect/transit-java 1.1.401-alpha and https://github.com/cognitect/transit-clj 1.1.354-alpha which uses the new transit-java version. The biggest change is the move from msgpack to msgpack-core.
If you use transit with msgpack, please test and give feedback!
Clojurists Together is pleased to announce that we are accepting proposals for the Q2 2026 funding period. We'll be funding between 5-6 projects for up to $33K. More information about the funding, our recent survey, and https://www.clojuriststogether.org/news/call-for-proposals.-feb.-2026-survey/. Please consider submitting a proposal and good luck! Deadline March 19th.