The term "main thread" can be ambiguous and confusing I'm afraid.
In emscripten we disambiguate we have two concepts of `main` thread.
1. The main browser thread (i.e. not a worker)
2. The main emscripten runtime thread (the thread where the emscripten module get first loaded).
Normally on the web these two are the same thing since the emscripten module gets instantiated on the main browser thread. However if you load the emscripten module on a worker, then there will be no main browser thread, or at leat no main browser thread that is accessible to emscripten.
When we say "proxy to main thread" or "MAIN_THREAD_EM_ASM" we are always talking about the main runtime thread, since that is the only thing that is guaranteed to exist.
There are many APIs which won't work if your main runtime thread is not also the main browser thread (e.g anything related to the DOM).
Note: I myself have been confused about these concepts in the past, and my knowledge could still have gaps but that is my understanding today.
cheers,
sam