Article URL: https://magik.net/freecad/ Comments URL: https://news.ycombinator.com/item?id=48867264 Points: 31 # Comments: 20

It started with a Hacker News thread: LibreCAD, the whole Qt desktop application, compiled to WebAssembly and running in a tab. magik shipped that, then OpenSCAD, and the pattern looked like a recipe — Qt for WebAssembly, JSPI, a static dependency stack, and an honest audit of whatever the app assumed about threads, filesystems and OpenGL. The obvious next question was how far it scales. So here is FreeCAD: parametric 3D CAD, sketch-constrained solid modeling, an embedded Python, a dozen-plus workbenches. It is roughly an order of magnitude larger than the other two — about 1.5 million lines of C++ and 700 thousand of Python — and it now runs in a browser tab. The port took ~4 days from the HackerNews thread to the current state. The implementation was done almost entirely by Fable, and was a way for me to stress-test Fable capabilities in really big complex projects. If that sounds like a large claim, it is checkable. Every prompt over those four days is reproduced verbatim near the end of this post — all forty-eight of them — and the complete session transcripts, every sub-agent and every workflow, are published as a browseable archive. First load is ~96 MB compressed (Brotli) — this is a big program and I won’t pretend otherwise; your browser caches it afterward. Needs a recent Chromium-based browser (Chrome/Edge 137+): the port relies on WebAssembly JSPI, which Firefox and Safari don’t ship yet. When it boots, a demo document (a box with a cylindrical cut) opens in a live 3D viewport. the rest of this post is a technical note written entirely by Fable to answer the most burning questions, but it is an AI post from here on FreeCAD is not one program; it’s a platform. Under the Qt GUI sits OpenCASCADE (OCCT), the industrial B-rep geometry kernel; Coin3D with Quarter, an Open Inventor scene graph driving the 3D view; a full embedded CPython 3.14; the PySide6/shiboken6 Qt bindings (so Python code can build Qt UI); and this time, cross-compiled specifically for the FEM workbench, a subset of VTK 9.3 and the Salome SMESH mesher. On top of that: 17+ workbenches — Part, Sketcher, PartDesign, Draft, Spreadsheet, Measure, Surface, Import, Mesh/MeshPart/Points/Inspection/Robot, TechDraw, Assembly, CAM, BIM, FEM, Material and Start. All of it compiles statically into one 196 MB WebAssembly module next to Qt 6.11. Two pieces of that had never been done before in a browser, as far as I can tell: PySide6 and pivy (the Coin bindings) running under wasm at all, and OCCT+Coin+CPython+PySide+VTK+SMESH linked together into a single module. The rest of this post is how it got there, in the order it happened. This section is long on purpose — the request was every fix and every direction, in order, and the specificity is the point. If you just want to poke at the app, the launch button is above. LibreCAD could use a prebuilt Qt-for-wasm. FreeCAD can’t, for one reason: JSPI. FreeCAD is saturated with modal dialogs — 185 C++ exec() sites and 156 more in Python — and blocking Python code cannot be mechanically rewritten into callbacks. The only way to keep QDialog::exec() semantics is to suspend the wasm stack while the dialog is open, which is exactly what WebAssembly JSPI (JavaScript Promise Integration) does. That requires -feature-wasm-jspi, which requires a Qt built from source. So the toolchain under /opt/toolchains is Qt 6.11.1 compiled for wasm with JSPI and native wasm exceptions, on Emscripten 4.0.12, sitting next to hand-built static prefixes for OCCT, CPython, ICU, Boost, Xerces, {fmt} and yaml-cpp.