scittle 2025-08-23

Request for comments: https://github.com/timothypratley/scittle-kitchen Precompiled plugins to make the ClojureScript ecosystem more accessible from Scittle, and help adoption of Scittle.

👀 2

This is great and as a scittle consumer I love the idea of access to more plugins. My main concern would be the centralizing aspect which feels a bit like clojars. In general going through a new central repository has the same issues as adding a plugin to scittle itself. My personal preference would be what you mentioned in "Alternatives to consider": > • Publishing to NPM or CDN. Providing a nice simple tool for enabling people to compile plugins and then npm publish them seems like a tighter integration with the existing JS ecosystem and doesn't depend on people merging PRs etc. The existing infrastructure of npm is mature and doesn't need any work from us. Anybody can then just publish a Scittle plugin by themselves. Thanks for putting this together - great idea! 🙏

In the current version of josh I added a search function which checks GitHub for projects tagged with scittle-template. A similar kind of thing could be built to search GitHub and npm for projects tagged with scittle-plugin which would be a reasonably decentralized discovery/search mechanism for scittle plugins, and later somebody could build a website aggregating that info. @chaos has also done some similar work with scittlets (though I don't know where the templates are stored in that case).

Just checked the scittlets repository and it seems you update catalog.json and then send a PR to add a new template.

Thanks 🤔 I like what you are saying and also don't understand all of it. I'm glad you are thinking about this, and I'd like to learn more about it 😄

I think it means there is an npm installed based existing solution (https://socket.dev/npm/package/scittlets) which already solves this, and/or we might be able to leverage that to make some sort of automated build process (rather than expecting people to contribute to scittle-kitchen). Which makes sense to me.

i.e. we don't need scittle-kitchen at all

What I'm hoping is that scittlets would be deployed somewhere I can use it (maybe it already is) through jsdeliver or something

(to be more precise I mean in a way that I can add a <script src="....">, rather than doing an npx install etc)

Is that what you are thinking about? or am i misunderstanding?

Sorry, I'm confusing things. 😅 I think we do need a new tool. Scittlets doesn't do what you're describing. I think the focus of scittle-kitchen could be the actual compilation part - helping to compile things to plugins without needing such a tight integration with scittle itself (unless I have misunderstood this part from the README). > a way that I can add a <script src="....">, rather than doing an npx install etc 100% aligned with this goal.

For me the ideal solution would look like this: • Some tooling (scittle-kitchen?) to make scittle plugins easier to compile without adding them to the scittle source itself. • Some documentation for how to publish a newly compiled plugin to npm/github in such a way that it is then available via CDNs and people can just add a script tag to load it.

I think it would be good to avoid a situation where a newly compiled scittle plugin needs a PR to be merged before it goes up on CDNs and I think npm/GH is a good way to accomplish that.

😄 Great! Yes I agree. As I understand it, in order to be "activatable", scittle itself needs to know a little bit about the plugin. So it can't be completely decentralized. A variant of scittle (perhaps calling it scittle-kitchen) would need to know about the plugins. All that to say I think there does need to be a "centralized build process that publishes to <wherever>" but I really like the idea of searching for templates etc. Possibly we could have a mix of (if your cljs project does this it will be picked up, and "add it here" if you don't want to do that) just a though 🤷

👍 1

Ah yes I've just remembered the constraint that the plugins need to be synchronized to a particular version of Scittle.

Maybe we should be thinking about ways for plugins to tell scittle about themselves instead, but I don't know anything about that (I just assume there must be a reason it's hard).

Anyway sorry for confusing things. Making it easier to build and distribute plugins sounds great!

Thanks, you didn't confuse it, and added important information. I hope to ask you more questions about it soon.

I found the scittlets github (I think) https://github.com/ikappaki/scittlets "This repository offers the scaffolding needed to develop, test, showcase, and publish scittlets, served via https://www.jsdelivr.com/ from this GitHub repository." Sounds to me like it at least intends to publish the plugins, but the example https://github.com/ikappaki/scittlets/blob/main/examples/mermaid/mermaid_demo.html confuses me because it pulls in standard scittle and a local mermaid.cljs 🤯

