Search code examples
clojureclojurescriptreact-native-reanimated-v2shadow-cljs

How to use Reanimated "worklet" directive in ClojureScript?


I am trying to use the react-native-reanimated library in the clojurescript project. And for this library, I have to create worklets by adding the "worklet" directive at the top. ex:

function someWorklet(greeting) {
  'worklet';
  console.log("Hey I'm running on the UI thread");
}

How can I use same in the clojurescript, currently I have:

(defn someWorklet [greeting]
    (js/console.log "Hey I'm running on the UI thread"))    

Solution

  • My advice would be to keep those "worklets" in JavaScript.

    As far as I know they run in their own context and therefore would need to load the entire ClojureScript runtime. At which point they likely lose all their performance benefit they may have had. Also I assume it is going to try to "copy" arguments passed to them. So you can't pass and CLJS datastructures (maps, sets, vectors, keywords, etc.) as arguments to them since that copying does not work for those. If you serialize them instead all potential performance benefit will be gone again.

    The main hurdle isn't the "worklet" directive, you could hack those in yourself via (js* "\"worklet;\"") as the first "call" in a defn. Closure optimizations will likely remove them though.

    The main hurdle is that those directives need to be processed by the react-native build tools and it likely won't understand the ClojureScript code in the first place.

    So instead write them in JS and include them in the CLJS builds in a way that the react-native tools can find them. So this could be (def my-worklets (js/require "../my-worklets.js") using a valid path here. In case of shadow-cljs this path would need to be relative to the :output-dir. Same for krell I believe.