But I prefer the wasmtime webassembly component model approach these days.
Built a plugin system with that, which has one major upside in my book:
No stringly function invocation.
Instead of run_function("my-function-with-typo") I have a instantiated_plugin.my_function call, where I can be sure that if the plugin has been instantiated, it does have that function.