https://github.com/avanelsas/baredom A library of 100+ UI components built entirely on web standards: Custom Elements v1, Shadow DOM, and ES modules. This release turns the Web Components x-select, x-date-picker, x-combobox and x-multi-combobox into form controls with inline validation error display and native form participation and constraint validation. I implemented this after experimenting with BareDOM components in another project called https://github.com/avanelsas/baredom/tree/main/barebuild that attempts to build a thin, framework-and state-free client that uses presentational Web Components to represent server-state and handles user interaction (data, not html, over the wire). A video of the demo for BareBuild is available in the #C015AL9QYH1 channel. Visit #C0AS9CBPALB for questions, or take a look at a live demo https://avanelsas.github.io/baredom/.
dbos-clj 0.1.0 โ durable workflow execution for Clojure
Hi folks! Happy to announce the first release of dbos-clj โ tiny wrapper over dbos-transact-java to create durable, resumable workflows in Clojure.
Highlights:
- Workflows are functions. Wrap non-deterministic work (ids, timestamps, API calls) in steps. DBOS persists the result and replays it on recovery, so a workflow always takes the same path.
- Child workflows (scatter/gather), scheduled workflows, durable sleep & workflow events
- Transit serialization included by default. Supports BYO serialization
- Query workflow status & steps, target specific app versions
(defn sync-user [dbos {:keys [user-id]}]
(let [row (run-step dbos "fetch" (fetch-user db user-id))] ; persisted + replayed
(do-step! dbos "notify" (notify! row)) ; side-effect only
{:done true}))
com.shipclojure/dbos-clj {:mvn/version "0.1.0"}
Repo: https://github.com/shipclojure/dbos-clj
Feedback and bug reports very welcome!I used to use https://github.com/framed-data/overseer for this kind of thing but Iโll check this out!
I haven't used Overseer. We've been using DBOS at my job for almost a year now and it's been great! Finally extracting it into a library, since dbos-transact-java hit 1.0.0 .
We are even migrating some of our proletarian jobs to DBOS due to ease of debugging since all execution steps are persisted in the database.
we've been using Temporal heavily at my job for the last years but compared to it the simplicity of DBOS is very appealing! excited to try this out
Small updates to dbos-clj. See v0.4.0 https://clojurians.slack.com/archives/C015AL9QYH1/p1785153099580709
Have been looking at workflow engines lately after using simple cron scheduling and keeping state manually in tables or some background execution utilities coupled to various web frameworks. DBOS seems like a good fit to try out. Nice to have a wrapper library and docs, thank's. Added to https://github.com/dbos-inc/awesome-dbos
Wow! That is so awesome! Thank you!
cider CIDER 2.0.1 is out with a bunch of small fixes (mostly around session management inferences outside projects)! More details in the release notes - https://github.com/clojure-emacs/cider/releases/tag/v2.0.1 Overall, I happy to report that no significant bugs were discovered in CIDER 2.0, and I hope that this will be the only bug-fix release it gets. cider
๐ cljgo โ Clojure hosted on Go (0.x, working)
I built Clojure hosted on Go so I can work across my projects with both ecosystems. Simple idea: emit Go source like CLJS emits JS. Clojure and Go libraries both first-class, web APIs Compojure-style on net/http. nREPL for the REPL side, or cljgo build โ one static binary, no JVM โ same source, byte-identical output both ways.
93% of clojure.core, verified against Clojure 1.12.5.
https://github.com/muthuishere/cljgo
Given there are already two (three?) pretty complete implementations of Clojure-on-Go, what makes this different?
#C05NVNMA2ES #C04DCFZKPJN #C0AEASGBZ7Y off the top of my head...
both let-go and Glojure are great, and cljgo builds on both โ the runtime data structures are adapted from Glojure's (vendored + credited in the repo), and I picked up ideas from reading let-go. Main difference is the model: cljgo compiles Clojure to plain Go source, like ClojureScript does to JS. So the output is just a Go program โ any Go library works directly with require-go, no bindings, and a cljgo lib is just a Go module you publish/pull like any Go package. let-go ships binaries too, but bundles bytecode + its VM; here the output lives inside the Go ecosystem. Honestly the real reason is personal โ I couldn't work in Clojure for a long time and didn't want to lose the feeling, but my day-to-day is Go now. So I wanted one tool that lets me write Clojure and ship it as a normal Go binary. Everything's conformance-tested against JVM Clojure 1.12.5. Still early โ would love your take if you try it. #C0BKDGTMA7L
Does a REPL work with this approach?
with persistent state
I guess it could work, just wondering
> Full REPL-driven developmentโ live re-`def`,`defmacro`at the prompt, nREPL for CIDER/Calva. I guess so :)
Woah nice, how readable is the Go source it emits? That's exactly my use case as well, have to write Go at my day job ๐
that's nice. does it write a memory heap to disk or something? or does it replay the REPL
Neat! I added cljgo to https://github.com/clj-easy/clojure-dialects-docs/commit/f108c854ac6a62fa3845d06e80d3a472d3e07143. Edits/corrections are always welcome.
I guess I'm double posting since I asked on Reddit. But I don't see what's different from Glojure especially, but even Let-go, since they both can compile to Go source.
It seems you mean that you're able to AOT more without a runtime bundled in? Do I understand that comes at the cost of manually coercing types back and forth between Go and Clojure?
It sounds like it isn't really dealing with "Go and Clojure" tho', since it compiles Clojure to Go, and then all "interop" is just within Go. There's no "back and forth".
I did some more digging. It's incredibly similar to Glojure. Both AOT compile to Go source with no interpreter fallback. If something isn't supported by AOT, compilation generally fails rather than falling back to interpretation. Glojure seems to cover more of Clojure for now. And the biggest difference appears to be how they do interop. Glojure goes the extra mile of allowing Clojure types to be passed directly into Go functions that expect Go types. So a Clojure vector can be passed to a parameter that takes a Go slice, for example, and a Clojure function can be passed directly as a typed Go callback. Whereas in cljgo it seems the programmer has to manually coerce/adapt those when doing interop, but likely incurs less overhead. Anyways, good job, and interesting to see another attempt at this.
@muthuishere You might want to check out https://github.com/gloathub/gojava as well. Glojure uses those so that many Clojure libs that use Java interrop still work as-is by allowing Java interrop syntax to be shimmed by gojava. Jolt (Clojure on Chez Scheme) does similar, and even lets the user provide configured shims.
I wrote gojava for #C05NVNMA2ES as a port of the most common Java classes used in typical Clojure JVM interop. Then I met @yogthos the author of #C0B8G0WB63C and he had gone further with https://jolt-lang.github.io/docs/libraries.html so I added all of those to gojava as well. Feel free to use them. I think #C04DCFZKPJN might also use gojava or is planning to. #C0AEASGBZ7Y is a really useful build tool that sits over both glojure and let-go and makes it easy to work with in many contexts. Think of it as something like Leiningen for dialects that support AOT to binary code. I'm planning to add jolt as a third engine, since it can compile to native as well. I'll consider supporting cljgo as it matures. Note that gloat is getting close to being a replacement for GraalVM native-image with similar runtime speed, cross-compilation to 25+ os/arch platforms, fast compile to native binary and shared libraries and a completely open source code base and license, I'll add cljgo to the https://clojure.cc/dialects/ page. Feel free to join #C0B655S3R19
Four new go+clojure dialects were not on my 2026 bingo card. Congrats! I just like seeing people build things.
@seancorfield yes, it converts to Go only. A pure .cljc lib still serves both worlds though โ publishable as a Go module and as Clojure source (git coordinate in deps.edn today, Clojars coordinate on the roadmap). No Java by design โ JVM Clojure already excels there. Great questions all around, added a FAQ: https://muthuishere.github.io/cljgo/faq/
I added cljgo to https://clojure.cc/dialects/ #C0B655S3R19
@muthuishere You really need an entry to compare it to Glojure, because I see like no difference with it ๐. And that's ok, the FAQ can also say, cljgo and Glojure take the same approach and work the same way, two different attempts at implementing the same thing. Unless there are relevant differences, which is kind of what I'm interested in learning, but with my deep dive I haven't found very many that aren't tiny details. You might need to ignore the LLM, because it's clearly only using Glojure's readme and that's why it's wrong in its comparison with Glojure. Or tell it to ignore all readme and analyze the Glojure source exclusively to compare. Edit: And do the same for let-go, the LLM is also wrong and clearly only using the readme, so it's not comparing at all against its AOT compiler which does direct Go source generation by lifting the IR.
I need to rewrite the Glojure and Gloat readmes and web pages to better represent what those projects can do (which is a lot). I have that on my list for today or tomorrow. The short of it is: โข Glojure is a rather full/complete port of Clojure. Hosted on Go with full Go interop. Basic Java interop supported as well to make most current Clojure code just work. Can AOT to Go code and be (cross-)compiled anywhere Go can. โข Gloat is an automation tool for Glojure, let-go (and other AOT capable dialects) that makes common use cases trivial. It compiles clojure to native bins and shared libs (very quickly). Cross-compiles to 25 places including wasm. It also produces go code in build directories ready to integrate into existing Go projects. (ready for the workplace).
I'm also going to write (hopefully real life) tutorials docs for the gloat use cases, next week.
@ingy or others who might be knowledgeable on the topic: what sort of runtime does Glojure and let-go bundle into their AOT'd binaries, and what sort of overhead would there be for executing AOT'd clojure code compared to plain go code for each of them?
@max.r.rothman, that's heavily evolving by the day right now! It's approaching graalvm speed. I'm working on a benchmark system right now to get real data comparing glj, lg and graal.
let-go started with a novel/bespoke bytecode and vm written in Go to evaluate it. It performed well. Then they started lowering functions to Go code, trampolining back to the VM when things were not supported. It's promising. Glojure has had full AOT for clojure to Go, but was very much unoptimized. That is also changing fast. In my experience as of today, sometimes one is faster and sometimes the other. join #C0AEASGBZ7Y for further discussion and real-word asks.
And maybe also bench against cljgo now ๐
Well yeah. planning to add it under gloat soon enough.
Let the GO games begin ๐
Winter is coming.
@muthuishere Nice. I think one thing I still get confused, I feel you need to add a steering for it in your agent.md, is that only let-go includes the interpreter in it's AOT as fallback. Because it says "and the zero-interpreter binary is why ours are 5.3-6.7 MB vs 7.5", and that's not why, because Glojure does not include its interpreter in the binary either.
I also have some question, you might want to review or ask AI, because it's strange it includes a range of sizes for cljgo, but a single size for glojure and letgo ?
Are you a @jfhamlin stunt double?
@didibus https://github.com/muthuishere/cljgo/blob/main/benchmark/run-aot.sh. (the benchmark script) It used to be 5.3 mb in beginning ( when we scored 22% in jank test suite) now after fixing it and with added new features , its 6.7 MB now
@ingy i used from let go to see how good or bad cljgo is
That would make sense
@muthuishere it just occurred to me that maybe you could work on Glojure with us instead of making another dialect. Up to you but more hands make less work. ๐
@ingy Thanks for the offer, and I mean that. Glojure's codegen beat mine on 6 of 8 rows in the benchmark I published, so I'm learning from your work as it is. Where I'm heading just isn't a fourth Clojure port. The specs I'm working through are an app framework more than a language: one blessed data layer, an OS-keychain secret store, opt-in otel, a native cross-platform CLI suite where every command is also an agent-drivable tool โ curated into core and linked only when required, so binaries stay small. Bun's model, Clojure on top. Different goal than Glojure's, which is why merging doesn't quite fit. You're ahead of me on shared libs and wasm โ I have cross-compilation but nothing there. Next spec on my side is a cgo-free systems layer: SIMD kernels in Go asm, GPU and native OS APIs via purego at runtime, so binaries stay static. Accepted design, not built yet. More hands making less work is real though. Gloat's already in cljgo's credits since I used it to build the comparison binaries โ happy to share work anywhere it doesn't mean merging identities.
@muthuishere Sorry didn't fully follow. You mean that you intend to bundle a web framework of sorts with it? Why not just make that as a separate lib though?
@didibus Thats the core differentiator of cljgo (i think its kind of odd as well) it's the Bun and Elixir path rather than anything new. Bun ships its own sqlite, http, test runner. Elixir has Phoenix. You start with a working project and build your thing. In Clojure, "build a web API" still means picking an http server, a router, a db layer, migrations, logging, and wiring them yourself, differently in every project. That's fine once you're experienced and opinionated. It's rough if you're new, and it's a big part of why people bounce off. What's in the box today: http, db with migrations, config, auth, secrets in the OS keychain, otel, cache, background jobs, html, openapi, audit logging, and a CLI suite. Templates wire them up โ cljgo new --template web or --template cli gives you a project that runs. Planned: a systems layer for SIMD and GPU work, cgo-free so binaries stay static, and shared libs and wasm output eventually. They're libraries, not a framework โ you require a namespace and call it, nothing owns your main, and unused pieces don't land in the binary. Plain cljgo without any of it works fine. I'll own the odd part: treating them as first-class means work in the language core gets driven by what those libraries need. Opt-in linking is the clearest case โ the compiler has to know about a battery to leave it out of the binary when it's unused, so the two co-evolve rather than staying cleanly separated. Not how Clojure usually does it, and I get why it looks backwards. But I think that's the trade that gets more people building here. Side benefit: it also makes generated code consistent, since there's one obvious way to do each thing.
https://github.com/ring-clojure/ring-content-encoding 0.1.0 has just been released. This library provides a Ring middleware function that adds support for ZStandard, Brotli, GZip and Deflate content encoding to your handler.