Oh I think I got it; Scittlets is more about hey you could make a cljs wrapper for a JS lib like this, Whereas when you run into say Datascript or some large CLJS dependency, it's not feasible to load all the CLJC files you need, so having it compiled as a plugin is useful.

So it's more for dynamically including .cljs files via script tags than a compiled plugin?

I think that's the purpose of scittlets yes

Can you tell me more about cljs-josh search feature?

Or point me where I should look?

Oh it appears I haven't pushed the commits yet. Basically it works like this:

$ ./josh.cljs --help
Usage: josh [command] [options]

Commands:
  (no command)         Starts the webserver.
  init                 Initializes a new project.
  templates [search]   Lists available templates.
  install <owner/repo> Installs a template from GitHub.

Options:
  -d, --dir DIR    ./    Path to dir to serve.
  -p, --port PORT  8000  Webserver port number.
  -h, --help
      --prod             Disable live-reloading and nREPL for production.
$ ./josh.cljs templates
Fetching repositories with the 'scittle-template' tag.

Found 4 repositories:

- chr15m/scittle-template-basic
  Basic Scittle ClojureScript template

- chr15m/scittle-template-2d-game
  Scittle ClojureScript starter template for 2d games using reagent

- chr15m/scittle-template-serviceworker
  Service worker in Scittle ClojureScript

- chr15m/clojurescript-tiny-slides
  Minimal presentation slides for ClojureScript
$ ./josh.cljs templates game
Fetching repositories with the 'scittle-template' tag matching 'game'.

Found 1 repositories:

- chr15m/scittle-template-2d-game
  Scittle ClojureScript starter template for 2d games using reagent
Let me put this on a branch and push so you can see the code.

Oh sweet, that's nice 😄

Do you have to have an organization name? Could you just register the bare package like npm i scittle-kitchen?

I don't know 😕 I've never registered an npm before laughcry I was hoping you would tell me the best thing to do.

😅 1

it appears that all options are possible: an unscoped unique name, a scoped to user name, or a scoped to org name.

Many thanks for this, @timothypratley @chris358. Indeed the fork we used at scicloj/clay was just a temporary solution. Personally I need to relearn the landscape of scittle-related projects, but based on my experience about 10 months ago, some unified approach to handle plugins seems to be important. This need has been one of the main obstacles for me in enjoying the full potential of Scittle. I'll try to learn scittle-kitchen to understand better.

Maybe the idea of plugins and their limitations isn't clear. The scittle build supports plugins so companies and/or projects can add their own custom stuff. Nbb has a similar mechanism. Logseq has their own build of nbb for scripting which includes datascript and logseq. Babashka also has a similar mechanism although I don't know anyone who produces their own bb flavor nowadays (maybe because pods can brigde that gap). The "normal" scittle build contains only plugins I deem widely applicable. I keep this limited because compile times will explode if I add all the libraries from the CLJS ecosystem. And once things are added I can't remove them anymore (backward compatibility). If your company (or project or organization) wants to have their own flavor of scittle with their own set of libraries added, anyone can do so via the plugin system. Plugins don't need to live inside scittle and also don't have to be maintained by me (some are), it's a classpath thing. So maybe I don't understand scittle-kitchen. What problem does it solve?

Thanks, I'm trying to embrace that philosophy and compile a wider set of libraries in a separate build that tracks scittle. scittle-kitchen doesn't solve any problems (I can't get it to work due to my lack of understanding) but my hope is that in the future I can do something like this: <script src="somewhere/scittle-kitchen.js"> <script src="somewhere/scittle.dataspex.js"> and then use dataspex. My main hope is that having more precompiled builds available will help people trying things. That's what I really love about scittle, is being able to just try things without using a build tool.

If that works, I also hope that it will provide a path for other people like me who feel stuck when it comes to trying to get hold of a clojurescript library, because they don't know how to make a build .

👍 2

makes sense to me

yep makes sense. build all the things ;)

