Repository: tetratelabs/wazero
Pull request #1129 (2023-02-15 23:43:51)

API BREAK: renames InstantiateModuleFromBinary to Instantiate
This renames `InstantiateModuleFromBinary` to `Instantiate` to both make first time use simpler to write and also de-complicate adding a `WithConfig` variant as requested in #1105

End users in simple case need to change their signature like so.
```diff
-       mod, err := r.InstantiateModuleFromBinary(ctx, addWasm)
+       mod, err := r.Instantiate(ctx, addWasm)
```

In practice, many will not need to change their signature because they had to use the `InstantiateModule` function in order to assign configuration such as the module name, filesystem or use a real clock. Instead, they had to use the more complicated chain of `CompileModule` and `InstantiateModule` even when only assigning config. Users in this situation can opt into the more simplified syntax below:

```go
mod, err := r.InstantiateWithConfig(ctx, addWasm,
	wazero.NewModuleConfig().WithName("adder"))
```

codefromthecrypt: There are actually a lot of use of the `InstantiateModuleFromBinary` API on GitHub, but I can help migrate them. I think we should do another .pre before the rc at the end of the month.

Patch:
diff --git a/config.go b/config.go
index 7a9bf4d1..d39ee1cf 100644
--- a/config.go
+++ b/config.go
@@ -405,7 +405,7 @@ func (c *customSection) Data() []byte {
 //	config := wazero.NewModuleConfig().WithStdout(buf).WithSysNanotime()
 //
 //	// Assign different configuration on each instantiation
-//	module, _ := r.InstantiateModule(ctx, compiled, config.WithName("rotate").WithArgs("rotate", "angle=90", "dir=cw"))
+//	mod, _ := r.InstantiateModule(ctx, compiled, config.WithName("rotate").WithArgs("rotate", "angle=90", "dir=cw"))
 //
 // While wazero supports Windows as a platform, host functions using ModuleConfig follow a UNIX dialect.
 // See RATIONALE.md for design background and relationship to WebAssembly System Interfaces (WASI).
diff --git a/examples/allocation/rust/greet.go b/examples/allocation/rust/greet.go
index 1fe28528..3d19eec3 100644
--- a/examples/allocation/rust/greet.go
+++ b/examples/allocation/rust/greet.go
@@ -39,7 +39,7 @@ func main() {
 
 	// Instantiate a WebAssembly module that imports the "log" function defined
 	// in "env" and exports "memory" and functions we'll use in this example.
-	mod, err := r.InstantiateModuleFromBinary(ctx, greetWasm)
+	mod, err := r.Instantiate(ctx, greetWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/examples/allocation/tinygo/greet.go b/examples/allocation/tinygo/greet.go
index d56b696f..09e1831b 100644
--- a/examples/allocation/tinygo/greet.go
+++ b/examples/allocation/tinygo/greet.go
@@ -44,7 +44,7 @@ func main() {
 
 	// Instantiate a WebAssembly module that imports the "log" function defined
 	// in "env" and exports "memory" and functions we'll use in this example.
-	mod, err := r.InstantiateModuleFromBinary(ctx, greetWasm)
+	mod, err := r.Instantiate(ctx, greetWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/examples/allocation/zig/greet.go b/examples/allocation/zig/greet.go
index 2cd74ed6..467dc8e0 100644
--- a/examples/allocation/zig/greet.go
+++ b/examples/allocation/zig/greet.go
@@ -45,12 +45,8 @@ func run() error {
 
 	// Instantiate a WebAssembly module that imports the "log" function defined
 	// in "env" and exports "memory" and functions we'll use in this example.
-	compiled, err := r.CompileModule(ctx, greetWasm)
-	if err != nil {
-		return err
-	}
-
-	mod, err := r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithStdout(os.Stdout).WithStderr(os.Stderr))
+	mod, err := r.InstantiateWithConfig(ctx, greetWasm,
+		wazero.NewModuleConfig().WithStdout(os.Stdout).WithStderr(os.Stderr))
 	if err != nil {
 		return err
 	}
diff --git a/examples/basic/add.go b/examples/basic/add.go
index 77c7b470..93658e9a 100644
--- a/examples/basic/add.go
+++ b/examples/basic/add.go
@@ -42,7 +42,7 @@ func main() {
 
 	// Instantiate the guest Wasm into the same runtime. It exports the `add`
 	// function, implemented in WebAssembly.
-	mod, err := r.InstantiateModuleFromBinary(ctx, addWasm)
+	mod, err := r.Instantiate(ctx, addWasm)
 	if err != nil {
 		log.Panicf("failed to instantiate module: %v", err)
 	}
diff --git a/examples/import-go/age-calculator.go b/examples/import-go/age-calculator.go
index 18bcfd81..d5bbf0cf 100644
--- a/examples/import-go/age-calculator.go
+++ b/examples/import-go/age-calculator.go
@@ -62,7 +62,7 @@ func main() {
 	//
 	// Note: The import syntax in both Text and Binary format is the same
 	// regardless of if the function was defined in Go or WebAssembly.
-	ageCalculator, err := r.InstantiateModuleFromBinary(ctx, ageCalculatorWasm)
+	ageCalculator, err := r.Instantiate(ctx, ageCalculatorWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/examples/multiple-results/multiple-results.go b/examples/multiple-results/multiple-results.go
index 19a4713e..91b9a969 100644
--- a/examples/multiple-results/multiple-results.go
+++ b/examples/multiple-results/multiple-results.go
@@ -82,7 +82,7 @@ var resultOffsetWasm []byte
 // resultOffsetWasmFunctions are the WebAssembly equivalent of the Go-defined
 // resultOffsetHostFunctions. The source is in testdata/result_offset.wat
 func resultOffsetWasmFunctions(ctx context.Context, r wazero.Runtime) (api.Module, error) {
-	return r.InstantiateModuleFromBinary(ctx, resultOffsetWasm)
+	return r.Instantiate(ctx, resultOffsetWasm)
 }
 
 // multiValueWasm was generated by the following:
@@ -95,7 +95,7 @@ var multiValueWasm []byte
 // multiValueWasmFunctions are the WebAssembly equivalent of the Go-defined
 // multiValueHostFunctions. The source is in testdata/multi_value.wat
 func multiValueWasmFunctions(ctx context.Context, r wazero.Runtime) (api.Module, error) {
-	return r.InstantiateModuleFromBinary(ctx, multiValueWasm)
+	return r.Instantiate(ctx, multiValueWasm)
 }
 
 // multiValueWasm was generated by the following:
@@ -122,5 +122,5 @@ func multiValueFromImportedHostWasmFunctions(ctx context.Context, r wazero.Runti
 		return nil, err
 	}
 	// Then, creates the module which imports the `get_age` function from the `multi-value/host` module above.
-	return r.InstantiateModuleFromBinary(ctx, multiValueFromImportedHostWasm)
+	return r.Instantiate(ctx, multiValueFromImportedHostWasm)
 }
diff --git a/examples/multiple-runtimes/counter.go b/examples/multiple-runtimes/counter.go
index a6cfff6d..3bfafdee 100644
--- a/examples/multiple-runtimes/counter.go
+++ b/examples/multiple-runtimes/counter.go
@@ -78,15 +78,9 @@ func (e *counter) getAndIncrement() (ret uint32) {
 
 // instantiateWithEnv returns a module instance.
 func instantiateWithEnv(ctx context.Context, r wazero.Runtime) api.Module {
-	// Compile WebAssembly that requires its own "env" module.
-	compiled, err := r.CompileModule(ctx, counterWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
 	// Instantiate a new "env" module which exports a stateful function.
 	c := &counter{}
-	_, err = r.NewHostModuleBuilder("env").
+	_, err := r.NewHostModuleBuilder("env").
 		NewFunctionBuilder().WithFunc(c.getAndIncrement).Export("next_i32").
 		Instantiate(ctx)
 	if err != nil {
@@ -94,7 +88,7 @@ func instantiateWithEnv(ctx context.Context, r wazero.Runtime) api.Module {
 	}
 
 	// Instantiate the module that imports "env".
-	mod, err := r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig())
+	mod, err := r.Instantiate(ctx, counterWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/imports/assemblyscript/example/assemblyscript.go b/imports/assemblyscript/example/assemblyscript.go
index 0fe1afa4..20bdd40c 100644
--- a/imports/assemblyscript/example/assemblyscript.go
+++ b/imports/assemblyscript/example/assemblyscript.go
@@ -36,18 +36,12 @@ func main() {
 		log.Panicln(err)
 	}
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, asWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
 	// Instantiate a WebAssembly module that imports the "abort" and "trace"
 	// functions defined by assemblyscript.Instantiate and exports functions
 	// we'll use in this example.
-	mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig().
+	mod, err := r.InstantiateWithConfig(ctx, asWasm,
 		// Override the default module config that discards stdout and stderr.
-		WithStdout(os.Stdout).WithStderr(os.Stderr))
+		wazero.NewModuleConfig().WithStdout(os.Stdout).WithStderr(os.Stderr))
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/imports/wasi_snapshot_preview1/example/cat.go b/imports/wasi_snapshot_preview1/example/cat.go
index 766d006c..d4bab06c 100644
--- a/imports/wasi_snapshot_preview1/example/cat.go
+++ b/imports/wasi_snapshot_preview1/example/cat.go
@@ -83,15 +83,9 @@ func main() {
 		log.Panicln("unknown toolchain", toolchain)
 	}
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, catWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
 	// InstantiateModule runs the "_start" function, WASI's "main".
 	// * Set the program name (arg[0]) to "wasi"; arg[1] should be "/test.txt".
-	if _, err = r.InstantiateModule(ctx, code, config.WithArgs("wasi", os.Args[1])); err != nil {
+	if _, err = r.InstantiateWithConfig(ctx, catWasm, config.WithArgs("wasi", os.Args[1])); err != nil {
 		// Note: Most compilers do not exit the module after running "_start",
 		// unless there was an error. This allows you to call exported functions.
 		if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
diff --git a/imports/wasi_snapshot_preview1/wasi.go b/imports/wasi_snapshot_preview1/wasi.go
index dfe9c47e..480024be 100644
--- a/imports/wasi_snapshot_preview1/wasi.go
+++ b/imports/wasi_snapshot_preview1/wasi.go
@@ -11,7 +11,7 @@
 //	defer r.Close(ctx) // This closes everything this Runtime created.
 //
 //	wasi_snapshot_preview1.MustInstantiate(ctx, r)
-//	mod, _ := r.InstantiateModuleFromBinary(ctx, wasm)
+//	mod, _ := r.Instantiate(ctx, wasm)
 //
 // See https://github.com/WebAssembly/WASI
 package wasi_snapshot_preview1
diff --git a/runtime.go b/runtime.go
index 056092bd..67cdd3a3 100644
--- a/runtime.go
+++ b/runtime.go
@@ -24,8 +24,41 @@ import (
 //	r := wazero.NewRuntime(ctx)
 //	defer r.Close(ctx) // This closes everything this Runtime created.
 //
-//	module, _ := r.InstantiateModuleFromBinary(ctx, wasm)
+//	mod, _ := r.Instantiate(ctx, wasm)
 type Runtime interface {
+	// Instantiate instantiates a module from the WebAssembly binary (%.wasm)
+	// with default configuration.
+	//
+	// Here's an example:
+	//	ctx := context.Background()
+	//	r := wazero.NewRuntime(ctx)
+	//	defer r.Close(ctx) // This closes everything this Runtime created.
+	//
+	//	mod, _ := r.Instantiate(ctx, wasm)
+	//
+	// See InstantiateWithConfig for configuration overrides.
+	Instantiate(ctx context.Context, source []byte) (api.Module, error)
+
+	// InstantiateWithConfig instantiates a module from the WebAssembly binary
+	// (%.wasm) or errs if invalid.
+	//
+	// Here's an example:
+	//	ctx := context.Background()
+	//	r := wazero.NewRuntime(ctx)
+	//	defer r.Close(ctx) // This closes everything this Runtime created.
+	//
+	//	mod, _ := r.InstantiateWithConfig(ctx, wasm,
+	//		wazero.NewModuleConfig().WithName("rotate"))
+	//
+	// # Notes
+	//
+	//   - This is a convenience utility that chains CompileModule with
+	//     InstantiateModule. To instantiate the same source multiple times,
+	//     use CompileModule as InstantiateModule avoids redundant decoding
+	//     and/or compilation.
+	//   - If you aren't overriding defaults, use Instantiate.
+	InstantiateWithConfig(ctx context.Context, source []byte, config ModuleConfig) (api.Module, error)
+
 	// NewHostModuleBuilder lets you create modules out of functions defined in Go.
 	//
 	// Below defines and instantiates a module named "env" with one function:
@@ -42,7 +75,7 @@ type Runtime interface {
 	// CompileModule decodes the WebAssembly binary (%.wasm) or errs if invalid.
 	// Any pre-compilation done after decoding wasm is dependent on RuntimeConfig.
 	//
-	// There are two main reasons to use CompileModule instead of InstantiateModuleFromBinary:
+	// There are two main reasons to use CompileModule instead of Instantiate:
 	//   - Improve performance when the same module is instantiated multiple times under different names
 	//   - Reduce the amount of errors that can occur during InstantiateModule.
 	//
@@ -54,21 +87,16 @@ type Runtime interface {
 	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#name-section%E2%91%A0
 	CompileModule(ctx context.Context, binary []byte) (CompiledModule, error)
 
-	// InstantiateModuleFromBinary instantiates a module from the WebAssembly binary (%.wasm) or errs if invalid.
+	// InstantiateModule instantiates the module or errs if the configuration was invalid.
 	//
 	// Here's an example:
-	//	ctx := context.Background()
-	//	r := wazero.NewRuntime(ctx)
-	//	defer r.Close(ctx) // This closes everything this Runtime created.
+	//	mod, _ := n.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithName("prod"))
 	//
-	//	module, _ := r.InstantiateModuleFromBinary(ctx, wasm)
-	//
-	// # Notes
-	//
-	//   - This is a convenience utility that chains CompileModule with InstantiateModule. To instantiate the same
-	//	source multiple times, use CompileModule as InstantiateModule avoids redundant decoding and/or compilation.
-	//   - To avoid using configuration defaults, use InstantiateModule instead.
-	InstantiateModuleFromBinary(ctx context.Context, source []byte) (api.Module, error)
+	// While CompiledModule is pre-validated, there are a few situations which can cause an error:
+	//   - The module name is already in use.
+	//   - The module has a table element initializer that resolves to an index outside the Table minimum size.
+	//   - The module has a start function, and it failed to execute.
+	InstantiateModule(ctx context.Context, compiled CompiledModule, config ModuleConfig) (api.Module, error)
 
 	// CloseWithExitCode closes all the modules that have been initialized in this Runtime with the provided exit code.
 	// An error is returned if any module returns an error when closed.
@@ -80,23 +108,12 @@ type Runtime interface {
 	//
 	//	// Everything below here can be closed, but will anyway due to above.
 	//	_, _ = wasi_snapshot_preview1.InstantiateSnapshotPreview1(ctx, r)
-	//	mod, _ := r.InstantiateModuleFromBinary(ctx, wasm)
+	//	mod, _ := r.Instantiate(ctx, wasm)
 	CloseWithExitCode(ctx context.Context, exitCode uint32) error
 
 	// Module returns an instantiated module in this runtime or nil if there aren't any.
 	Module(moduleName string) api.Module
 
-	// InstantiateModule instantiates the module or errs if the configuration was invalid.
-	//
-	// Here's an example:
-	//	module, _ := n.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithName("prod"))
-	//
-	// While CompiledModule is pre-validated, there are a few situations which can cause an error:
-	//   - The module name is already in use.
-	//   - The module has a table element initializer that resolves to an index outside the Table minimum size.
-	//   - The module has a start function, and it failed to execute.
-	InstantiateModule(ctx context.Context, compiled CompiledModule, config ModuleConfig) (api.Module, error)
-
 	// Closer closes all compiled code by delegating to CloseWithExitCode with an exit code of zero.
 	api.Closer
 }
@@ -229,13 +246,18 @@ func (r *runtime) failIfClosed() error {
 	return nil
 }
 
-// InstantiateModuleFromBinary implements Runtime.InstantiateModuleFromBinary
-func (r *runtime) InstantiateModuleFromBinary(ctx context.Context, binary []byte) (api.Module, error) {
+// Instantiate implements Runtime.Instantiate
+func (r *runtime) Instantiate(ctx context.Context, binary []byte) (api.Module, error) {
+	return r.InstantiateWithConfig(ctx, binary, NewModuleConfig())
+}
+
+// InstantiateWithConfig implements Runtime.InstantiateWithConfig
+func (r *runtime) InstantiateWithConfig(ctx context.Context, binary []byte, config ModuleConfig) (api.Module, error) {
 	if compiled, err := r.CompileModule(ctx, binary); err != nil {
 		return nil, err
 	} else {
 		compiled.(*compiledModule).closeWithModule = true
-		return r.InstantiateModule(ctx, compiled, NewModuleConfig())
+		return r.InstantiateModule(ctx, compiled, config)
 	}
 }
 
@@ -245,7 +267,7 @@ func (r *runtime) InstantiateModule(
 	compiled CompiledModule,
 	mConfig ModuleConfig,
 ) (mod api.Module, err error) {
-	if err := r.failIfClosed(); err != nil {
+	if err = r.failIfClosed(); err != nil {
 		return nil, err
 	}
 


Test patch:
diff --git a/context_done_example_test.go b/context_done_example_test.go
index 1df567b7..9f57c084 100644
--- a/context_done_example_test.go
+++ b/context_done_example_test.go
@@ -19,16 +19,14 @@ var infiniteLoopWasm []byte
 // of infinite loop function with context.Context created by context.WithTimeout powered by
 // RuntimeConfig.WithEnsureTermination configuration.
 func ExampleRuntimeConfig_WithCloseOnContextDone_context_timeout() {
-	r := wazero.NewRuntimeWithConfig(context.Background(),
+	ctx := context.Background()
+
+	r := wazero.NewRuntimeWithConfig(ctx,
 		// Enables the WithCloseOnContextDone option.
 		wazero.NewRuntimeConfig().WithCloseOnContextDone(true))
+	defer r.Close(ctx)
 
-	compiledModule, err := r.CompileModule(context.Background(), infiniteLoopWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	moduleInstance, err := r.InstantiateModule(context.Background(), compiledModule,
+	moduleInstance, err := r.InstantiateWithConfig(ctx, infiniteLoopWasm,
 		wazero.NewModuleConfig().WithName("malicious_wasm"))
 	if err != nil {
 		log.Panicln(err)
@@ -37,7 +35,7 @@ func ExampleRuntimeConfig_WithCloseOnContextDone_context_timeout() {
 	infiniteLoop := moduleInstance.ExportedFunction("infinite_loop")
 
 	// Create the context.Context to be passed to the invocation of infinite_loop.
-	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	ctx, cancel := context.WithTimeout(ctx, time.Second)
 	defer cancel()
 
 	// Invoke the infinite loop with the timeout context.
@@ -54,16 +52,14 @@ func ExampleRuntimeConfig_WithCloseOnContextDone_context_timeout() {
 // of infinite loop function with context.Context created by context.WithCancel powered by
 // RuntimeConfig.WithEnsureTermination configuration.
 func ExampleRuntimeConfig_WithCloseOnContextDone_context_cancel() {
-	r := wazero.NewRuntimeWithConfig(context.Background(),
+	ctx := context.Background()
+
+	r := wazero.NewRuntimeWithConfig(ctx,
 		// Enables the WithCloseOnContextDone option.
 		wazero.NewRuntimeConfig().WithCloseOnContextDone(true))
+	defer r.Close(ctx)
 
-	compiledModule, err := r.CompileModule(context.Background(), infiniteLoopWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	moduleInstance, err := r.InstantiateModule(context.Background(), compiledModule,
+	moduleInstance, err := r.InstantiateWithConfig(ctx, infiniteLoopWasm,
 		wazero.NewModuleConfig().WithName("malicious_wasm"))
 	if err != nil {
 		log.Panicln(err)
@@ -72,7 +68,7 @@ func ExampleRuntimeConfig_WithCloseOnContextDone_context_cancel() {
 	infiniteLoop := moduleInstance.ExportedFunction("infinite_loop")
 
 	// Create the context.Context to be passed to the invocation of infinite_loop.
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(ctx)
 	go func() {
 		// After 2 seconds, cancel the invocation of infinite loop.
 		time.Sleep(2 * time.Second)
@@ -93,16 +89,14 @@ func ExampleRuntimeConfig_WithCloseOnContextDone_context_cancel() {
 // of infinite loop function with api.Module's CloseWithExitCode method powered by
 // RuntimeConfig.WithEnsureTermination configuration.
 func ExampleRuntimeConfig_WithCloseOnContextDone_moduleClose() {
-	r := wazero.NewRuntimeWithConfig(context.Background(),
+	ctx := context.Background()
+
+	r := wazero.NewRuntimeWithConfig(ctx,
 		// Enables the WithCloseOnContextDone option.
 		wazero.NewRuntimeConfig().WithCloseOnContextDone(true))
+	defer r.Close(ctx)
 
-	compiledModule, err := r.CompileModule(context.Background(), infiniteLoopWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	moduleInstance, err := r.InstantiateModule(context.Background(), compiledModule,
+	moduleInstance, err := r.InstantiateWithConfig(ctx, infiniteLoopWasm,
 		wazero.NewModuleConfig().WithName("malicious_wasm"))
 	if err != nil {
 		log.Panicln(err)
@@ -114,13 +108,13 @@ func ExampleRuntimeConfig_WithCloseOnContextDone_moduleClose() {
 		// After 2 seconds, close the module instance with CloseWithExitCode, which triggers the termination
 		// of infinite loop.
 		time.Sleep(2 * time.Second)
-		if err := moduleInstance.CloseWithExitCode(context.Background(), 1); err != nil {
+		if err := moduleInstance.CloseWithExitCode(ctx, 1); err != nil {
 			log.Panicln(err)
 		}
 	}()
 
 	// Invoke the infinite loop with the timeout context.
-	_, err = infiniteLoop.Call(context.Background())
+	_, err = infiniteLoop.Call(ctx)
 
 	// The exit code is correctly handled and triggers the termination of infinite loop.
 	fmt.Println(err)
diff --git a/dwarf_test.go b/dwarf_test.go
index 068f1df1..eed86e06 100644
--- a/dwarf_test.go
+++ b/dwarf_test.go
@@ -140,10 +140,8 @@ wasm stack trace:
 					if len(lang.bin) == 0 {
 						t.Skip()
 					}
-					compiled, err := r.CompileModule(ctx, lang.bin)
-					require.NoError(t, err)
 
-					_, err = r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig())
+					_, err := r.Instantiate(ctx, lang.bin)
 					require.Error(t, err)
 
 					errStr := err.Error()
diff --git a/example_test.go b/example_test.go
index 7143826c..033e4947 100644
--- a/example_test.go
+++ b/example_test.go
@@ -39,7 +39,7 @@ func Example() {
 
 	// Instantiate the guest Wasm into the same runtime. It exports the `add`
 	// function, implemented in WebAssembly.
-	mod, err := r.InstantiateModuleFromBinary(ctx, addWasm)
+	mod, err := r.Instantiate(ctx, addWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/experimental/listener_example_test.go b/experimental/listener_example_test.go
index d2433d22..4d8cdf3b 100644
--- a/experimental/listener_example_test.go
+++ b/experimental/listener_example_test.go
@@ -63,13 +63,7 @@ func Example_customListenerFactory() {
 
 	wasi_snapshot_preview1.MustInstantiate(ctx, r)
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, listenerWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig())
+	mod, err := r.Instantiate(ctx, listenerWasm)
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/experimental/listener_test.go b/experimental/listener_test.go
index 5b662a11..f15efd83 100644
--- a/experimental/listener_test.go
+++ b/experimental/listener_test.go
@@ -86,8 +86,8 @@ func TestFunctionListenerFactory(t *testing.T) {
 		"fn2": {},
 	}, factory.m)
 
-	// Ensures that FunctionListener is a compile-time option, so passing context.Background here
-	// is ok to use listeners at runtime.
+	// Ensures that FunctionListener is a compile-time option, so passing
+	// context.Background here is ok to use listeners at runtime.
 	m, err := r.InstantiateModule(context.Background(), compiled, wazero.NewModuleConfig())
 	require.NoError(t, err)
 
diff --git a/experimental/logging/log_listener_example_test.go b/experimental/logging/log_listener_example_test.go
index 65f21d5d..5109c15e 100644
--- a/experimental/logging/log_listener_example_test.go
+++ b/experimental/logging/log_listener_example_test.go
@@ -31,13 +31,8 @@ func Example_newHostLoggingListenerFactory() {
 
 	wasi_snapshot_preview1.MustInstantiate(ctx, r)
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, listenerWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig().WithStdout(os.Stdout))
+	mod, err := r.InstantiateWithConfig(ctx, listenerWasm,
+		wazero.NewModuleConfig().WithStdout(os.Stdout))
 	if err != nil {
 		log.Panicln(err)
 	}
@@ -69,13 +64,8 @@ func Example_newLoggingListenerFactory() {
 
 	wasi_snapshot_preview1.MustInstantiate(ctx, r)
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, listenerWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-
-	mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig().WithStdout(os.Stdout))
+	mod, err := r.InstantiateWithConfig(ctx, listenerWasm,
+		wazero.NewModuleConfig().WithStdout(os.Stdout))
 	if err != nil {
 		log.Panicln(err)
 	}
diff --git a/imports/emscripten/emscripten_test.go b/imports/emscripten/emscripten_test.go
index 3d0e90a9..bc2f9d96 100644
--- a/imports/emscripten/emscripten_test.go
+++ b/imports/emscripten/emscripten_test.go
@@ -46,7 +46,7 @@ func TestGrow(t *testing.T) {
 	require.NoError(t, err)
 
 	// Emscripten exits main with zero by default
-	_, err = r.InstantiateModuleFromBinary(ctx, growWasm)
+	_, err = r.Instantiate(ctx, growWasm)
 	require.Error(t, err)
 	require.Zero(t, err.(*sys.ExitError).ExitCode())
 
@@ -66,7 +66,7 @@ func TestInvoke(t *testing.T) {
 	_, err := Instantiate(ctx, r)
 	require.NoError(t, err)
 
-	mod, err := r.InstantiateModuleFromBinary(ctx, invokeWasm)
+	mod, err := r.Instantiate(ctx, invokeWasm)
 	require.NoError(t, err)
 
 	tests := []struct {
diff --git a/imports/wasi_snapshot_preview1/example_test.go b/imports/wasi_snapshot_preview1/example_test.go
index 3abd0a4c..3677a105 100644
--- a/imports/wasi_snapshot_preview1/example_test.go
+++ b/imports/wasi_snapshot_preview1/example_test.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	_ "embed"
 	"fmt"
-	"log"
 	"os"
 
 	"github.com/tetratelabs/wazero"
@@ -33,16 +32,10 @@ func Example() {
 	// Instantiate WASI, which implements system I/O such as console output.
 	wasi_snapshot_preview1.MustInstantiate(ctx, r)
 
-	// Compile the WebAssembly module using the default configuration.
-	code, err := r.CompileModule(ctx, exitOnStartWasm)
-	if err != nil {
-		log.Panicln(err)
-	}
-	defer code.Close(ctx)
-
 	// InstantiateModule runs the "_start" function which is like a "main" function.
-	// Override default configuration (which discards stdout).
-	mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig().WithStdout(os.Stdout).WithName("wasi-demo"))
+	mod, err := r.InstantiateWithConfig(ctx, exitOnStartWasm,
+		// Override default configuration (which discards stdout).
+		wazero.NewModuleConfig().WithStdout(os.Stdout).WithName("wasi-demo"))
 	if mod != nil {
 		defer r.Close(ctx)
 	}
diff --git a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
index 7962e306..e424f337 100644
--- a/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_stdlib_test.go
@@ -173,10 +173,8 @@ func compileAndRun(t *testing.T, config wazero.ModuleConfig, bin []byte) (consol
 	_, err := wasi_snapshot_preview1.Instantiate(testCtx, r)
 	require.NoError(t, err)
 
-	compiled, err := r.CompileModule(testCtx, bin)
-	require.NoError(t, err)
-
-	_, err = r.InstantiateModule(testCtx, compiled, config.WithStdout(&consoleBuf).WithStderr(&consoleBuf))
+	_, err = r.InstantiateWithConfig(testCtx, bin,
+		config.WithStdout(&consoleBuf).WithStderr(&consoleBuf))
 	if exitErr, ok := err.(*sys.ExitError); ok {
 		require.Zero(t, exitErr.ExitCode(), consoleBuf.String())
 	} else {
diff --git a/imports/wasi_snapshot_preview1/wasi_test.go b/imports/wasi_snapshot_preview1/wasi_test.go
index 30b66672..a223e0d6 100644
--- a/imports/wasi_snapshot_preview1/wasi_test.go
+++ b/imports/wasi_snapshot_preview1/wasi_test.go
@@ -42,7 +42,7 @@ func TestNewFunctionExporter(t *testing.T) {
 		require.NoError(t, err)
 
 		// Instantiate our test binary, but using the old import names.
-		_, err = r.InstantiateModuleFromBinary(testCtx, exitOnStartUnstableWasm)
+		_, err = r.Instantiate(testCtx, exitOnStartUnstableWasm)
 
 		// Ensure the test binary worked. It should return exit code 2.
 		require.Equal(t, uint32(2), err.(*sys.ExitError).ExitCode())
@@ -69,7 +69,7 @@ func TestNewFunctionExporter(t *testing.T) {
 		require.NoError(t, err)
 
 		// Instantiate our test binary which will use our modified WASI.
-		_, err = r.InstantiateModuleFromBinary(testCtx, exitOnStartWasm)
+		_, err = r.Instantiate(testCtx, exitOnStartWasm)
 
 		// Ensure the modified function was used!
 		require.Zero(t, err.(*sys.ExitError).ExitCode())
diff --git a/internal/integration_test/bench/bench_test.go b/internal/integration_test/bench/bench_test.go
index a66ed3d5..f90a1e78 100644
--- a/internal/integration_test/bench/bench_test.go
+++ b/internal/integration_test/bench/bench_test.go
@@ -227,8 +227,8 @@ func runRandomMatMul(b *testing.B, m api.Module) {
 func instantiateHostFunctionModuleWithEngine(b *testing.B, config wazero.RuntimeConfig) api.Module {
 	r := createRuntime(b, config)
 
-	// InstantiateModuleFromBinary runs the "_start" function which is what TinyGo compiles "main" to.
-	m, err := r.InstantiateModuleFromBinary(testCtx, caseWasm)
+	// Instantiate runs the "_start" function which is what TinyGo compiles "main" to.
+	m, err := r.Instantiate(testCtx, caseWasm)
 	if err != nil {
 		b.Fatal(err)
 	}
diff --git a/internal/integration_test/engine/adhoc_test.go b/internal/integration_test/engine/adhoc_test.go
index d5cb3945..1f929a05 100644
--- a/internal/integration_test/engine/adhoc_test.go
+++ b/internal/integration_test/engine/adhoc_test.go
@@ -156,7 +156,7 @@ func testUserDefinedPrimitiveHostFunc(t *testing.T, r wazero.Runtime) {
 
 	proxyBin := proxy.NewModuleBinary("", hostCompiled)
 
-	mod, err := r.InstantiateModuleFromBinary(testCtx, proxyBin)
+	mod, err := r.Instantiate(testCtx, proxyBin)
 	require.NoError(t, err)
 
 	f := mod.ExportedFunction(fn)
@@ -185,7 +185,7 @@ func testReftypeImports(t *testing.T, r wazero.Runtime) {
 	require.NoError(t, err)
 	defer host.Close(testCtx)
 
-	module, err := r.InstantiateModuleFromBinary(testCtx, reftypeImportsWasm)
+	module, err := r.Instantiate(testCtx, reftypeImportsWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -197,7 +197,7 @@ func testReftypeImports(t *testing.T, r wazero.Runtime) {
 }
 
 func testHugeStack(t *testing.T, r wazero.Runtime) {
-	module, err := r.InstantiateModuleFromBinary(testCtx, hugestackWasm)
+	module, err := r.Instantiate(testCtx, hugestackWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -217,7 +217,7 @@ func testHugeStack(t *testing.T, r wazero.Runtime) {
 // testOverflow ensures that adding one into the maximum integer results in the
 // minimum one. See #636.
 func testOverflow(t *testing.T, r wazero.Runtime) {
-	module, err := r.InstantiateModuleFromBinary(testCtx, overflowWasm)
+	module, err := r.Instantiate(testCtx, overflowWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -234,7 +234,7 @@ func testOverflow(t *testing.T, r wazero.Runtime) {
 
 // testGlobalExtend ensures that un-signed extension of i32 globals must be zero extended. See #656.
 func testGlobalExtend(t *testing.T, r wazero.Runtime) {
-	module, err := r.InstantiateModuleFromBinary(testCtx, globalExtendWasm)
+	module, err := r.Instantiate(testCtx, globalExtendWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -257,7 +257,7 @@ func testUnreachable(t *testing.T, r wazero.Runtime) {
 		Instantiate(testCtx)
 	require.NoError(t, err)
 
-	module, err := r.InstantiateModuleFromBinary(testCtx, unreachableWasm)
+	module, err := r.Instantiate(testCtx, unreachableWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -282,7 +282,7 @@ func testRecursiveEntry(t *testing.T, r wazero.Runtime) {
 		Instantiate(testCtx)
 	require.NoError(t, err)
 
-	module, err := r.InstantiateModuleFromBinary(testCtx, recursiveWasm)
+	module, err := r.Instantiate(testCtx, recursiveWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -308,7 +308,7 @@ func testHostFuncMemory(t *testing.T, r wazero.Runtime) {
 	require.NoError(t, err)
 	defer host.Close(testCtx)
 
-	module, err := r.InstantiateModuleFromBinary(testCtx, hostMemoryWasm)
+	module, err := r.Instantiate(testCtx, hostMemoryWasm)
 	require.NoError(t, err)
 	defer module.Close(testCtx)
 
@@ -352,7 +352,7 @@ func testNestedGoContext(t *testing.T, r wazero.Runtime) {
 	defer imported.Close(testCtx)
 
 	// Instantiate a module that uses Wasm code to call the host function.
-	importing, err = r.InstantiateModuleFromBinary(testCtx, callOuterInnerWasm(t, importedName, importingName))
+	importing, err = r.Instantiate(testCtx, callOuterInnerWasm(t, importedName, importingName))
 	require.NoError(t, err)
 	defer importing.Close(testCtx)
 
@@ -388,7 +388,7 @@ func testHostFunctionContextParameter(t *testing.T, r wazero.Runtime) {
 			defer imported.Close(testCtx)
 
 			// Instantiate a module that uses Wasm code to call the host function.
-			importing, err = r.InstantiateModuleFromBinary(testCtx,
+			importing, err = r.Instantiate(testCtx,
 				callReturnImportWasm(t, importedName, importingName, i32))
 			require.NoError(t, err)
 			defer importing.Close(testCtx)
@@ -458,7 +458,7 @@ func testHostFunctionNumericParameter(t *testing.T, r wazero.Runtime) {
 			defer imported.Close(testCtx)
 
 			// Instantiate a module that uses Wasm code to call the host function.
-			importing, err := r.InstantiateModuleFromBinary(testCtx,
+			importing, err := r.Instantiate(testCtx,
 				callReturnImportWasm(t, importedName, importingName, test.vt))
 			require.NoError(t, err)
 			defer importing.Close(testCtx)
@@ -640,7 +640,7 @@ func testCloseInFlight(t *testing.T, r wazero.Runtime) {
 
 func testMemOps(t *testing.T, r wazero.Runtime) {
 	// Instantiate a module that manages its memory
-	mod, err := r.InstantiateModuleFromBinary(testCtx, memoryWasm)
+	mod, err := r.Instantiate(testCtx, memoryWasm)
 	require.NoError(t, err)
 	defer mod.Close(testCtx)
 
diff --git a/internal/integration_test/engine/hammer_test.go b/internal/integration_test/engine/hammer_test.go
index 22443daf..6ccfcff4 100644
--- a/internal/integration_test/engine/hammer_test.go
+++ b/internal/integration_test/engine/hammer_test.go
@@ -37,7 +37,7 @@ func closeImportingModuleWhileInUse(t *testing.T, r wazero.Runtime) {
 
 		// Prove a module can be redefined even with in-flight calls.
 		binary := callReturnImportWasm(t, imported.Name(), importing.Name(), i32)
-		importing, err := r.InstantiateModuleFromBinary(testCtx, binary)
+		importing, err := r.Instantiate(testCtx, binary)
 		require.NoError(t, err)
 		return imported, importing
 	})
@@ -61,7 +61,7 @@ func closeImportedModuleWhileInUse(t *testing.T, r wazero.Runtime) {
 
 		// Redefine the importing module, which should link to the redefined host module.
 		binary := callReturnImportWasm(t, imported.Name(), importing.Name(), i32)
-		importing, err = r.InstantiateModuleFromBinary(testCtx, binary)
+		importing, err = r.Instantiate(testCtx, binary)
 		require.NoError(t, err)
 
 		return imported, importing
@@ -91,7 +91,7 @@ func closeModuleWhileInUse(t *testing.T, r wazero.Runtime, closeFn func(imported
 
 	// Import that module.
 	binary := callReturnImportWasm(t, imported.Name(), t.Name()+"-importing", i32)
-	importing, err := r.InstantiateModuleFromBinary(testCtx, binary)
+	importing, err := r.Instantiate(testCtx, binary)
 	require.NoError(t, err)
 	defer importing.Close(testCtx)
 
diff --git a/internal/integration_test/fs/fs_test.go b/internal/integration_test/fs/fs_test.go
index 3c4fd68c..fba21e15 100644
--- a/internal/integration_test/fs/fs_test.go
+++ b/internal/integration_test/fs/fs_test.go
@@ -158,10 +158,7 @@ func TestReader(t *testing.T) {
 	sys := wazero.NewModuleConfig().WithFS(fstest.FS)
 
 	// Create a module that just delegates to wasi functions.
-	compiled, err := r.CompileModule(testCtx, fsWasm)
-	require.NoError(t, err)
-
-	mod, err := r.InstantiateModule(testCtx, compiled, sys)
+	mod, err := r.InstantiateWithConfig(testCtx, fsWasm, sys)
 	require.NoError(t, err)
 
 	pathOpen := mod.ExportedFunction("path_open")
diff --git a/internal/integration_test/fuzz/wazerolib/nodiff.go b/internal/integration_test/fuzz/wazerolib/nodiff.go
index 1102853c..7ed7d0b0 100644
--- a/internal/integration_test/fuzz/wazerolib/nodiff.go
+++ b/internal/integration_test/fuzz/wazerolib/nodiff.go
@@ -219,7 +219,7 @@ func ensureDummyImports(r wazero.Runtime, origin *wasm.Module, requireNoError fu
 			}
 			m.ExportSection = append(m.ExportSection, &wasm.Export{Type: imp.Type, Name: imp.Name, Index: index})
 		}
-		_, err := r.InstantiateModuleFromBinary(context.Background(), binary.EncodeModule(m))
+		_, err := r.Instantiate(context.Background(), binary.EncodeModule(m))
 		requireNoError(err)
 	}
 	return
diff --git a/internal/integration_test/fuzzcases/fuzzcases_test.go b/internal/integration_test/fuzzcases/fuzzcases_test.go
index d85ec3f5..b007678a 100644
--- a/internal/integration_test/fuzzcases/fuzzcases_test.go
+++ b/internal/integration_test/fuzzcases/fuzzcases_test.go
@@ -52,7 +52,7 @@ func run(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
 // Test695 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
 func Test695(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 695))
+		module, err := r.Instantiate(ctx, getWasmBinary(t, 695))
 		require.NoError(t, err)
 
 		_, err = module.ExportedFunction("i8x16s").Call(ctx)
@@ -74,7 +74,7 @@ func Test696(t *testing.T) {
 	}
 
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 696))
+		module, err := r.Instantiate(ctx, getWasmBinary(t, 696))
 		require.NoError(t, err)
 
 		for _, name := range functionNames {
@@ -89,7 +89,7 @@ func Test696(t *testing.T) {
 func Test699(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
 		defer r.Close(ctx)
-		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 699))
+		_, err := r.Instantiate(ctx, getWasmBinary(t, 699))
 		require.NoError(t, err)
 	})
 }
@@ -97,7 +97,7 @@ func Test699(t *testing.T) {
 // Test701 requires two functions to exit with "out of bounds memory access" consistently across the implementations.
 func Test701(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		module, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 701))
+		module, err := r.Instantiate(ctx, getWasmBinary(t, 701))
 		require.NoError(t, err)
 
 		_, err = module.ExportedFunction("i32.extend16_s").Call(ctx)
@@ -112,14 +112,14 @@ func Test701(t *testing.T) {
 
 func Test704(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 704))
+		_, err := r.Instantiate(ctx, getWasmBinary(t, 704))
 		require.NoError(t, err)
 	})
 }
 
 func Test708(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 708))
+		_, err := r.Instantiate(ctx, getWasmBinary(t, 708))
 		require.NotNil(t, err)
 		require.Contains(t, err.Error(), "out of bounds memory access")
 	})
@@ -127,7 +127,7 @@ func Test708(t *testing.T) {
 
 func Test709(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 709))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 709))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("f64x2.promote_low_f32x4")
@@ -142,7 +142,7 @@ func Test709(t *testing.T) {
 
 func Test715(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 715))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 715))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("select on conditional value after table.size")
@@ -156,7 +156,7 @@ func Test715(t *testing.T) {
 
 func Test716(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 716))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 716))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("select on ref.func")
@@ -170,7 +170,7 @@ func Test716(t *testing.T) {
 
 func Test717(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 717))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 717))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("vectors")
@@ -188,7 +188,7 @@ func Test717(t *testing.T) {
 
 func Test718(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 718))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 718))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("v128.load_zero on the ceil")
@@ -200,7 +200,7 @@ func Test718(t *testing.T) {
 
 func Test719(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 719))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 719))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("require unreachable")
@@ -213,7 +213,7 @@ func Test719(t *testing.T) {
 
 func Test720(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 720))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 720))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("access memory after table.grow")
@@ -226,7 +226,7 @@ func Test720(t *testing.T) {
 
 func Test721(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 721))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 721))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("conditional before elem.drop")
@@ -240,7 +240,7 @@ func Test721(t *testing.T) {
 
 func Test722(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 722))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 722))
 		require.NoError(t, err)
 
 		f := mod.ExportedFunction("conditional before data.drop")
@@ -255,7 +255,7 @@ func Test722(t *testing.T) {
 func Test725(t *testing.T) {
 	functions := []string{"i32.load8_s", "i32.load16_s"}
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 725))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 725))
 		require.NoError(t, err)
 
 		for _, fn := range functions {
@@ -286,7 +286,7 @@ func Test730(t *testing.T) {
 	}
 
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 730))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 730))
 		require.NoError(t, err)
 
 		for _, tc := range tests {
@@ -303,7 +303,7 @@ func Test730(t *testing.T) {
 
 func Test733(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 733))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 733))
 		require.NoError(t, err)
 
 		name := "out of bounds"
@@ -338,14 +338,14 @@ func Test733(t *testing.T) {
 
 func Test873(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 873))
+		_, err := r.Instantiate(ctx, getWasmBinary(t, 873))
 		require.NoError(t, err)
 	})
 }
 
 func Test874(t *testing.T) {
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		_, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 874))
+		_, err := r.Instantiate(ctx, getWasmBinary(t, 874))
 		require.NoError(t, err)
 	})
 }
@@ -374,13 +374,11 @@ func Test888(t *testing.T) {
 			},
 		})
 
-		_, err := r.InstantiateModuleFromBinary(ctx, imported)
+		_, err := r.Instantiate(ctx, imported)
 		require.NoError(t, err)
 
-		compiled, err := r.CompileModule(ctx, getWasmBinary(t, 888))
-		require.NoError(t, err)
-
-		_, err = r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithName("test"))
+		_, err = r.InstantiateWithConfig(ctx, getWasmBinary(t, 888),
+			wazero.NewModuleConfig().WithName("test"))
 		require.NoError(t, err)
 	})
 }
@@ -392,7 +390,7 @@ func Test1054(t *testing.T) {
 
 	modules := make([]api.Module, 0, 2)
 	run(t, func(t *testing.T, r wazero.Runtime) {
-		mod, err := r.InstantiateModuleFromBinary(ctx, getWasmBinary(t, 1054))
+		mod, err := r.Instantiate(ctx, getWasmBinary(t, 1054))
 		require.NoError(t, err)
 		modules = append(modules, mod)
 	})
diff --git a/runtime_test.go b/runtime_test.go
index 055ba7ae..1ba7291b 100644
--- a/runtime_test.go
+++ b/runtime_test.go
@@ -222,7 +222,7 @@ func TestModule_Memory(t *testing.T) {
 			defer r.Close(testCtx)
 
 			// Instantiate the module and get the export of the above memory
-			module, err := r.InstantiateModuleFromBinary(testCtx, tc.wasm)
+			module, err := r.Instantiate(testCtx, tc.wasm)
 			require.NoError(t, err)
 
 			mem := module.ExportedMemory("memory")
@@ -371,9 +371,9 @@ func TestRuntime_InstantiateModule_UsesContext(t *testing.T) {
 	require.Equal(t, uint32(2), r.(*runtime).store.Engine.CompiledModuleCount())
 }
 
-// TestRuntime_InstantiateModuleFromBinary_DoesntEnforce_Start ensures wapc-go work when modules import WASI, but don't
+// TestRuntime_Instantiate_DoesntEnforce_Start ensures wapc-go work when modules import WASI, but don't
 // export "_start".
-func TestRuntime_InstantiateModuleFromBinary_DoesntEnforce_Start(t *testing.T) {
+func TestRuntime_Instantiate_DoesntEnforce_Start(t *testing.T) {
 	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
@@ -382,12 +382,12 @@ func TestRuntime_InstantiateModuleFromBinary_DoesntEnforce_Start(t *testing.T) {
 		ExportSection: []*wasm.Export{{Name: "memory", Type: wasm.ExternTypeMemory, Index: 0}},
 	})
 
-	mod, err := r.InstantiateModuleFromBinary(testCtx, binary)
+	mod, err := r.Instantiate(testCtx, binary)
 	require.NoError(t, err)
 	require.NoError(t, mod.Close(testCtx))
 }
 
-func TestRuntime_InstantiateModuleFromBinary_ErrorOnStart(t *testing.T) {
+func TestRuntime_Instantiate_ErrorOnStart(t *testing.T) {
 	tests := []struct {
 		name, wasm string
 	}{
@@ -424,7 +424,7 @@ func TestRuntime_InstantiateModuleFromBinary_ErrorOnStart(t *testing.T) {
 			require.NoError(t, err)
 
 			// Start the module as a WASI command. We expect it to fail.
-			_, err = r.InstantiateModuleFromBinary(testCtx, []byte(tc.wasm))
+			_, err = r.Instantiate(testCtx, []byte(tc.wasm))
 			require.Error(t, err)
 
 			// Close the imported module, which should remove its compiler cache.
@@ -486,11 +486,9 @@ func TestRuntime_InstantiateModule_ExitError(t *testing.T) {
 		StartSection: &one,
 	})
 
-	code, err := r.CompileModule(testCtx, binary)
-	require.NoError(t, err)
-
 	// Instantiate the module, which calls the start function.
-	_, err = r.InstantiateModule(testCtx, code, NewModuleConfig().WithName("call-exit"))
+	_, err = r.InstantiateWithConfig(testCtx, binary,
+		NewModuleConfig().WithName("call-exit"))
 
 	// Ensure the exit error propagated and didn't wrap.
 	require.Equal(t, err, sys.NewExitError("call-exit", 2))
@@ -618,11 +616,8 @@ func TestHostFunctionWithCustomContext(t *testing.T) {
 		StartSection: &one,
 	})
 
-	code, err := r.CompileModule(hostCtx, binary)
-	require.NoError(t, err)
-
 	// Instantiate the module, which calls the start function. This will fail if the context wasn't as intended.
-	ins, err := r.InstantiateModule(hostCtx, code, NewModuleConfig())
+	ins, err := r.Instantiate(hostCtx, binary)
 	require.NoError(t, err)
 	require.True(t, calledStart)
 
@@ -679,9 +674,9 @@ func TestRuntime_Closed(t *testing.T) {
 			},
 		},
 		{
-			name: "InstantiateModuleFromBinary",
+			name: "Instantiate",
 			errFunc: func(r Runtime, mod CompiledModule) error {
-				_, err := r.InstantiateModuleFromBinary(testCtx, binaryNamedZero)
+				_, err := r.Instantiate(testCtx, binaryNamedZero)
 				return err
 			},
 		},