Skip to main content
Your files import each other the way you would expect from Node, but the resolver is the app’s own and it is closed: an expansion can import its own files, its own libraries and the SDK. Nothing else.

What resolves

Assets that resolve: .png .jpg .jpeg .gif .webp .svg, .ogg .mp3 .wav, .mp4 .webm, .bbmodel .gltf .glb .obj, .ttf .woff .woff2.

What does not

Everything else fails the load, not at runtime, with the file and line.
Also refused:
  • absolute paths
  • import() and require() with anything but a literal path, because everything is resolved before your code runs
  • sdk/anything-else: only sdk and sdk/ui exist

TypeScript and JSX

The app compiles .ts, .tsx, .jsx and .js on load. Types are stripped without being checked, which is what makes loading fast; run tsc in your editor for checking. JSX uses the automatic runtime, so there is no need to import React to write JSX. Compiled output keeps your line numbers, so a stack trace and an error card point at the line you wrote.

How modules behave

  • Each module runs once; its exports are cached for everyone importing it.
  • Circular imports behave as in Node: the module still running exposes its partial exports.
  • Output is cached by content hash, so a reload only recompiles files that changed.

CSS

Both are scoped to your expansion: every selector is prefixed with your expansion’s wrapper, so button { … } styles your buttons and not the app’s. @media, @supports, @container and @layer are scoped inside too. @keyframes names are prefixed so two expansions can both animate spin, and animation declarations are rewritten to match. :root, html and body mean your own wrapper. @import is dropped: it would fetch a URL at runtime. .module.css additionally hashes class names and gives you the map as the default export, so two files can both use .title.

Assets

An asset import is a data: URL string, usable anywhere a URL goes: <img src={logo} />, new Audio(sound), a CSS url() you build yourself. Assets are inlined at load, so large files cost memory; keep a 3D model or a long audio file out of the import graph if you do not need it.

JSON

Parsed at load. A malformed file fails the load with the parse error.