It's not that difficult to write a library that runs on both.
But there are differences in the runtimes, of course.
Some examples:
https://github.com/stuartsierra/component https://github.com/plumatic/schema (uses .cljx, the precursor to .cljc)
(ns com.stuartsierra.component
(:require [com.stuartsierra.dependency :as dep]
[com.stuartsierra.component.platform :as platform]))
requires the correct platform.clj or platform.cljs depending on the runtime?And that this:
#?(:clj
(defmethod clojure.core/print-method SystemMap
[system ^java.io.Writer writer]
(.write writer "#<SystemMap>"))
:cljs
(extend-protocol IPrintWithWriter
SystemMap
(-pr-writer [this writer opts]
(-write writer "#<SystemMap>"))))
is how you perform different operations in a single file based on runtime?It depends on what you're trying to do, and whether the platforms help.
Doing something 'pure' like math or datastructures: trivial. Writing a common interface to two different host libraries (e.g. DateTime in JVM & Browser): manageable. Doing something 'host-y', like graphics, with no host libraries in common: very hard.
Basically, Clojure doesn't get in the way of cross-platform concerns, but it might still be a difficult problem.
I work for a SaaS/PaaS company using Clojure internally for 2 years and was looking into making a universal client (jvm, clr, js, ios, android)... I'd surely have used a Cljx core with Lein profiles for each platform prior but now it's up in the air, may still have to go that way if we're supporting older Clojure. Each approach on its own is easy, but now there are two and the unofficial one (cljx) is more widely supported than the official one (cljc).
This instantly gives you access to a whole ecosystem of stuff written for Java. It's very easy to use the Java AWS SDK directly from Clojure code, for example.