ClojureScript ↔ JavaScript interop boundary for incremental migration without downtime
0 reputation · 27 May 2022, 07:37 UTC
0 reputation · 27 May 2022, 07:37 UTC
A small frontend application is being considered for incremental migration from plain JavaScript to ClojureScript with no downtime. The goal is to mount ClojureScript components into isolated DOM nodes and routes while the existing JavaScript remains active, using feature flags and separate asset loading.
ClojureScript compiles to plain JavaScript and can be delivered as ES modules or bundles that coexist with existing JavaScript on the same page. Interoperability relies on explicit interop syntax and externs declarations. Under advanced compilation Closure renames symbols and properties, which breaks external calls without externs. Build tool choice influences the output shape, with shadow-cljs providing npm integration and hot reload for development and the official CLI targeting Google Closure Compiler for production artifacts. Zero-downtime behavior depends on deployment practices such as feature flags and cache busting, not on ClojureScript itself.
An unresolved decision is the stability of the JavaScript API surface exported from ClojureScript. The trade-off is between exposing names via defonce and externs for external JavaScript callers versus keeping the boundary internal and recompiling on change.
What contract should define a stable JS API from ClojureScript when advanced optimizations are enabled? How should externs or export maps be maintained across incremental releases to avoid breaking existing JavaScript callers? Is it advisable to keep the interop boundary internal rather than publishing a versioned JS surface?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.