😄 hahahaha right 🧹 I really appreciate your guidance. What I plan to look into today is learning the options for compilation better. So far I've been trying to replicate the scittle/plugins/demo folder into scittle/plugins/kitchen but it occurs to me that was a huge mistake. I think your comment about "it's a classpath thing" means that what I should be doing is just a normal deps dependency on scittle where I refer and call build/build , and it will somehow find the scittle_plugin.edn files -- 🤔 I'll give that a try next.

yes. just add the plugins as dependencies on scittle with a deps/root that should work I hope

👍 1

what's the appeal of dataspex for scittle btw? can you explain it? I understand replicant in the sense of "simpler reagent without react" kind of things. but what is dataspex for exactly?

we can do that in another thread if you'd like

I don't know because I've never tried it! laughcry I think that it can potentially be a very nice way to display data structures in Clay notebooks. That's the appeal to me. I like the demo video

It seems dataspex is much more than what I want to use it for, but I'm primarily just interested in a way to show data in a blog post for example.

I hope it works well under advanced compilation. cljs-devtools doesn't

and you don't need a browser plugin for it? that part confused me too

I probably should watch the video

They do recommend using the browser plugin yes, and it can connect to REPL and fancy stuff... but I'm just interested in using it as a library for visualizing data.

More progress: https://timothypratley.github.io/scittle-kitchen/ lists all the plugins. Note the presence of mathbox, emmy, and tmdjs (community contributed plugins). All of these have more recent versions than scicloj/scittle. The [README](https://github.com/timothypratley/scittle-kitchen) has been updated with more information about the build details. I think now would be a great time to get some more feedback and verify if this is going in the right direction.

👏 1

Great. I hope to look a bit during the coming day.

This is awesome! I indeed want grammers of graphics, but general purpose, not just dataviz. Very inspiring.

@chromalchemy have you tinkered with SVG in hiccup? That's pretty much a graphics DSL.

What’s your favorite CLJS lib to try next?
@timothypratley Specter might bee cool as a general purpose data utility lib. But I think it relies heavily on macros, which maybe complicates things. But it was made to work in BB, so..? https://github.com/redplanetlabs/specter

Interesting... I've never tried using macros in Scittle before think_beret so I'm not sure what to expect. I'll look into it more next week 😄

Here's a demo of using Instaparse as a Scittle Kitchen plugin: https://clojurecivitas.github.io/instaparse/grammar_of_physics/rigid_body.html 🎳 babashka cljs It was a fun experience to write it as a cljs include script with no compilation.

🙌 3

I normally just pick a unique name and register it, but I can see the value in an org prefix.

A little bit. Maybe can build something higher level off that.

While scittle.dataspex.js was built, notably it does not work (for me).

