Skip to content

imakira/js4clj

Repository files navigation

js4clj is a library aiming for facilitating the interop between Clojure and JavaScript on JVM using GraalVM and GraalJS.

Prerequisite & Installation

TODO

Usage

Requiring Namespaces

(ns net.coruscation.js4clj.example
  (:require
   [net.coruscation.js4clj.require :refer [require-js]]
   [net.coruscation.js4clj.utils :refer [js. js.- js.. clj->js js->clj js-set!]]
   [net.coruscation.js4clj.core :refer [js-new]]
   [net.coruscation.js4clj.js :as js]))

Using JavaScript Libraries

Install JavaScript libraries in the project root using npm like usual.

npm init
npm i luxon # luxon as an example
;; we can use luxon as a namespace now, for example: luxon/DateTime
(require-js '["luxon" :as luxon])

Converting data between Clojure and JavaScript

This library provides two functions similar to those of ClojureScript: js->clj and clj->js.

;; result: #object[org.graalvm.polyglot.Value 0x22b60c71 "{key: \"value\"}"]
(def js-obj (clj->js {:key "value"}))
;; result: {:key "value"}
(js->clj js-obj :keywordize-keys true) 

Calling JavaScript functions, get/set JavaScript properties

Similar to ClojureScript, this libraries provides four macros: js. js.- js.. and js-set!

We can use js. to call a method of an Object.

(def current-time (js. luxon/DateTime now))
;; result: "2025-11-27T23:27:34.853+08:00"
(js. current-time toString) 

We can use js.- to access properties of an object.

;; result: "value"
(js.- (clj->js {:key "value"})
	  key) 

We can also use js.. to chain the calling

(js.. luxon/DateTime now toString)

We can also use js.. to access property by using - as a prefix:

(js.. luxon/DateTime
  (fromObject (clj->js {:day 22}))
  (plus (clj->js {:day 1}))
  ;; results: 23
  -day) 

The library also provides a js-set!, it must be used along with js.- or js...

(let [obj (clj->js {})]
  (js-set! (js.- obj key)
           "value")

  (js.- obj key) ;; "value"

  (js-set! (js.. obj -key)
           "new value")
  (js.- obj key) ;; "new value"
  )

Examples

You can check this minimal Server Side Rendering with Client Side Rehydration example using react.

Links

This project is inspired by:

Check this blog about roughly how it is done Experiment with GraalVM, Clojure, and JavaScript.

About

Using JavaScript in JVM with Clojure by GraalJS

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published