Anything built with emscripten expects the emscripten runtime to be provided for those imports. The default output of emscripten isn't a WASM file that's meant to be used on its own, but a WASM file plus a JS file that sets up the runtime. It looks like they're trying to use the WASM file on its own and running into the problems that come from that.

Standards like WASI are meant to define a common runtime for WASM modules. A WASM module built for WASI would fit the author's expectations better (as they could possibly find an all-in-one WASM+WASI library or attach a WASI implementation to a WASM library to run the WASM file), though I don't know anything about emscripten and WASI compatibility.

Edit: You can use the STANDALONE_WASM emscripten option to make it not depend on the emscripten runtime and use WASI instead. This is what the author should use.

It's straightforward to create a WASI executable with Emscripten:

    emcc hello.c -o hello.wasm
This generates a single self-contained .wasm file that's runnable as 'WASI executable':

    wasmtime hello
    Hello World!
Some advice for C/C++ library design to make life easier for users in such 'esoteric environments':

- distribute as source code, ideally as a small number of .h and .c files

- ideally don't distribute any build system files, instead make the library configurable via a handful of preprocessor defines, list those defines in the readme

- don't have builtin IO calls such as fopen/fread/fclose, instead let the library user provide any data to be processed in memory

- don't have built-in multithreading calls, instead provide functions which allow processing data in slices, so that the library user can easily call those 'slice functions' from multiple threads (or a similar solution to prevent multithreading from being baked into the library)

- ideally let the user also override memory allocation functions

It doesn't sound like that would end up with a particularly pleasant-to-use API. Do you know of any examples??

The STB headers are mostly built like that: https://github.com/nothings/stb

Dear ImGui is a C++ example: https://github.com/ocornut/imgui

You could also add an optional 'convenience layer' over the lower-level flexible-but-inconvenient core library, as long as the core library can be built and used without the convenience layer.

In essence it's just a way to decouple the actually important library functionality from runtime environment details which might be better implemented outside the C and C++ stdlibs anyway.

It's already as simple as the stdlib IO functions not being asynchrononous while many operating systems provide more modern and performant asynchronous IO APIs. For a specific type of library (such as an image decoder) it's often better to delegate such details to the library user instead of either using the stdlib or having the library talk directly to OS APIs.

PS: this type of library design is actually also quite common in game development, because such libraries must be embeddable in game engine code bases which usually implement their own IO-, threading- and memory-management systems.