22

Normally, Clojure source files are named (for example) foo.clj, and Clojurescript source files are named foo.cljs. My impression is that in Clojure versions >= 1.7, I can name a file foo.cljc if I want it to be available for loading with require or use both from Clojure and Clojurescript.

Is this correct? It seems to be implicit in the primary documentation pages on Using cljc and reader conditions, but as far as I can see it's never explicitly stated.

This is not a question about using reader conditionals to specify alternate code for running in Clojure and Clojurescript; it's more fundamental. For example, I have a source file that contains code that's completely generic: It will run in both Clojure and Clojurescript unchanged. Can I assume that by naming it with ".cljc", require will always find it from inside both Clojure and Clojurescript (assuming it's named correctly, is in the correct location, etc.)?

[I'm pretty sure that I'm right, but I'm not certain, and I thought it would be worth having the answer documented here if I'm correct.]

Mars
  • 8,689
  • 2
  • 42
  • 70
  • Hmm, good question! Seems like it's pretty much been taken for granted so far. I'd say **yes**, your understanding of the purpose and functionality of cljc files is correct, but as you've stated in your question, finding an official statement of that is another matter. Perhaps Alex Miller can post a definitive answer. – Sam Estep Jul 30 '16 at 18:12
  • I'd be satisfied with a confident assertion from an experienced and knowledgeable user even if there's no official statement, @SamEstep. A statement from someone like Alex Miller would be even better, of course--that does make it official, pretty much--but doesn't seem necessary. If you feel confident enough that this is how things are, you might want to answer. – Mars Jul 30 '16 at 19:55
  • I consider myself experienced and knowledgeable in Clojure, but not in ClojureScript. I'll let one of the Clojure core developers or someone who is both Clojure developer and a ClojureScript developer, and who has used cljc files more extensively than I have, answer your question. – Sam Estep Jul 30 '16 at 20:01

2 Answers2

26

That's correct. When Clojure or ClojureScript needs to load a namespace, they first look for the platform-specific file (.class then .clj on Clojure and .cljs on ClojureScript) and if not found, then they look for the .cljc file.

You do still need to make sure it is available to the language on the classpath, as with other source files.

Alex Miller
  • 69,183
  • 25
  • 122
  • 167
9

Yes.

The nuances is the precedence of loading, which is explained here:

https://github.com/clojure/clojure-site/commit/010134bcc2e8af899ba2b1e5816b0fcf7e007ba4

In short, cljc files are loaded last, and conditionals are only valid in cljc.

Timothy Pratley
  • 10,586
  • 3
  • 34
  • 63