scittle.js:639 ----- Scittle error ------------------------------
scittle.js:639 Message:  Could not find namespace: dataspex.core.
scittle.js:639 Location: scittle-tag-2:3:1
scittle.js:639 ----- Context ------------------------------------
1  (def xx {:foo [1 2 3]})
2  (require '[reagent.core :as r])
3  (require '[dataspex.core :as dataspex])
   ^--- Could not find namespace: dataspex.core.
4   #_ (dataspex/inspect xx)
5   (println :HELLO)
Uncaught #error {:message "Could not find namespace: dataspex.core.", :data {:type :sci/error, :line 3, :column 1, :message "Could not find namespace: dataspex.core.", :sci.impl/callstack #object[cljs.core.Volatile {:val ({:line 3, :column 1, :ns #object[El user], :file "scittle-tag-2", :sci.impl/f-meta nil} {:line 3, :column 1, :ns #object[El user], :file "scittle-tag-2", :sci.impl/f-meta nil})}], :file "scittle-tag-2"}, :cause #object[Error Error: Could not find namespace: dataspex.core.]}
scittle.dataspex is an "official plugin" in that it is part of the scittle source codebase, but is not published as an artifact (AFAIK). @jeroenvandijk maybe you could help (I saw you tagged on the announcement)? I'm trying to understand if I built it wrong. Is there a working example in the wild?

@timothypratley hi, cool thing you are trying with scittle -kitchen. I'm using scittle.dataspex in a private build and it works, but it is a bit tricky. It supports inspecting datascript connections, but therefore has a datascript dependency. So you need to include the scittle datascript plugin as well, and require this plugin before requiring dataspex. Now I think about it, maybe datascript could be an explicit dependency of the dataspex plugin to avoid this hard dependency on the scittle datascript plugin (sounds counter intuitive maybe)

amazing, it works for me!!!

Thank you so much, that's great 😄

❤️ 1

it doesn't sound right to me that datascript is a dependency of the dataspex scittle plugin ;)

Yeah I am not sure how it would work otherwise, unless you bundle them together. But I agree it is not pretty

Oh wait maybe you are ok with the dep on scittle.datascript but not on the datascript lib?

It would be nice if it would work like how it works in clojure; nothing if datascript is not there. But with clojurescripts advanced compilation this is a bit different (I think)

Calling dataspex/inspect didn't appear to do anything (no error, nothing on the webpage)... should I be expecting something?

probably I don't want inspect but to attach it to a page element. I'll dig deeper. Probably inspect is just talking to the browser plugin (which I don't have).

I'm not near a computer to test now. At least the inspection of the datascript connection should work (assuming the dataspex browser extension is installed properly ). I've tested it with the replicant Kanban app that I ported to scittle

👍 that makes sense. Just to clarify, I'm not using the browser extension. Looking closer what I need to call to show it on a HTML page is dataspex.hiccup/render-inline (I think). The dataspex.hiccup ns is not exported (yet) but now I know where to look (in the plugin/dataspex and can try adding it and rebuilding.

@borkdude could you clarify "it doesn't sound right to me that datascript is a dependency of the dataspex scittle plugin ;)" There are several dependencies it seems: 1. dataspex project depends on datascript project 2. dataspex.scittle :depends-on #{:scittle :scittle.datascript} 3. My HTML page needs to load scittle.js then scittle.datascript.js, then scittle.dataspex.js 4. Code require statements I think you are talking about (2), but I'm not sure what the alternative is? Is it possible to remove :scittle.datascript from the scittle_plugin.edn and something good will happen? Or are you just observing that it seems like a heavy dependency?

I'm asking because I'm curious about the role of :depends-on It seems that it controls what goes into a module definition, so by removing :scittle.datascript I think that means more stuff would go into scittle.dataspex.js but that would be totally fine. So somewhat counter-intuitively it might be better to remove the :depends-on relationship?

I haven't looked at the code but dataspex as a library doesn't depend on datascript I presume? if so, then the plugin should not either

o wait, it does depend on datascript

yes, then it all makes sense

why does a visualization tool depend on datascript I wonder, but ok

I guess it's because of this one: https://github.com/cjohansen/dataspex/blob/7b1ec1147f2a517b3a475a53f1f86ae9f147b9f3/src/dataspex/datascript.cljc#L4 what I would do in this case is split scittle.dataspex into scittle.dataspex and scittle.dataspex.datacript and only the latter would depend on the scittle.datascript plugin

👍 1

👍 got it.

just noting that (at least some parts of) dataspex also depends on replicant, but there is no :depends-on #{:scittle.replicant} relationship think_beret

More progress... this show dataspex being loaded inside a HTML page...

🙌 1

using a custom build of scittle.dataspex.js

I added *<http://thi.ng/geom*|thi.ng/geom*> as a plugin scittle.geom.js and it works!!!???!!! I'm kind of amazed. All I did was add to the scittle-kitchen plugin-templates.edn ``` :geom {:namespaces [thi.ng.geom.viz.core thi.ng.geom.svg.core thi.ng.geom.vector thi.ng.color.core thi.ng.math.core] :deps {<http://thi.ng/geom|thi.ng/geom> {:mvn/version "1.0.1"}}}``` And it was included in the build. Screenshot of using scittle.geom.js

🙏 1

TLDR, I think this template approach really simplifies adding libraries

One thing I wonder about is why not add all the namespaces? i.e.: inspect the library to generate the list of namespaces. That would avoid the situation where a namespace exists but was not exposed (maybe it has a downside though).

Currently the full build takes 3m 37s as a Github action (I'm fine with it getting longer with more plugins) and for local testing I added an option to just build one (or a selected subset) of plugins which has made it quicker to iterate on. (see https://github.com/thi-ng/geom/blob/feature/no-org/org/examples/viz/demos.org) for more geom examples (from the official docs), and https://timothypratley.github.io/scittle-kitchen/ shows the link to https://timothypratley.github.io/scittle-kitchen/js/scittle.geom.js

What's your favorite CLJS lib to try next?

just noting that (at least some parts of) dataspex also depends on replicant, but there is no :depends-on #{:scittle.replicant} relationship
That is very suspicious. I think that can be enforced by adding replicant.core etc as entries here: https://github.com/babashka/scittle/blob/f2517187bff0c3cd13fabaf5d2ce7c66128e31ff/shadow-cljs.edn#L31

> I added http://thi.ng/geom as a plugin scittle.geom.js and it works!!!???!!! I'm kind of amazed. > > All I did was add to the scittle-kitchen plugin-templates.edn >

:geom {:namespaces [thi.ng.geom.viz.core
>                      thi.ng.geom.svg.core
>                      thi.ng.geom.vector
>                      thi.ng.color.core
>                      thi.ng.math.core]
>         :deps { {:mvn/version "1.0.1"}}}
I don't understand this. How do you use thing/geom in your code then?

About dataspex, I just want to note that there is a difference in the kind of dependency. Dataspex has a strict dependency on datascript, meaning it will not recognize a datascript connection created outside of dataspex if they are not compiled via the same process. And will therefore not work correctly (for datscript). The replicant dependency however is of a supporting nature. It doesn't interact with replicant instances outside of dataspex. So the benefit of extracting it would be compilation size maybe, but it would also complicate things. Because now you need to know about the internals of dataspex and have to include scittle.replicant and you need to include it before dataspex. So unless scittle can resolve these dependencies for us somehow, extracting internal dependencies like this might actually make things harder to use

I'm actually thinking a dependency resolver could be a good addition to scittle. I have already run into it trying to use some npm libs. With clojurescipt shadowcljs does this for you but with scittle you need to do this manually

• plugins are always compiled together, they never work together if you compile them in different builds • do you mean adding scittle.dataspex.datascript.js makes things harder to use? I don't agree on that, adding an extra script tag is a small price to pay, it's how scittle works anyway

• dataspex has a hard dependency on replicant, it doesn't work without it. • only the dataspex.datascript namespace doesn't work without datascript

dependency resolver: do you mean, when you include dataspex plugin it will automatically add the replicant plugin? I've thought about something like that

what happens now when you compile the dataspex plugin is that it will move replicant to the dataspex plugin. so the replicant plugin won't work without the dataspex plugin, is my expectation. this is wrong. they should be split and dataspex should depend on replicant

Hmmm now you mention it, I haven't tried dataspex without replicant. Maybe it wouldn't work. Ok let me test things later a bit. Most likely you are right and I am wrong Yeah regarding the dependency resolver. It would be nice if, in this case, it would add replicant and datascript automatically and also put them in the right order. I can imagine this could be both a client side thing and/or a (one time) server side thing, e.g. for static builds. I have a gist somewhere for npm libraries using the info from jsdelivr, maybe it could be the same or similar. If scittle packages are pushed to npm with right dep info, maybe this would already work

the main point is: replicant now won't work without dataspex (I think) which is plain wrong

so try replicant without adding dataspex when also compiling the dataspex plugin

Oh I have used replicant without dataspex I'm pretty sure (in my custom build) But the other way around not sure.

anyway: if scittle moved to sci.async then we could just dynamically import the dependencies from jsdelivr when a certain namespace is required

😍 1

which is of course much nicer but also requires some breakage I think

I use the same mechanism in nbb

That sounds great. I'm assuming that most of us are still ok with breakage ATM for these kind of improvements

another way (to avoid async) is to pre-scan the tags's ns forms to see what namespaces are included, then load those plugins first and then evaluate all the script tags

this won't work in the REPL though. sci.async will

I don't understand this. How do you use thing/geom in your code then?
It's just the same as all scittle plugins:







That's why I'm so happy about it!!! 😄

And excited to try some more libraries (any suggestions?)

ah I see. so the "template" takes care of just running sci/copy-namespace on the namespace I guess? you're lucky if that works, then no other complexity like macros or dynamic vars are involved

Right, the build process expands the template definitions (usually all you need) into plugins directory, then searches all plugins (can contain extra stuff not in the template if needed) and scittle/plugins (official plugins) and compiles.

Maybe template is the wrong word 🤔 anyway that's the idea... and so far it's worked just to provide the deps and namespaces.

Thinking about this library: piranha/keybind really only consists of https://github.com/piranha/keybind/blob/master/src/keybind/core.cljs in this case I don't think it makes sense to add a plugin, but rather just load the cljs file (perhaps there is the question of where to load it from still), @chris358 maybe you have opinions about this? What do you do for keybindings in your cljs-josh experiments?

Compared to https://github.com/oakes/play-cljc this could be useful as a plugin, maybe I'll try that next.

I'm not using keybindings for anything. I have done the trick of remote-loading a single-file cljs namespace. For example the README for scittle-iconloader (a macro that preloads icons) shows how to load it from a script tag before using it: https://github.com/chr15m/scittle-iconloader

👍 1

I know it's not scalable but I kind of like the software minimalism this approach enforces. When you have to list every dep in a baroque HTML script tags it encourages a kind of parsimony. 🧐 I find myself trying to fit every app or library I write into a single file of 1000 lines these days.

💯 1

@borkdude is it correct to believe that there can never be a scittle.core-async because macros? Or does SCI have some magic that makes it possible?

quil did not compile due to cljsjs/p5

given this commit log:

commit f2517187bff0c3cd13fabaf5d2ce7c66128e31ff (HEAD -> main, origin/main, origin/HEAD)
Author: Michiel Borkent <michielborkent@gmail.com>
Date:   Fri Aug 22 12:45:38 2025 +0200

    Bump SCI

commit 76a32f63e542dc4ac1d1b715fbae2f9974d4e98a
Author: Michiel Borkent <michielborkent@gmail.com>
Date:   Thu Aug 21 15:12:20 2025 +0200

    README

commit 9e1feb81af87f5d79269cddef9df007408496788
Author: Michiel Borkent <michielborkent@gmail.com>
Date:   Thu Aug 21 15:03:34 2025 +0200

    version

commit 6b56464bd67c2a65de93270f5b3ab6d483260ffd (tag: v0.7.27)
Author: Michiel Borkent <michielborkent@gmail.com>
Date:   Thu Aug 21 15:03:00 2025 +0200

    0.7.27
I should pin skittle-kitchen to 6b56464bd67c2a65de93270f5b3ab6d483260ffd (tag: v0.7.27) right? i.e.: always use the latest tag (not the latest commit).

I think that's right, just double checking.

I'm planning on versioning scittle-kitchen as v0.7.27-1234 where 1234 is the commit count of the scittle-kitchen repo., v0.7.27 is the scittle version

Builds are now versioned, For now there is only one version (the latest, v0.7.27-31) available on the gh-pages site: https://timothypratley.github.io/scittle-kitchen/ If/when it comes to publishing to NPM would it be preferable to: • use my name as the organization • use ClojureCivitas as the organization • use SciCloj as the organization • use Babashka as the organization