Skip to content
Sebastian Bensusan edited this page Jul 29, 2015 · 14 revisions

Reader Conditionals allow you to write code that can target both Clojure and ClojureScript. This problem was previously solved by cljx which is now deprecated.

Transitioning from cljx

After reading the Reader Conditionals Design Page you'll notice the conversion is straightforward:

(try
 (dangerous!)
 (catch #+clj Exception
        #+cljs :default
        e
   (solve-it)))

is transformed to:

(try
 (dangerous!)
 (catch #?(:clj Exception
           :cljs :default)
        e
   (solve-it)))

Some things to have in mind while making the transition:

  • Make sure you delete all the files generated by cljx before starting with the transition. While some projects would generate the clj and cljs files to target others would mix them with other sources (i.e. using a common folder).

Some examples of transitions are zelkova and bidi

General Considerations

  • Think about your new project structure: while some libraries can get away with full cljc codebases, most application code will need clj, cljs, and cljc files. If one of your namespaces is mostly interop (i.e. date handling), it is preferable to have 2 distinct clj and cljs that one file full of reader conditionals.
  • ns specs are one of the greatest differences between clj and cljs. Read this wiki if you run into trouble. Requiring macros is the most obvious difference, but there other ones. For example, while :import is used in Clojure for user defined classes (defrecord and deftype), it is only used in ClojureScript for Google Closure Classes. Therefore, don't use :import for user defined classes in cljc

For example, the following clj code

(ns foo.bar
  (:import [baz.core BazRecord])
  (:require [baz.core :as baz]))

should be

(ns foo.bar
  (:require [baz.core :as baz :refer BazRecord]))

to be used in cljc.

Clone this wiki locally