Skip to main content
Model Mender

Architecture

How Model Mender works

Everything here runs in your browser. This page explains the mechanism, because a privacy claim you cannot verify is just marketing.

Where the work happens

When you add a file, the browser hands the page a File handle, not the file’s contents. Bytes are read only at the moment a job needs them, then transferred into a Web Worker rather than copied. The worker parses the model, measures it, applies any operations, writes the output format and reads that output back to verify it. The finished bytes are transferred to the page, which turns them into a download.

Because bytes are read on demand and released afterwards, a hundred-file batch costs roughly one file in memory per running worker, not a hundred.

Why there is nowhere to upload to

  • This site has no API routes, no server actions, no database and no object storage. There is no code path that receives a file.
  • Pages are static HTML and JavaScript. The only thing the server does is serve them.
  • The Content Security Policy sets connect-src to this origin only. Any fetch, XHR, WebSocket or beacon aimed anywhere else is blocked by the browser, not by our good intentions.
  • The browser test suite converts a real model while recording every network request the page makes, and fails the build if a cross-origin request appears.
  • Once the page has loaded you can go offline entirely. Conversion, inspection, repair and download all continue to work.

Memory, and why files get refused

A browser tab has a finite memory budget, and WebKit’s is stricter than most. The honest failure is to refuse a file before allocating, rather than crash the tab halfway through.

Every parser estimates the working set a mesh will need — positions, indices, the adjacency structures the analysis builds, and the copy the writer produces — and compares it with the budget for your device before it allocates anything. Triangle counts, vertex counts, mesh counts, scene-graph depth and node counts are all bounded too.

On phones and in Safari the workspace uses smaller limits and converts files one at a time. On a desktop with spare cores it runs several at once, leaving two cores for the interface so the viewer keeps responding during a batch.

Why every export is re-opened

A converter can produce a file that downloads perfectly and is subtly wrong: an index off by one, a header that disagrees with the body, a unit silently changed. Producing a Blob proves nothing about its contents.

So every file this site writes is immediately parsed again, by the same reader a third-party tool would use, and the result is compared against what the writer was asked to produce: triangle count exactly, mesh count against the target format’s documented behaviour, and the bounding box within a stated tolerance. For 3MF the declared unit is checked too. The outcome of that comparison is shown next to the download, and it is recorded for every file in the batch manifest.

What repair will and will not do

Safe repair welds coincident vertices, drops zero-area triangles, and makes triangle winding consistent across each closed shell so faces point outward. Those changes cannot alter the shape you designed.

It does not fill holes, remesh, or resolve self-intersections. Those operations invent geometry, and geometry invented silently is exactly the failure this tool exists to avoid. Where a hole remains, the workspace says how many open edges are left rather than quietly patching them.

Anything that can change the shape is gated: you see measured before-and-after counts, every warning the operations raised, and have to confirm before an export is offered.

Untrusted input

  • 3MF is a ZIP archive, so entry count, declared uncompressed size, compression ratio and entry paths are all checked from the central directory before a single byte is decompressed.
  • Declared sizes can lie, so the real decompressed total is checked as well.
  • The XML parser has no concept of external entities or DTD subsets. A DOCTYPE that declares entities is refused outright, and only the five predefined entities plus numeric character references are expanded.
  • Object names, material names and other model-supplied text are treated as data. They are stripped of control characters, length-capped, rendered as text by React, and escaped when written back into XML.
  • Scene graphs are bounded in both node count and recursion depth, so a file containing a cycle is refused rather than hanging the tab.

What the analytics see

The site includes Vercel Analytics for page views. It records the URL you visited and standard request metadata. It is never given a filename, a file size, a format, a triangle count, a dimension, or anything else read out of a model, and the Content Security Policy would block it from sending data off-origin regardless.

There are no accounts, no cookies used for tracking, and no file storage. The privacy page states this in full.