February 25, 2025
by Pablo Mayrgundter
Tech Talk: High-Performance JS Parsing, Complete IFC+STEP Coverage, Exact Bools
An Interview with Conor Stokes
Pablo: Welcome to our first post in a new tech talk series! Today, I'm chatting with Conor Stokes, our programming lead on the Conway CAD engine.
First, some history. Conway started as a fork of the IFC.js/web-ifc project in 2023. web-ifc was great for initial demos and product planning, but the community never really coalesced and we wanted to make major changes for quality, performance and flexibility towards more general CAD applications.
We recently had our initial open source release in Q4'23 and are ready to share more with the community!
Pablo: So Conor, we knew from the start that getting a powerful CAD application into the browser would be a technical challenge, but also that strides in WASM and JS performance from Web 2.0 had shown the way for even the most challenging web-based apps.
"Fast is our favorite feature"
Pablo: Our first focus was JavaScript parsing performance. Can you tell the story how we approached this, maybe starting with the initial document parse.
Conor:
Sure! The big win comes from shifting away from classic string-based parsing toward typed arrays (like Uint8Array) and UTF-8 encoding. This change eliminates most garbage collection overhead because we operate on a byte-by-byte level instead of constantly allocating or deallocating new strings. We also sprinkle in a few additional techniques:
- Lazy Parsing & Memoization – We avoid work until it's actually needed and cache results wherever possible.
- Index Pre-Pass – We do a quick pass to figure out where data lives, so we don't re-scan everything later.
- C++ Extensions – Certain time-critical sections we move to C++ modules compiled to WebAssembly for near-native performance.
All of this comes together to give us performance that's close to a compiled language, especially for query-intensive workloads.
JIT Compilers and Class Hierarchies
Pablo: We have designed our class system to leverage JavaScript's JIT optimization. Can you elaborate?
Conor: Each JS engine (V8, SpiderMonkey, etc.) has its own JIT nuances, but certain best practices are consistent:
- Static Class Assignments: If you have well-known classes, it helps the JIT compiler optimize by avoiding shape changes.
- Minimizing Virtual Calls: We keep the class hierarchy fairly simple and rely on lazy indexing for field lookups. That means fewer slowdowns from polymorphic lookups.
These JIT-friendly design choices really helped keep execution fast and consistent across different browsers.
Where Antlr Fits: IFC & STEP Parser Generation
Pablo: For those who aren't familiar, what's IFC Gen, and how does it fit into the workflow?
Conor: IFC Gen is our proprietary code-generation layer. It uses Antlr (a parser generator) to produce a class hierarchy that covers the full IFC specs published by buildingSMART. This borrowed some initial work by Hypar.io, and then we rewrote the base classes and generated structures to create our object model.
It's worth noting that the specs themselves are huge, with ~7,000 pages of documentation across 1,000+ types. Only about 10% of them are geometry related, with BIM encompassing much more about the building process, roles, materials and purchasing, construction stages and more.
The key point is that we are able to achieve complete spec coverage while not generating a bloated object model. Antlr does its job at compile time — generating the scaffolding for all the classes we'll need — then it steps out of the way. At runtime, Conway handles actual parsing and byte array manipulation in an optimized, custom way that avoids realizing the size of the overall spec when working with any given element.
Once we had that setup for IFC 2x3 and 4, we took a shot at STEP AP214. It's an ISO spec with shared lineage to IFC, that addresses parts in the automotive and 3d printing space. While IFC support took around 9 months, initial STEP support has taken a few months and we think the other STEP specs (Aerospace, Electrical, etc) will now be reachable in relatively short order.
Conway Proper, Conway Geom, and Data Extraction
Pablo: So once we have that generated code, what's the lifecycle of data in our system?
Conor:
- High-Level Indexing – Conway proper does a quick pass to identify where each piece of data resides.
- Object Extraction – We create objects from the IFC classes on-the-fly using a flyweight pattern, which keeps memory usage efficient.
- Lazy Loading & Memoization – Not everything is loaded at once. We bring in data only when we need it, and we cache frequently accessed parts.
- Geometry Generation – Finally, we pass the processed data to Conway Geom, which handles geometry creation of CSG, BREP & NURBS, and then off to the renderer.
We're also working on an event-driven approach that will let the render side populate objects without data copying, so it's all about optimizing the pipeline from parsing to the final draw call.
Data Transfer to WebGL
Pablo: Speaking of draw calls, you mentioned a shim currently copies data to WebGL. Any plans to reduce that overhead?
Conor: Yes! For WebGL, we can technically tap into the WebAssembly (WASM) memory directly, so we don't have to copy data out to JavaScript arrays first. For instance, in Three.js, we can slice typed arrays as "views" into WASM memory. This eliminates a whole bunch of overhead. We also use instancing to cut down on repeated geometry data.
Zero-Copy, IFC5
Pablo: That begs the question: how far can we take zero-copy performance?
Conor: In an ideal world, we'd do true zero-copy — like using memory-mapped buffers or DMA. But browsers vary in how they implement this under the hood, so it may still end up copying in the graphics driver. That said, adopting a native data format — like a USD-style pack — can push us closer to real zero-copy. There's talk of IFC5 possibly going in this direction. If so, that would be a game-changer for direct file-to-GPU workflows.
Our New Constructive Solid Geometry (CSG) System
Pablo: We have a new CSG approach. How does it differ from web-ifc's fuzzybools library?
Conor: Fuzzybools was a good heuristic start, but can produce weird or inconsistent results on complex geometry, and debugging models with it is often whack-a-mole; solving a geometry problem in one model can bring up new problems in others.
Our approach uses exact predicates, which is a more mathematically rigorous system that avoids floating-point drift. We do pay some cost in complexity and are still in early versions, but it means we can handle huge models reliably without random failures or ambiguous edges. (We've drawn our methods from "Exact predicates, exact constructions and combinatorics for mesh CSG", Lévy et al. 2024 — arxiv.org/pdf/2405.12949.)
Pablo: What makes that feasible, performance-wise?
Conor: We rely on a combination of:
- AABB (Axis-Aligned Bounding Box) Structures for spatial partitioning.
- Generalized Winding Numbers to quickly figure out how solids overlap.
- Parallelization to leverage multiple cores, especially for big meshes.
Despite exactness adding overhead, the parallel approach is incredibly fast. In some cases, we're outpacing desktop CAD software on heavy datasets.
Looking Forward
Pablo: Any final thoughts on next steps or new experiments on the horizon?
Conor: Absolutely. We're excited to keep refining our zero-copy data paths to WebGL, possibly adopt or help shape the work on IFC5, and keep iterating on the exact-predicate approach for CSG. The ultimate goal is to have a real-time collaborative CAD platform that runs smoothly in a browser — no compromises on performance or precision.
Closing Thoughts
We've covered quite a bit: JavaScript parsing performance, IFC generation, data extraction, zero-copy possibilities, and a deep dive into our new CSG system. It's an exciting time for the project, and Conor's insights underscore just how high-performance can be achieved in the modern browser environment.
Stay tuned for more tech talks as we explore further developments in our CAD engine and highlight the brilliant minds behind the code.
Thanks for reading, and a special thanks to Conor for sharing these details! If you have questions, drop us a line in the comments, and we'll do our best to address them in the next post.
This post is part of our ongoing Tech Talk series, where we bring you the latest behind-the-scenes updates on our development work at Bldrs.ai.