Skip to content
A clojurescript compilation watcher
Shell Clojure
Find file
Pull request Compare This branch is 28 commits ahead of ibdknox:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

CLJS watcher

This is a modification of

The modifications support basic generic usage and compilation of clj files as cljs


You must have ClojureScript already setup and have $CLOJURESCRIPT_HOME correctly set.

Put cljs-watch on your $PATH (such as in /usr/local/bin) and then simply run it from your project root.


cljs-watch option

the option is mandatory


cljs-watch cljsc

Compiles javascript


cljs-watch gen-once

Generates src-generated from src-generic - in the local project only - once only

Useful if you want to jar your clj and cljs


cljs-watch gen-watch

Generates 'src-generated' and watches for changes in 'src-generic' in the local project and in all 'checkouts' projects recursively.

Useful when developing.

Note that all 'src-generated' directories in you checkouts tree will be removed when you start this. But you shouldn't be touching those anyway.


If you are writing pure clojurescript - i.e. no code you may want to use in clojure. Then you do not need to worry about generic source - just put your clojurescript in src. You can still compile.

If you are only writing clj code for jvm or clr - you don't need this at all. Move along.

But, if you have code that is portable across clj and cljs then this tool will help.

I am not 100% happy with this methodology - it is cludgy. But, I want to be able to reuse my code for both clj and cljs easily - including jaring and clojurescript compilation.

When most of my files are generic, the ovehead of renames to include in cljs is too high.

General definitions

Filename extensions

The following filename extension conventions are defined and used here

  • .clj - platform specific clj file (jvm typically)
  • .cljs - platform specific cljs file
  • .cljg - generic clojure file - no platform specifics
  • .cljgm - generic clojure macros file - no platform specifics

Compiling clojurescript

The script will search for the src and src-generic folders in your project and recursively in all projects in the 'checkouts' directory.

any file that is relevant to a clojurescript build will be staged to a directory 'cljs-staging' this is .cljs, .cljg and .cljgm files

the staged files will then be built as clojurescript

cljs compilation options

  • default options are
{:optimizations :simple
 :pretty-print true
 :output-dir "resources/public/cljs/"
 :output-to  "resources/public/cljs/bootstrap.js"}
  • You can specify cljsc options in a file named 'cljs-opts.clj'.
  • these options will be merged with the default.

See examples including jquery below

lib jars

  • jars in lib that contain cljs files are included in the build. (see example with pinot)
  • they undergo no special treatment

The gen-once option

This option is included to generate a combined set of source for jar packaging.

The src-generic directory (only) is searched for relevant files and .clj and .cljs files are created in a directory named 'src-generated'.

If you set :source-path "src-generated" in leiningen, this will build for clojure code and jar both the .clj and .cljs files.

The gen-watch option

This option is included for general development. It will watch the local project and all checkouts projects If code in src-generic changes it will be copied to src-generated as appropriate.

This way lein repl, require reloads and such like will work for you.


Important : NEVER ever edit or put anything in 'cljs-staging' or 'src-generated'.

Important : when compiling - the staging directory is recursively removed when you start cljs-watch.

Important : when generating src - the src-generated directory is recursively removed when you start cljs-watch.

Platform specific implementations

By implementing both a clj and a cljs file you can get useful platform portability. provided the two implementations use the same "api".

If you do this, use a naming convention, so that the appropriate file can be picked up on different platforms.

For example

  • utils.x.log.clj - use java logging
  • utils.x.log.cljs - do js logging to console

as long as both define "log" then any client code can use this freely.

(ns whatever
 (:require utils.x.log :as l))

(l/log "something")

will work on both platforms.

Example cljs-opts.clj

E.g.: Including JQuery

  • will work only for simple optimizations
  • jquery lib will be included automatically
  {:file "" 
   :provides ["jquery"]}

E.g.: Including JQuery

  • will work for advanced optimizations.
  • jquery must be included in your html before bootstrap.js.
 :optimizations :advanced
 :externs ["js-lib/jquery/1.7.1/externs.js"]

Some Externs files:

Generating jar files

in you project.clj :source-path should be set to "src-generated"

cljs-watch gen-once
lein jar

that's all

but, because the cljs compilation by default generates resources/public/cljs, you may want to remove this.


Copyright (C) 2011 Dave Sann (my modifications)

Copyright (C) 2011 Chris Granger

Distributed under the Eclipse Public License, the same as Clojure.

Something went wrong with that request. Please try again.