Metosin
ClojureScript aims to eliminate its largest source of incidental complexity by automating extern inference, forcing third-party JavaScript libraries to conform to its optimization standards.
AI-assisted summary of The Next Five Years of ClojureScript - David Nolen — original source. Check the original for full context.
Source published:
Key ideas
- Five years after its launch, ClojureScript achieved near-total standard library parity with Clojure on the JVM, powered by cross-platform reader conditionals (.cljc) and a fully self-hosting compiler that eliminated JVM dependencies. (34:21)
- Manual Google Closure externs remain the single largest source of incidental complexity in ClojureScript, driving active compiler prototyping toward automated extern inference for third-party JavaScript interop. (45:10)
- Early ClojureScript work on persistent data structures inspired Mori, which directly influenced Facebook's design of Immutable.js after React popularized reference-equality checks for virtual DOM diffing. (53:40)
- Targeting WebAssembly directly remains a long-term goal projected 6 to 10 years out due to the initial specification's lack of native runtime garbage collection. (58:10)
Detailed notes
## Background Published by Metosin on YouTube on September 16, 2016, this talk features ClojureScript lead developer David Nolen reflecting on the language's first five years. The presentation aims to document key architectural milestones before early community lore is forgotten and outline a pragmatic roadmap for the next five years of compiler development.
## TL;DR David Nolen details the evolutionary milestones of ClojureScript since its 2011 launch, including the migration to persistent data structures, source map implementation, self-hosting via reader conditionals, and validation through real-world tools like Light Table. He addresses major friction points, highlighting how Google Closure Compiler advanced compilation and manual externs historically burdened frontend developers. Looking ahead, Nolen outlines priorities centered on clojure.spec integration, automated extern inference, compiler optimization passes, and seamless modern JavaScript module interop.
## Atmosphere & style The presentation is candid, technically rigorous, and conversational, marked by Nolen's genuine awe at the power of the tooling alongside self-deprecating humor about past development burnouts. Rather than presenting a rigid corporate roadmap, the narrative feels like an affectionate, community-centered retrospective that credits countless volunteer contributors for solving thorny compiler problems. The vibe is energizing and pragmatic, balancing deep architectural discussions with an enthusiastic call for everyday developers to dive into open-source compiler work.
## Bulletin - [34:21](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2061s) Five years after its launch, ClojureScript achieved near-total standard library parity with Clojure on the JVM, powered by cross-platform reader conditionals (.cljc) and a fully self-hosting compiler that eliminated JVM dependencies. - [45:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2710s) Manual Google Closure externs remain the single largest source of incidental complexity in ClojureScript, driving active compiler prototyping toward automated extern inference for third-party JavaScript interop. - [53:40](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3220s) Early ClojureScript work on persistent data structures inspired Mori, which directly influenced Facebook's design of Immutable.js after React popularized reference-equality checks for virtual DOM diffing. - [58:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3490s) Targeting WebAssembly directly remains a long-term goal projected 6 to 10 years out due to the initial specification's lack of native runtime garbage collection.
## Key takeaways - [05:13](https://www.youtube.com/watch?v=mty0RwkPmE8&t=313s) Rich Hickey announced ClojureScript in July 2011 to expand Clojure's reach into environments barring the JVM, architecting the compiler in Clojure with protocols at the base. - [09:55](https://www.youtube.com/watch?v=mty0RwkPmE8&t=595s) Adoption initially stumbled over unfamiliar Google Closure tooling until Evan Mezeske created the lein-cljsbuild plugin, integrating ClojureScript compilation into standard Leiningen workflows. - [14:31](https://www.youtube.com/watch?v=mty0RwkPmE8&t=871s) Porting persistent data structures to JavaScript took over a year, but benchmarking and compiler tuning brought ClojureScript vector performance to within 20% to 30% of handwritten JavaScript on V8. - [16:48](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1008s) Chris Granger's Light Table demonstrated that ClojureScript could power large-scale, desktop-grade developer tooling, disproving widespread skepticism around client-side immutable data structures. - [19:32](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1172s) Implementing Source Maps took over two years due to Clojure's Java reader lacking column metadata, requiring Nicola Mometto's tools.reader and Sean Grove's Base64 VLQ implementation to resolve. - [31:45](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1905s) Mobile toolkits like Mike Fikes's Ambly established untethered iOS REPL workflows over Wi-Fi direct to JavaScriptCore without requiring Xcode after the initial build. - [34:21](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2061s) Clojure 1.7 introduced reader conditionals (.cljc), allowing David Nolen to port the ClojureScript analyzer and compiler to ClojureScript itself, unlocking standalone tools like Plank, Replete, and KLIPSE. - [38:30](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2310s) The emergence of React eliminated mainstream skepticism about immutable data by shifting UI paradigms away from mutable DOM manipulation to pure state-driven rendering. - [41:46](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2506s) ClojureScript development follows a user-need-driven organic path rather than a rigid roadmap, with language parity with Clojure remaining the overarching priority. - [41:46](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2506s) Serial compiler optimizations could yield an estimated 2x speedup, shortening build times significantly when paired with parallel compilation. - [45:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2710s) Google Closure externs cause frequent production breakages under advanced optimizations, making native extern inference and module processing primary development targets. - [45:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2710s) Translating clojure.spec definitions into Google Closure type annotations offers compile-time type verification to catch defects before production. - [57:34](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3454s) Whole-program dead-code elimination via Google Closure enables ClojureScript to discard unused code from upstream dependencies, obviating the need for micro-modular JavaScript packaging. - [58:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3490s) Full WebAssembly adoption for ClojureScript will take 6 to 10 years because bundling a custom garbage collector without native host GC support would cause severe performance issues.
## Detailed walkthrough ### [00:02](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2s) Introduction and the Early Horizon of ClojureScript
Opening the final talk of the day at a conference in Finland, David Nolen explains that rather than giving a deeply technical presentation, he wants to chronicle the history of ClojureScript. Stepping back is critical because with five years having elapsed since its inception, the early history is already fading from collective memory. A quick poll of the audience underscores this: while almost no hands go up for five or four years of experience, a few appear for three, and the vast majority have only adopted it within the last one to two years. Because so many are newcomers, Nolen hopes that walking through this long, winding road will give developers perspective on how ClojureScript is built and how its development philosophy works.
Nolen briefly introduces himself as a software engineer at Cognitect, a software consultancy that stewards Clojure and ClojureScript, where he serves as the lead developer of ClojureScript (alongside working with products like Datomic). He highlights a major milestone that had occurred just weeks earlier: ClojureScript finally launched an official, dedicated website. Repurposing the infrastructure and design of `clojure.org`, Alex Miller led the effort to create content targeted specifically to the language. While existing developers had long known ClojureScript to be reliable and capable, having a polished public face gives newcomers the sense that the technology has fully grown up. Reflecting on his daily work, Nolen remarks:
> “Even though I work on the compiler, every time I have Figwheel or I'm building my project, it's like this is like magic, this is amazing.”
Even to the people building it, the distance the ecosystem has traveled feels like scaling an immense mountain.
---
[02:56](https://www.youtube.com/watch?v=mty0RwkPmE8&t=176s) Pre-History (2011): The Search for a Frontend Lisp
Five years prior, in 2011, Nolen was not working with Clojure professionally. He worked in the newsroom at *The New York Times* on the Interactive News team building news applications using a standard stack of Ruby on Rails, JavaScript, and jQuery. He shared an office with Jeremy Ashkenas, who had created CoffeeScript. At the time, compiling to JavaScript was widely dismissed by mainstream web developers; although tools like Google Web Toolkit (GWT) could compile Java down to JavaScript, the broader JavaScript community viewed source-to-source compilation as an oddity. CoffeeScript fundamentally changed that mindset by demonstrating to frontend developers that compiling down to JavaScript was a viable, elegant way to write web software.
Nolen was personally drawn to Lisp rather than Ruby or JavaScript and began searching for a dialect that could compile down to JS. Clojure was merely a hobby language for him at the time, and an early experimental project called ClojureScript by Chris Houser existed but was nowhere near ready for real-world usage. Nolen evaluated Scheme2Js, a nearly fully compliant Scheme R5RS compiler written by Florian Loitsch (who later joined Google to build Dart's `dart2js` compiler). However, Scheme2Js lacked macros. Being completely committed to the power of Common Lisp, Scheme, and Clojure, Nolen felt macros were non-negotiable and resigned himself to sticking with CoffeeScript.
- Mainstream web dev stack in 2011: Ruby on Rails, JavaScript, jQuery. - CoffeeScript served as the cultural turning point that normalized compiling to JavaScript. - Florian Loitsch's Scheme2Js offered near-R5RS compliance, but its lack of macro support made it a dead end for Nolen's needs.
---
[05:13](https://www.youtube.com/watch?v=mty0RwkPmE8&t=313s) The Launch of ClojureScript: Reach and Self-Hosting Roots
In July 2011, Relevance held a meetup at Clojure NYC—one of the most heavily attended meetups in the group's history—where Rich Hickey officially unveiled ClojureScript. The core motivation behind the language was *reach*. Clojure developers loved targeting the JVM, but the JVM could not run everywhere. Apple strictly prohibited JVM environments on iOS, and web browsers had long abandoned Java applets. To write client-side software and target platforms where the JVM was locked out, JavaScript was the only viable runtime.
Rich Hickey also positioned ClojureScript as a groundbreaking conceptual experiment: it was the first pass at writing Clojure in Clojure itself. Clojure on the JVM had an implementation written almost exclusively in Java, from its compiler to its persistent data structures. ClojureScript broke with that architecture by being written in Clojure, with abstractions driven by Clojure protocols at the lowest level of the language. This realized a cryptic teaser Rich Hickey had dropped on IRC back in January 2011 when he briefly asked:
> “What if there was a version of Clojure with protocols at the bottom?”
```mermaid flowchart TD accTitle: Clojure JVM versus ClojureScript Implementation Architectures accDescr: Diagram contrasting Clojure JVM's Java-based implementation with ClojureScript's self-hosting Clojure implementation.
subgraph JVM ["Clojure (JVM)"] JCompiler["Compiler (written in Java)"] JDS["Core Data Structures (written in Java)"] JTarget["Runtime Target: JVM"] JCompiler --> JTarget JDS --> JTarget end
subgraph CLJS ["ClojureScript (2011)"] CCompiler["Compiler (written in Clojure)"] CProtocols["Core Data Structures via Protocols"] CTarget["Runtime Target: JavaScript Engine"] CCompiler --> CTarget CProtocols --> CTarget end ```
---
[07:34](https://www.youtube.com/watch?v=mty0RwkPmE8&t=454s) First Contributions and Early Adoption Hurdles
ClojureScript had been public for two or three months before Nolen got involved. After cloning the repository to try out the REPL, he attempted to run `reify` and hit an immediate error because the macro had not been implemented. After asking on the mailing list, he learned it was simply waiting for someone to write it. Expecting compiler work to require weeks of grueling effort, he dug into the source and was surprised by how approachable and simple the codebase was because it was written in Clojure. He drafted a clean implementation in just eight lines of code:
> “Rich Hickey and Chris Houser both [were] like, 'Wow, that's so cool, only eight lines of code to get `reify`,' and this was my—this got me commit rights to ClojureScript.”
From that point on, Nolen became a primary committer, triaging Jira issues and shepherding patches to sustain community momentum, knowing the language would only survive if early adopters believed it would succeed.
Despite its technical elegance, ClojureScript faced steep friction with the broader web ecosystem. While the 2011 frontend world was centered around jQuery and lightweight scripts, ClojureScript arrived tied to Google tools that web developers rarely encountered: the Google Closure Compiler for aggressive minification and dead-code elimination, and the Google Closure Library for standard browser utilities. The steep learning curve and unfamiliar ecosystem prompted Relevance to create "ClojureScript One," an opinionated starter suite designed to help newcomers navigate this novel architecture.
[09:55](https://www.youtube.com/watch?v=mty0RwkPmE8&t=595s) Google Closure Library and the Arrival of `lein-cljsbuild`
ClojureScript One was never meant to be a full-blown developer tool; it was a template project built to demonstrate that developers could create a viable application and find everything they missed from jQuery already present in the Google Closure Library. David Nolen highlights that Google Closure Library remains heavily developed by Google, serving as the actual foundation behind their production JavaScript applications alongside the Closure Compiler. While seeing the depth of Closure Library opened people's eyes, getting work done remained awkward because ClojureScript One was still just a template. Developers had to clone repositories and execute clunky custom scripts. By 2011, Leiningen had completely taken over the Clojure ecosystem:
> “By 2011 Leiningen had taken the Clojure world by storm. I mean, it's basically if it wasn't a Leiningen plugin, chances are nobody was going to use your thing.”
Around eight or nine months into ClojureScript’s lifecycle, Evan Mezeske introduced `lein-cljsbuild`. This plugin lowered the barrier to entry by making it straightforward to stand up a Ring application and add ClojureScript compilation directly into an existing Leiningen workflow. That development marked the moment Clojure programmers finally began giving ClojureScript a chance, creating real community momentum. Maintenance of `lein-cljsbuild` later shifted to Maria Geller.
[11:58](https://www.youtube.com/watch?v=mty0RwkPmE8&t=718s) Porting Persistent Data Structures to JavaScript
Many developers do not realize that ClojureScript launched without persistent data structures. For almost its entire first year, it relied on naive, slow copy-on-write collections that exposed standard Clojure interfaces without the underlying efficiency. In 2011, skepticism was high, but the JavaScript performance landscape shifted when Google assembled an elite compiler team led by Lars Bak—known for his decades of work on the Self language and the Java HotSpot VM. Google's work on V8 prompted the ClojureScript team to explore what would happen if they hand-ported Clojure's Java implementations to JavaScript.
László Török took Clojure’s persistent vector—roughly 400 lines of Java—and created a direct JavaScript port to benchmark on V8. The results were startling: the JavaScript port was only about 4x slower than the JVM, comfortably within an order of magnitude. Török then wrote a 200-line ClojureScript version of that JavaScript port, initiating the effort to implement all persistent data structures directly in a Clojure dialect rather than host-level Java.
```mermaid flowchart TD accTitle: Evolution of Persistent Vectors in ClojureScript accDescr: Diagram showing the porting sequence of persistent vectors from Java to JavaScript to ClojureScript, followed by compiler optimizations. subgraph Implementation["Vector Implementations"] A["Original Java PersistentVector (JVM)<br>~400 lines"] B["László Török's JS Port<br>~4x slower than JVM"] C["László Török's ClojureScript Port<br>~200 lines (initially 3x slower than JS)"] end subgraph Optimization["Compiler Refinement"] D["David Nolen Optimizes Code Gen<br>(Inlining arithmetic, reducing call overhead)"] E["Optimized CLJS Persistent Vector<br>~20-30% slower than handwritten JS"] end
A --> B B --> C C --> D D --> E ```
[14:31](https://www.youtube.com/watch?v=mty0RwkPmE8&t=871s) Compiler Tuning and Full Ecosystem Ports
Using persistent data structures as a performance baseline proved to be a practical way to diagnose compiler inefficiencies. Rather than relying on synthetic benchmarks that meant little in practice, Nolen used Török’s ClojureScript vector port to reveal flaws in ClojureScript’s code generation:
> “The cool thing about using persistent data structures to drive ClojureScript perf was that this is something that everybody's going to depend on. If we make this fast, then we know that we're actually delivering on performance.”
Investigating why the initial ClojureScript code ran three times slower than handwritten JavaScript exposed missing arithmetic inlining and extraneous function call overhead. Once the compiler was tuned, the ClojureScript implementation ran only 20% to 30% slower than pure JavaScript without requiring changes to Török’s source code.
Seeing that V8 handled these algorithms well—and knowing competitors like JavaScriptCore and SpiderMonkey would race to match V8's pace—Polish mathematician and programmer Michał Marczyk took on porting the rest of Clojure's persistent collections. Over roughly fourteen months, each newly ported data structure was benchmarked against the JVM to uncover further code generation flaws. When users updated their ClojureScript applications, they regularly reported immediate 10x, 20x, or 30x performance improvements.
[16:48](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1008s) The Light Table Breakthrough
Despite internal excitement within the Clojure community, mainstream adoption remained elusive throughout 2011 and 2012. While libraries like Facebook’s Immutable.js later popularized immutability, outside engineers at the time dismissed persistent data structures as academic curiosities, repeatedly asking for real-world proof of what could be built with a Lisp targeting the browser.
The perception shifted dramatically when Chris Granger unveiled Light Table. Pitching an interactive, responsive coding environment that originally planned support for Clojure, ClojureScript, Python, and Ruby, Light Table caught the attention of the broader programming world. Many of its UI and interactive ideas were subsequently adopted by mainstream tools like Swift Playgrounds, Xcode, and IntelliJ. Crucially, Granger constructed the entire desktop application out of 11,000 to 12,000 lines of ClojureScript running on Node-Webkit.
Seeing a complex, desktop-grade development environment built entirely in ClojureScript convinced skeptical developers both inside and outside the Clojure ecosystem that the language was mature enough for production software. With that validation established, the community shifted its attention to compiling Clojure in Clojure itself.
[19:32](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1172s) Debugging Woes and the Reader Column Problem
As ClojureScript reached its two-year mark, a critical bottleneck emerged around debugging and compiler bootstrapping. Developers coming from Clojure would see tools like `lein-cljsbuild` and Light Table, get excited, and start building applications. However, as soon as an error occurred, they were thrown into baffling JavaScript code. David Nolen emphasizes that unlike CoffeeScript, ClojureScript never aimed to emit human-readable output: “the only thing we cared about is how fast is it going to be you know like that's all we cared about was performance we didn't care about is this something for humans to look at”. Debugging that raw JavaScript was intensely painful, making Source Maps an absolute necessity.
For its first two years, ClojureScript lacked Source Map support entirely. While early browser implementations were slow to mature, the deeper technical obstacle lay within the compiler's reliance on Clojure's standard reader. Because ClojureScript piggybacked heavily on Clojure's original Java-based reader, it inherited an unexpected gap: the reader annotated symbols and s-expressions with file and line metadata, but it did not record the column numbers. Accurate Source Maps in modern web browsers required column precision, meaning ClojureScript was completely blocked until the reader infrastructure evolved.
```mermaid flowchart TD accTitle: The Source Map Column Resolution Flow accDescr: Diagram illustrating how tools.reader bypassed Clojure's Java reader to enable column tracking for Source Maps.
subgraph Legacy ["Legacy Clojure Reader"] A["Clojure Java Reader"] -->|"tracks file & line only"| B["No Column Data"] B --> C["Blocked Source Maps"] end
subgraph Modern ["tools.reader Migration"] D["Nicola Mometto's 'blind' (Clojure)"] -->|"ported to contrib"| E["tools.reader"] E -->|"adds column metadata"| F["Accurate AST Locations"] F --> G["Browser Source Maps"] end ```
[21:26](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1286s) The Community Delivers: `tools.reader` and Source Maps
The breakthrough came from community member Nicola Mometto, who created a project called Blind—a faithful, pure-Clojure implementation of the Clojure reader. This offered two enormous advantages: being written in Clojure rather than Java meant it could eventually run in ClojureScript itself, and it decoupled reader development from the core Clojure release cycle. Because the Clojure core team was busy juggling higher-priority concerns, getting column metadata into the official Java reader would have taken an extended timeline. With Mometto as the sole maintainer of Blind, Nolen convinced him to move the project under Clojure Contrib as `tools.reader`. Mometto added column tracking, allowing ClojureScript to swap out the Java reader entirely.
With column metadata in place, Nolen spent two exhausting weeks tackling Source Maps during his off-hours while working full-time at *The New York Times*. The specification—a complex, MIDI-inspired Base64 Variable-Length Quantity (VLQ) encoding format—was miserable to implement and debug. Feeling burned out and unsupported, Nolen shelved the branch for two months. The project was rescued when Sean Grove appeared on IRC. Grove was building a commercial product in ClojureScript, was losing his mind reading generated JavaScript, and offered to help. Grove pushed the branch 98% of the way to completion, leaving Nolen to wrap up the final 2%. Roughly two years and one month after ClojureScript's initial launch, Source Maps officially landed. The result allowed developers to inspect syntax-highlighted Clojure code, set breakpoints, and step-debug directly inside Chrome DevTools, prompting Nolen to marvel that “it's like your browser is a lisp machine”.
- Nicola Mometto created the pure-Clojure reader `blind`, which transitioned into the official `tools.reader` library. - David Nolen worked on Source Maps on nights and weekends while employed at *The New York Times* in 2012. - The Source Map format's bit-level Base64 VLQ compression made manual debugging notoriously frustrating. - Sean Grove contributed roughly 98% of the remaining implementation work needed to finish the initial Source Map support.
[24:52](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1492s) JavaScript Modules and Maria Geller's Compiler Work
While improvements like Source Maps addressed immediate pain points, David Nolen also looked ahead to long-term ecosystem shifts, specifically JavaScript module compatibility. The broader JS ecosystem was rapidly fragmenting across competing module specifications—ES6 modules, AMD, standard CommonJS, and Node.js's custom dialect of CommonJS—while developers increasingly wanted to consume libraries published to npm. Predicting that module consumption would become a critical requirement years down the road, Nolen proposed JS module integration as a Google Summer of Code project.
The project was picked up by Maria Geller, who had only been writing Clojure for about three months. Despite her relative newcomer status, Geller tackled compiler internals and emerged as a ClojureScript compiler authority. She even accomplished a rare feat among outside contributors: getting patches accepted upstream into Google's Closure Compiler. Nolen noted that Google maintains automated infrastructure to immediately roll back any commit that breaks Google's internal codebases, making upstream contributions exceptionally challenging. Geller's work successfully improved module handling, illustrating Nolen's broader message about contributing:
> “...it's really not it's it's if you're writing closure or closure script programs it's the same stuff you know we we have multi methods and and we have maps and we have vectors it's all the same stuff it's really not any more complicated than what you're doing...”
He strongly urged the audience to watch Geller's talk from Clojure/conj, where she deconstructs the compilation pipeline into approachable, understandable phases.
[28:09](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1689s) The Realities of Open Source and the `clojure.pprint` Delay
Turning to the less glamorous side of open-source maintenance, Nolen noted that progress often mirrors maintainer interest: “open source is is a funny thing you know basically what happens with open source is you work on stuff when you want to work on it because nobody's paying you to do it right”. A consequence of unpaid, volunteer development is that unappealing tasks can sit neglected for years.
A prime example was `clojure.pprint` (pretty printing). Although widely used across tools and daily developer workflows in Clojure, `pprint` remained completely unported to ClojureScript for four full years simply because Nolen could never bring himself to dig into its dense implementation.
[28:50](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1730s) Porting pprint and Filling Core Library Gaps
David Nolen recalls that one of the most frustrating omissions in early ClojureScript was `clojure.pprint`. The Clojure version was written in 2009-era Clojure code, ported from an ancient Common Lisp pretty printer, and relied heavily on legacy constructs like `defstruct`. Spanning roughly 3,000 lines of arcane code, it was so intimidating that Nolen admits he could never bring himself to tackle it: “every time I would look at it I would close my tab right I was like cannot bring myself to do this”. This missing namespace was a major source of friction for newcomers who loved Clojure's standard library and could not understand why such a fundamental tool was missing when trying to inspect large application state atoms in frameworks like Reagent, Rum, or Om.
The impasse was finally broken when the community took the initiative. Jonathan Boston and Shaun Lebron authored what Nolen describes as perhaps the single biggest patch in the project's history—a massive 3,000-line patch implementing pretty printing in ClojureScript. Having native `pprint` meant developers debugging complex state in modern client-side apps could finally inspect their data structures without tearing their hair out, marking another milestone where volunteer open-source contributions rescued an essential piece of tooling from languishing.
[30:18](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1818s) Native Testing Support: Closing the Standard Namespace Gap
Another critical feature that remained unaddressed for nearly four years was built-in testing. Clojure had prioritized testing before version 1.0 when Rich Hickey added support for `:test` metadata directly on functions, treating testing as an essential first-class language feature. ClojureScript, however, lagged behind without an official out-of-the-box solution. While Chas Emerick (co-author of O'Reilly's *Clojure Programming*) had created a widely used third-party testing library, relying on external dependencies for baseline capabilities created unnecessary friction for developers expecting language parity.
Nolen eventually stepped in to build what became `cljs.test`, rounding out the core namespaces. With native testing in place alongside the earlier standard library additions, ClojureScript finally provided all core Clojure functionality that did not explicitly depend on JVM multi-threading. Nolen notes that developers arriving in 2016 entered a much smoother ecosystem, reflecting that “if you're coming to closure script right now in like in 2016 you're really lucky you missed you missed some a lot of turbulence”.
- **Clojure parity milestone:** With `cljs.test` resolved, the core namespaces reached near-total parity with Clojure, excluding JVM-specific multi-threading primitives. - **Timeline:** Key features like pretty printing and standard testing took roughly four full years of effort before achieving built-in status.
[31:45](https://www.youtube.com/watch?v=mty0RwkPmE8&t=1905s) Delivering on "Reach": Mike Fikes and Untethered iOS Development with Ambly
When Rich Hickey originally unveiled ClojureScript, a central thesis was "reach"—providing a single language that could target not just the web, but mobile platforms like iOS and Android. Yet for four years, practical mobile implementations remained elusive. That changed when Mike Fikes, known as the creator of Plank, shipped a production application to the Apple App Store using ClojureScript and built foundational open-source tooling for mobile development.
To solve the mobile workflow, Fikes created Ambly, a custom REPL server that reimagined the iOS development loop. Because Ambly required specialized capabilities, the ClojureScript compiler team refactored the core REPL abstractions to make building custom REPL environments easier. Ambly uses Bonjour/ZeroConf (multicast DNS) to discover an iOS device automatically across the local Wi-Fi network. Once the developer selects the device from the desktop terminal REPL, Ambly establishes a direct socket connection to JavaScriptCore on the device and synchronizes compiled assets over WebDAV. This setup enabled genuine interactive live coding directly on iOS hardware, untethering developers completely from Xcode after the initial bootstrapping phase and fulfilling the early vision of reaching mobile environments.
```mermaid flowchart TD accTitle: Ambly REPL Architecture for iOS accDescr: Diagram showing desktop compiler connecting to iOS device over Bonjour, WebDAV, and socket to JavaScriptCore.
subgraph Desktop["Developer Workstation"] D_REPL["Ambly REPL Client"] D_COMP["ClojureScript Compiler"] end
subgraph Discovery["Network Discovery"] M_DNS["Bonjour / ZeroConf (Multicast DNS)"] end
subgraph Mobile["iOS Device"] APP["Host App Running JavaScriptCore"] DAV["Embedded WebDAV Server"] end
APP -.->|"Broadcast presence"| M_DNS M_DNS -.->|"Discover device"| D_REPL D_REPL -->|"Socket connection (Eval/Read)"| APP D_COMP -->|"Sync compiled JS files"| DAV DAV -->|"Load runtime code"| APP ```
- **Zero-configuration connection:** Ambly automatically locates target devices on the local Wi-Fi network, allowing users to enter a device number and instantly connect. - **Untethered workflow:** Xcode is only required once to compile and launch the initial host runner; all subsequent development happens interactively via the ClojureScript REPL and live file syncing. - **React Native horizon:** These mobile breakthroughs laid the groundwork for integrating ClojureScript with emerging platforms like React Native.
[34:21](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2061s) Reader Conditionals and Self-Hosting: Compiling the Compiler
Nolen recounts that for the first four years, ClojureScript did not use conventional semantic versioning, relying instead on raw Git build numbers up to revision 3225. The shift to standard version numbers coincided with the release of Clojure 1.7, which introduced reader conditionals and the unified `.cljc` file extension. Previously, sharing logic across `.clj` and `.cljs` files required awkward, unofficial third-party preprocessors. The arrival of reader conditionals provided an official mechanism for cross-platform code sharing, prompting Nolen to immediately attempt an ambitious goal: self-hosting the compiler.
As soon as Clojure 1.7 landed, Nolen updated ClojureScript's dependencies and set to work porting the compiler and analyzer to `.cljc` so ClojureScript could compile itself. Nolen spent a month methodically fixing analyzer and compiler incompatibilities until the pipeline could successfully process its own codebase. The result was a fully self-hosted ClojureScript implementation that could run in pure JavaScript environments without any dependency on the JVM, realizing a classic Lisp milestone.
[36:20](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2180s) The Bootstrapping Breakthrough and Its Ecosystem Impact (Plank, Replete, KLIPSE)
Nolen highlights that bootstrapping ClojureScript proved surprisingly elegant because of how ClojureScript strictly separates phases. In ClojureScript, macro expansion occurs strictly at compile time, completely decoupled from runtime execution: “there are two distinct phases in closure script there's macro time and there's runtime and they'll never meet but that means bootstrapping closure script was a very very very straightforward affair”. In the macros file (`cljs.core`), macros require the analyzer and standard library to tie the metacircular knot. Because compilation and runtime do not cross-talk dynamically, self-hosting only required compiling the analyzer and compiler to JavaScript and concatenating them with the standard library.
This self-hosted compiler opened up an entire ecosystem of standalone ClojureScript tools that boot instantly without the JVM:
- **KLIPSE:** A web-based tool enabling live code evaluation and interactive documentation demos entirely inside the browser. - **Plank:** A fast, lightweight command-line REPL for macOS and Linux built on top of JavaScriptCore. - **Replete:** A full-featured ClojureScript REPL running natively on iOS devices. - **Parinfer integration:** Tools like Replete incorporated Parinfer, an editor innovation from the Clojure community that automatically manages Lisp parentheses based on line indentation, making mobile REPL hacking seamless on standard on-screen keyboards.
Nolen concludes this retrospective by emphasizing how many people, architectural iterations, and quiet multi-year efforts were required to take ClojureScript from an experimental offshoot to a mature, self-hosted, multi-platform language ecosystem.
[38:30](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2310s) Community Contributions and the React Revolution
David Nolen reflects on the broader ClojureScript ecosystem, emphasizing that while he cannot showcase every photograph or name, the project owes its success to a collective effort of approximately 141 contributors. No contribution has been too small: anyone who opened an issue, logged into IRC to ask if a feature was working as intended, filed a ticket, or submitted a patch shares credit for making the language what it is today. As Nolen asserts: “ClojureScript is as good as it is today because everybody that's worked on it.”
The trajectory of the language changed dramatically with the introduction of React. Previously, ClojureScript faced skepticism because having immutable data structures felt pointless when developers still had to manipulate the mutable DOM. React opened the floodgates, creating a Cambrian explosion of UI libraries and pushing ClojureScript far ahead of mainstream web development. Nolen recalls attending a React conference where developers were pitching Flux, eliciting an unenthusiastic reaction from ClojureScript developers who had already leapfrogged those design patterns. Beyond UI frameworks, other community tools transformed the day-to-day workflow:
- **binaryage/cljs-devtools**: Created by an author known online as Darwin, this Chrome extension hooks into browser custom object formatters. Instead of forcing developers to inspect tangled, raw JavaScript objects when logging vectors or stepping through the debugger, it prints native ClojureScript data structures cleanly in the console. - **Shadow-build (shadow-cljs)**: Developed by Thomas Heller as an alternative build tool, it pioneered several major features long before ClojureScript core implemented them, proving that competing out-of-tree experiments are vital sources of innovation.
```mermaid flowchart LR accTitle: Shadow-build Innovations Adopted by ClojureScript Core accDescr: Diagram illustrating features originating in Thomas Heller's shadow-build and later making their way into ClojureScript core.
subgraph SB["shadow-build (Thomas Heller)"] M["Google Closure Modules<br/>(Code Splitting)"] I["Macro vs. Runtime<br/>Var Inference"] end
subgraph Core["ClojureScript Core"] CSM["Native Module Code Splitting<br/>(Months later)"] CSI["Automatic Macro Inference<br/>(Removed need for:refer-macros)"] end
M -->|"Pioneered"| CSM I -->|"Pioneered"| CSI ```
- Thomas Heller's shadow-build included Google Closure module support for code splitting months before core ClojureScript adopted it. - Shadow-build pioneered inferring whether a symbol was a macro var or a runtime var, eliminating the long-standing requirement for developers to manually write `:refer-macros`.
---
[41:46](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2506s) The Next Five Years: Priorities and Core Compiler Improvements
Looking toward the future, Nolen describes ClojureScript's development philosophy not as a rigid five-year master plan, but as an organic evolution: “It's sort of a random walk in the right direction right, so you can expect the next five years it's probably going to be a random walk in the right direction; things will happen when people want them to happen.”
Historically, parity with Clojure has remained the single highest priority because discrepancies between the two languages represent the biggest source of user frustration. The main effort focuses on `clojure.spec`, where ClojureScript has matched features up to Alpha 11, with ongoing work to maintain parity as new versions land. Nolen expects the community will spend the next two years exploring what spec makes possible. Beyond language parity, several concrete compiler improvements are high on the agenda:
- **Google Closure Compiler Integration**: Staying current with Google's upstream changes to the Closure Compiler and module systems, which require constant adaptation because Google optimizes primarily for internal users rather than external consumers. - **Compiler Performance**: In five years, no dedicated pass had been made on serial compiler performance. While Nolen previously implemented a parallel build feature to split compilation across multiple CPU cores for production builds, single-threaded throughput had never been optimized. Nolen estimates an untapped 2x speedup in serial compilation, which could take a 30-second build down to 15 seconds, and down to 7 seconds when combined with parallel builds. - **Windows Support**: Despite a smaller Windows user base, Nolen welcomes contributions and pledges immediate review: “If you're a Windows user and you have a patch, there's a chance I will apply it immediately, the moment I get a Windows patch it'll probably get applied because we care; we want our stuff to work great everywhere.” - **Testing Infrastructure**: ClojureScript needs more automated test coverage across its various compiler flag combinations, generative tests for runtime behavior, and a long-term runtime performance benchmark harness to monitor generated code over time.
---
[45:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2710s) Spec-Driven Type Checking, Public APIs, and the Externs Problem
Turning to forward-looking compiler architecture, Nolen highlights how `clojure.spec` could directly improve ClojureScript’s output. Although full recursive validation is unsuitable for compile-time checking, simple specs could trivially translate into Google Closure type annotations. If the ClojureScript compiler knows whether an argument is nillable, a number, a map, or a vector, it can emit static type assertions that Google Closure Compiler uses to catch errors before code reaches production.
Nolen also emphasizes the necessity of maintaining robust, public compiler APIs. Tools like Bruce Hauman's Figwheel—widely used across the audience—depend entirely on compiler hooks to offer polished experiences, including detailed, Elm-style compiler error messages that pinpoint exact problem locations in the source code.
```mermaid flowchart TD accTitle: Spec Validation and Externs Pipeline accDescr: Shows how clojure.spec feeds type checks into the Google Closure Compiler and highlights the pain point of externs.
subgraph Compile["ClojureScript Compilation"] Spec["clojure.spec Metadata"] -->|"Emit basic static checks<br/>(nillable, map, vector)"| GCC["Google Closure Compiler"] Hooks["Public Compiler APIs"] -->|"Expose error locations"| Tools["Figwheel / Tooling<br/>(Elm-quality errors)"] end
subgraph Problem["External JS Ecosystem"] JS["Third-party JS / React Libs"] -.->|"Name minification without externs"| Break["Broken Production Builds"] end
GCC --> Break ```
The final hurdle Nolen introduces before pivoting is the persistent frustration of JavaScript interop: “Probably the largest source of incidental complexity in ClojureScript—ClojureScript is awesome, but there's things that are not awesome—is externs.” Whenever a developer incorporates an external library such as React, Highcharts, or a third-party npm package, advanced optimizations in the Google Closure Compiler rename unreferenced properties and break production releases unless explicit externs declarations instruct the minifier to preserve those exact symbol names. Nolen has begun prototyping native compiler solutions to remove this friction once and for all.
[47:17](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2837s) Eliminating Externs and Getting Involved in ClojureScript
David Nolen identifies externs as one of the last major pain points when integrating ClojureScript with third-party JavaScript libraries. Because Google Closure Compiler's advanced optimizations rename properties aggressively, missing an extern breaks production builds in subtle ways. Nolen admits that even he falls victim to this trap: “It's extremely error-prone, even I run into this: I do an advanced build, oh my god, I'm ready to go to production and it doesn't work because I missed an extern, right? It's a huge source of incidental complexity.” He views this as an entirely solvable problem and places automated extern inference on the near-term roadmap, noting that eliminating handwritten extern files will be a gigantic leap forward for seamless interoperability with the broader JavaScript ecosystem.
Achieving these milestones, however, depends on growing the contributor base. Nolen demystifies the contribution workflow, urging community members to submit a Clojure Contributor Agreement (CA) preemptively. He explains that unexpected edge-case bugs surface even after half a decade in production—such as persistent maps unexpectedly breaking past nine entries under specific conditions—and fixing them often requires just a trivial patch that any Clojure developer can write. For those wanting to collaborate, Nolen points to the `#cljs-dev` channels on IRC and the Clojurians Slack, encouraging newcomers to lurk, pick low-hanging fruit in JIRA, test open patches, and leave confirming comments.
- **Externs Roadmap**: The explicit goal is to completely remove the requirement of writing manual extern files for third-party JavaScript dependencies. - **Contributor Agreement**: Submitting a CA early ensures that when developers encounter a small bug, there is zero administrative friction preventing a patch submission. - **Low-Hanging Fruit**: Contributing does not require tackling complex compiler internals; testing existing JIRA patches or submitting trivial bug fixes provides immense value.
---
[49:13](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2953s) Normalizing Lisp, Giving Talks, and "Alien Technology"
Looking out at the audience of roughly 300 people, Nolen expresses excitement at the size of the gathering, observing that it rivals or exceeds many mainstream JavaScript conferences he attends. He reflects on his journey starting around 2008 with Common Lisp, which felt too eccentric and isolated for mainstream development. Clojure and ClojureScript fundamentally altered that perception. Today, seeing Clojure code discussed routinely on Hacker News, Reddit, and personal engineering blogs is completely normal. Nolen emphasizes that non-code advocacy—authoring blog posts about experiences with libraries like Reagent, Rum, or React Native—is among the most impactful contributions anyone can make toward technology adoption.
He also encourages developers to present ClojureScript at regional meetups and conferences. When the wider community actively promotes the language, core maintainers are freed from having to travel constantly to evangelize. In Nolen's view, pragmatic demonstrations matter far more than abstract rhetoric: “You can talk about fancy language features all day, but really developers are convinced when you show them something cool.” Concluding his talk, Nolen marvels that despite his years of working directly on the codebase, ClojureScript never loses its magic: “The reason I love ClojureScript is that every time I fire it up it really feels, even though I've contributed so much to it, it feels like alien technology; it feels like I can't believe you can do this stuff, it's so cool.”
- **Community Advocacy**: Writing tutorials and giving presentations at local meetups relieves the core team from carrying the entire promotional burden. - **Shared Tooling**: Nolen highlights that the core team dogfoods the exact same ecosystem tools as everyday users, including `lein-cljsbuild`, Boot, and Figwheel.
---
[51:50](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3110s) Q&A: Backporting ClojureScript Concepts into Clojure
An audience member asks whether the Clojure core team has considered backporting parts of ClojureScript into Clojure itself—specifically rewriting Clojure compiler internals in Clojure rather than Java, migrating Java-based persistent data structures, or moving protocols deeper into core.
```mermaid flowchart TD accTitle: Clojure and ClojureScript Compiler Relationship accDescr: Diagram illustrating how Rich Hickey's original ClojureScript implementation informs future Clojure-in-Clojure compiler designs. subgraph ClojureHistory["Historical Foundation"] C1["Rich Hickey writes original ClojureScript compiler"] C2["First concrete vision of Clojure-in-Clojure"] end subgraph Evolution["ClojureScript Evolution"] CS1["ClojureScript implemented in Clojure"] CS2["Refined protocol architecture & optimizations"] end subgraph FutureLoop["Future Architecture"] SPEC["Current focus: clojure.spec"] NEXT["Future Clojure compiler revisitation"] end
C1 --> C2 C2 --> CS1 CS1 --> CS2 CS2 -.->|"Feedback loop & lessons learned"| NEXT SPEC -.->|"Pushed to future cycles"| NEXT ```
Nolen explains that while there have been no formal discussions about copying code directly, ClojureScript's architecture is bound to influence future compiler designs. With `clojure.spec` serving as the primary engineering focus for the core Clojure team at the time, fundamental compiler redesigns remain on the back burner. However, Nolen points out that Rich Hickey himself authored the original ClojureScript compiler as his initial exploration of what Clojure written in Clojure would look like: “Rich wrote the first version of the ClojureScript compiler, so that was his idea of what a Clojure-in-Clojure would look like; so I'm convinced that whenever they go back to do it again, it's going to be heavily informed by how we did it in ClojureScript.”
---
[53:40](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3220s) Q&A: Mori and Its Influence on Immutable.js
Asked about where Mori fits into the history of ClojureScript, Nolen recounts extracting ClojureScript’s persistent data structures in 2012 to create a standalone library with an idiomatic JavaScript API for Node.js and browsers. The performance was striking: benchmarks demonstrated that constructing a persistent transient vector in Mori was faster than building a native mutable JavaScript array of one million elements on V8. Despite these numbers, JavaScript developers showed little interest for nearly two years.
That dynamic shifted dramatically with the emergence of React in 2014. Once developers realized that immutable data structures made component re-rendering checks trivial via reference equality (`===`), Mori suddenly gained traction. Nolen notes that Mori and his associated conference talks directly inspired Facebook to create Immutable.js: “It took two years before anybody in the JavaScript community cared about Mori, but with Mori, because I talked about Mori and I talked about React, I think a lot of that influenced Facebook to do Immutable.js.” He emphasizes that benchmarks alone rarely sway programmers; adoption usually requires an external catalyst like React to make the benefits immediately tangible.
- **Mori Origin (2012)**: Packaged ClojureScript persistent vectors, maps, and sets into an idiomatic npm/browser module. - **Benchmark Anomaly**: Transient vector instantiation outpaced native JavaScript mutable array creation at scale (1,000,000 elements). - **The React Catalyst (2014)**: Fast reference comparisons in virtual DOM architectures provided the missing real-world motivation for JavaScript developers to embrace immutable collections.
---
[55:47](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3347s) Q&A: The Status of JavaScript Module Support
An attendee asks about the status of native JavaScript module support worked on by Maria Geller during Google Summer of Code (GSoC) and whether that project still has momentum. Nolen clarifies that Geller is heavily committed maintaining `lein-cljsbuild` as well as Mori, leaving limited bandwidth for ongoing module development. While her GSoC implementation functions as originally presented—allowing developers to bundle AMD and CommonJS modules with measurable success—it faces maintenance challenges, including breaking interface changes introduced upstream by Google Closure Compiler that must be addressed when ClojureScript updates its compiler dependency.
Beyond compatibility fixes, Nolen articulates a far more ambitious end goal for module integration. The real benchmark is complete compatibility with Closure's dead-code elimination. Under this model, an engineer could import a single module like `react.Component`, and Google Closure Compiler would automatically strip away every unused line of React from the final production bundle. Nolen sums up the overarching vision: “That's the actual target, that we basically make the rest of the JavaScript world conform to us, which is that their code becomes optimizable. That's the real goal here, right? Is that you can take some random JavaScript library and you can now apply all the benefits that we have with ClojureScript code.”
[57:34](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3454s) Dead Code Elimination and Third-Party JavaScript
David Nolen explains the unique power of ClojureScript's compilation model when paired with Google Closure. Unlike the prevailing mindset in the broader JavaScript ecosystem, ClojureScript developers do not have to worry about fine-grained packaging just to keep bundle sizes manageable. If a developer pulls in a large ClojureScript library but only calls a single function, the compiler ensures that only that single function ends up in the final output. This whole-program dead code elimination frees developers from what Nolen terms the "myopic view of the world where you have micro-modules."
The ultimate goal is extending this exact same capability to code outside the ClojureScript ecosystem. Third-party JavaScript libraries—whose upstream architecture ClojureScript authors cannot control—should ideally be processed through Google Closure Compiler in the same aggressive way. Nolen emphasizes: “This is awesome we don't have this this myopic view of the world where you have micro modules we don't care because Google Closure eliminates all the stuff you don't use and I would like to be able to know that even third-party JavaScript libraries that we cannot control the development of we are able to apply this same optimization techniques to.”
[58:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3490s) Q&A: WebAssembly as a Potential Target
An audience member asks whether WebAssembly (Wasm) represents good news for ClojureScript. Nolen confirms that it is certainly not bad news, noting immediate and practical possibilities. Developers writing performance-sensitive numerical calculations or game engines could construct a specialized domain-specific language (DSL) that compiles directly to WebAssembly to yield hyper-optimized functions alongside standard ClojureScript code.
However, adopting WebAssembly as a full compilation target for ClojureScript presents significant technical hurdles. The fundamental constraint is garbage collection. Like Clojure on the JVM, ClojureScript fundamentally assumes the availability of an integrated, high-performance runtime garbage collector. Because WebAssembly lacks native GC integration, anyone targeting it directly would currently have to bundle and run their own garbage collector, which Nolen characterizes as a potential "performance nightmare." While the WebAssembly committee is well aware of this constraint and actively addressing it, any shift will take time. Nolen remarks: “If it becomes a desirable target there's no question we will target it if it if it's the right thing but it's cool it's is absolutely cool it definitely closes the gap in the types of performance you would get expect to get out of a browser environment.”
- Immediate potential: specialized DSLs for numeric computation or browser game engines. - Primary architectural obstacle: absence of built-in garbage collection in the early WebAssembly specification. - Long-term horizon: estimated at six to ten years (or sooner, depending on how fast the WebAssembly specification matures).
[59:34](https://www.youtube.com/watch?v=mty0RwkPmE8&t=3574s) Q&A: Maria Geller's Work vs. Externs Inference
Another attendee asks whether Maria Geller’s Google Summer of Code project on module processing and the recently discussed externs inference work are competing, identical, or complementary approaches. Nolen clarifies that both efforts are complementary strategies attacking the broader JavaScript interop problem from different sides.
If a developer can directly consume modern ES6 modules through Google Closure Compiler, Google Closure understands the symbol references natively, which removes the need for externs altogether. However, the ecosystem remains messy: one ES6 library might work seamlessly out of the box, whereas another library might fail under advanced compilation. In cases where a stubborn library must simply be bundled as an un-optimized foreign dependency kept outside of advanced compilation, automated externs inference steps in to ensure ClojureScript code can call it without hand-writing error-prone extern files. David Nolen summarizes the unified goal of these tools: “All of these things are designed to make integration with the wider ecosystem better um but they're sort of attacking it from two different ways.”
```mermaid flowchart TD accTitle: JavaScript Ecosystem Integration Strategies accDescr: Diagram illustrating how Module Processing and Externs Inference handle third-party JavaScript libraries under Advanced Compilation.
subgraph Input["Third-Party JS Library"] JS["JavaScript Dependency"] end
subgraph Strategies["Integration Pathways"] MProcess["Module Processing (Maria Geller's Work)<br/>Direct ingestion of ES6/CommonJS modules"] ExtInf["Externs Inference<br/>Automatic inference of external JS calls"] end
subgraph Pipeline["Closure Compilation"] AdvComp["Google Closure Advanced Compilation<br/>Dead code elimination & symbol minification"] Foreign["Foreign Dependency Build<br/>Excluded from minification"] end
JS -->|"Supported ES6 Module"| MProcess MProcess --> AdvComp
JS -->|"Incompatible / External Script"| Foreign ExtInf -->|"Protects interop symbols"| Foreign AdvComp -.->|"Safely references"| Foreign ```
With the final questions answered, David Nolen closes the session by thanking the audience for their patience and attention over the presentation.
## Notable quotes > [49:13](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2953s) You can talk about fancy language features all day, but really developers are convinced when you show them something cool. — David Nolen
> [45:10](https://www.youtube.com/watch?v=mty0RwkPmE8&t=2710s) Probably the largest source of incidental complexity in ClojureScript—ClojureScript is awesome, but there's things that are not awesome—is externs. — David Nolen
> [14:31](https://www.youtube.com/watch?v=mty0RwkPmE8&t=871s) The cool thing about using persistent data structures to drive ClojureScript perf was that this is something that everybody's going to depend on. If we make this fast, then we know that we're actually delivering on performance. — David Nolen
## Mentioned Alex Miller, Ambly, AMD, binaryage/cljs-devtools, Boot, Bruce Hauman, Chas Emerick, Chris Granger, Chris Houser, Clojure, Clojure Contributor Agreement, ClojureScript, ClojureScript One, clojure.spec, Clojurians Slack, CoffeeScript, Cognitect, Common Lisp, CommonJS, Dart, Darwin, David Nolen, ES6, Evan Mezeske, Facebook, Figwheel, Florian Loitsch, Google Closure Compiler, Google Closure Library, Google Summer of Code (GSoC), Google Web Toolkit (GWT), Hacker News, Highcharts, Immutable.js, IRC, Java, Jeremy Ashkenas, JIRA, Jonathan Boston, JVM, KLIPSE, Lars Bak, László Török, Leiningen, lein-cljsbuild, Light Table, Maria Geller, Michał Marczyk, Mike Fikes, Mori, Nicola Mometto, Node-Webkit, Node.js, npm, Om, Parinfer, Plank, React, React Native, Reagent, Reddit, Relevance, Replete, Rich Hickey, Rum, Scheme2Js, Sean Grove, shadow-build (shadow-cljs), Shaun Lebron, The New York Times, Thomas Heller, tools.reader, V8, WebAssembly (Wasm), Windows
## Video description With five years behind us, the history of ClojureScript is already becoming murky. This talk attempts to document the many interesting landmarks along the way before we forget them. By pausing to reflect on how much ground we have collectively covered, we also hope to form a clearer picture of the next five years ahead of us. Spoiler alert: the best is yet to come!
[Source](https://www.youtube.com/watch?v=mty0RwkPmE8)