Why We Built OpenSKP
If you want to read a .dxf file, there's an open specification. If you want to read a .gltf file, there's a Khronos Group standard with a public GitHub repo and a validator you can run against your output. If you want to read a .skp file — SketchUp's own native format — there is nothing. No spec, no schema, no reference decoder. Just a proprietary SDK, licensed by Trimble, that only runs where Trimble lets it run.
That gap is the entire reason OpenSKP exists.
The problem with "just use the SDK"
SketchUp's official SDK is a real, functional way to read and write .skp files — if your project can tolerate everything that comes with it: a native dependency tied to specific platforms, a license that constrains how and where you can ship, and no path at all if you're building for Linux servers, WebAssembly, or anywhere the SDK simply isn't available.
That constraint is exactly what two of the projects OpenSKP now powers ran into. FrameSmart, a 3D collaboration platform, needed to parse SketchUp files as part of a Linux-hosted pipeline. IngeTrazo, a Linux-first 3D modeler for civil engineering, was running the real SketchUp SDK through Wine — a working setup, but a fragile one, dragging a Windows-only dependency into a project that had no other reason to need it.
Neither of those is an unusual situation. Anyone building a pipeline tool, a headless converter, a web-based viewer, or a CI step that touches SketchUp files runs into the same wall: the only "real" way in is a native SDK that assumes you're building a desktop plugin on Windows or macOS.
Reverse-engineering, not guessing
Without a spec, the only way to understand the format is to look at real bytes and figure out what they mean — and then prove the theory rather than just believing it looks plausible. That distinction matters more than it sounds. A parser that produces geometry that looks right in a debug print is not the same as a parser that's actually correct; SketchUp files are dense binary structures where a single misread flag byte can silently corrupt geometry without ever throwing an error.
The methodology that held up: build real files with the actual SketchUp application (or, once OpenSKP's own writer existed, the real SDK as a validation oracle), then diff OpenSKP's understanding of those files against what SketchUp itself reports through its own API — material colors, transparency values, transform matrices, vertex positions, all checked field by field rather than assumed. Several real bugs were only caught this way: a legacy-format alpha byte that four of the five language ports were silently discarding, a face's texture-positioning data that was being parsed but never linked back to the face it belonged to, a slot-numbering edge case that corrupted any file crossing a specific size threshold. None of those would have shown up in a "does it produce a mesh" smoke test. All of them showed up the moment real SketchUp was used as the source of truth.
Two container formats, not one
Part of what makes this format genuinely hard is that it isn't one format — it's two. SketchUp changed its internal container completely in the 2021 release. Files from SketchUp 2021 onward use VFF, a ZIP-based container wrapping a TLV (Tag-Length-Value) binary tree. Files from SketchUp 2013–2020 use something structurally unrelated: a classic MFC CArchive object-graph stream, with its own class-reference and back-reference numbering scheme, no ZIP involved at all.
A tool that only reads one of these covers a shrinking slice of the real files people actually have sitting on disk — architecture firms, civil engineering practices, and product designers routinely have SketchUp libraries stretching back a decade. OpenSKP reads both, transparently, behind the same parse() call in every language, which is a meaningfully larger reverse-engineering effort than picking the newer, better-documented-by-inference format and calling it done.
Why five languages, and why not bindings
OpenSKP isn't a core parser in one language with thin wrapper bindings for the rest. Python, TypeScript, .NET, Dart, and C++ are five independent implementations of the same reverse-engineered format, each idiomatic to its own ecosystem — because a Python native extension is a poor fit for a browser-based TypeScript viewer, and a JavaScript parser is a poor fit for a native C++ desktop tool.
The tradeoff is real: five implementations mean five places a bug can hide, and cross-language parity has to be actively maintained rather than assumed. In practice that means every non-trivial fix gets checked against all five ports' actual source before being called complete, and the same real .skp fixtures get run through every language to confirm they produce identical geometry, layers, and materials — not just "each one compiles and returns something."
Where it stands now
What started as a read-only reverse-engineering project has grown into a full toolkit: parsing both container formats, converting to seven other formats natively (glTF, OBJ, STL, PLY, DXF, IFC4, JSON), and — as of the 1.1.0 release — writing genuinely new .skp files from scratch, in all five languages, with no SketchUp SDK involved at any point.
None of it required Trimble's permission, a license fee, or a Windows machine. That was always the point.
OpenSKP is open source under the MIT license: github.com/iamahsanmehmood/openskp
Top comments (0)