About the tiny-worker build
A Cloudflare Worker has a script-size budget and no business shipping three.js to render HTML. anvil's build is shaped so the Worker stays small and the heavy code loads lazily, in the browser, only when an animation actually mounts.
The <Anvil> component renders only a sizing placeholder
during server rendering. The real scene components — and the three.js and
Lottie players they pull in — are reached exclusively through a client-side
dynamic import() inside onMount. At build time those
scene modules are stubbed out of the Worker's module graph entirely, so the SSR
bundle contains no renderer at all.
On the client, three.js and the Lottie player are marked external and resolved through an import map pointing at a CDN. The hydration bundle the Worker serves is therefore a few kilobytes; the renderers arrive from the edge cache the first time a scene needs them, and never on a page that has no animation. The result is a Worker measured in tens of kilobytes rather than a megabyte.
If you would rather not depend on a third-party CDN, the same externals can be served as hashed, immutable assets from the Worker itself. The build emits those asset routes already; flipping the import map to point at them is a one-line change.