Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
168 lines (112 sloc) 6.06 KB


A smarter client-side in ClojureScript

Shoreleave is a collection of integrated libraries that focuses on:

  • Security
  • Idiomatic interfaces
  • Common client-side strategies
  • HTML5 capabilities
  • ClojureScript's advantages

Installing and using

You can pull all the pieces of Shoreleave into your project by adding the following to your project.clj

(defproject ...

  :dependencies [[org.clojure/clojure "1.4.0"]
                 [shoreleave "0.2.2"]
                 [shoreleave/shoreleave-remote-noir "0.2.2"]

Individual utilies can be pulled in with [shoreleave/UTILITY "0.2.2"]. See the specific repo/artifact names below.


Shoreleave has support for the following:

Common client-side interactions

  • An idiomatic interface to cookies
  • An idiomatic interface to browser history (with extended support for HTML5 History API)
  • BlobBuilders and on-demand asset building
  • (Coming soon) An idiomatic interface to browser storage (Local Storage, Session Storage, and App Cache)
  • Common auxiliary functions out-of-the-box to handle query strings, browser-repl, hash strings, and CLJS/JS interop

A remotes package

Shoreleave's remotes package includes XHR, Pooled-XHR, JSONP, and HTTP-RPC capabilities.

CSRF protection is built in if your Clojure server is using the ring-anti-forgery middleware.

The HTTP-RPC allows for exposing a server-side namespace as a client-side API, via a single server-side call, remote-ns.

A typical Noir setup might look like:

(ns example
  (:require [example.api] ; You don't have to pull this in, but it is suggested
            [noir.shoreleave.rpc :as rpc]))

;; ...

;; The Base Web Server
;; ---------------------
;; Serve every view file found in `src/example/views`
(server/load-views "src/example/views/")

;; Remote Namespaces
;; -----------------
(rpc/remote-ns 'example.api :as "api")

;; Middleware
(server/add-middleware ring.middleware.gzip/wrap-gzip)
(server/add-middleware ring.middleware.file-info/wrap-file-info)
(server/add-middleware ring.middleware.anti-forgery/wrap-anti-forgery)

You can also define single "global" rpc functions:

(defremote ping []
    (println "Pinged by client!")
    "PONG - from the server"))

A pub/sub abstraction (and implementations)

Why would I ever want to use this?

Shoreleave's pub/sub system enables you to completely decouple parts of your app and declaratively bind them together. New features and functionalities can be built by composing pre-existing services/publishables.

Additionally you can express cross-cutting functionality (like logging or metrics reporting) as a service.

Reactive ClojureScript

This gives you the heart of Reactive JavaScript (RxJS), without the additional verbs (both a benefit and a tradeoff). It's often most beneficial to use DOM listeners as entry-points into the pub/sub system.

Shoreleave's pub/sub system is built upon two protocols: "brokers" and "publishables"

Out of the box, Shoreleave allows you to publish funtions, atoms, web workers, and anything that implements (str ...)/.toString, as topics. The simple pub/sub bus has very little overhead, but operates synchronously. You can trade-off some performance for an async bus, the event pubsub bus.

(In-progress) The cross document bus has a small amount of overhead, but allows you to publish and subscribe from/to functions that live in other web workers or windows (in-browser concurrency for "free").

In most cases, the simple bus is the best choice.

Common external API support

Shoreleave has JSONP-wrapped support for external APIs including:

  • Google Maps
  • DuckDuckGo Zero-Click
  • (Coming soon) Wikipedia and Alpha

An enhanced ClojureScript experience

  • A Function object that supports metadata
  • The ability to create embedded web workers

Where's the code?

Shoreleave is a big project and has been split up into smaller pieces within the Shoreleave organization:

Plays well with others

Shoreleave makes no assumptions about other libraries you might be using in your app.

I have found it to pair particularly well with Enfocus

Examples and usage

Please the github doc pages (ie: Marginalia docs) above for library specifics.

There is a community-contributed demo app thanks to the hard work of Robert Stuttaford

Google Group and General Help

There is a Shoreleave CLJS Google Group. Please feel free to post all questions and general comments there.

Additionally, you can ping ohpauleez in #clojure on Freenode.


Copyright (C) 2012 Paul deGrandis

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

Something went wrong with that request. Please try again.