Course contentsShow
← Rust
Lesson 1839 of 1,91016. Specialized Runtime TargetsFree lesson

Dynamic Linking in Wasm

Structure projects to use shared Wasm modules for reduced load times and memory deduplication.

In this lesson, you will learn how to structure Wasm projects to utilize dynamic linking, allowing you to share code between multiple modules to save memory and decrease initial load times.

The Problem: Monolithic Bloat

In standard Rust Wasm workflows, we typically compile everything into a single, massive .wasm binary. If you have five different micro-apps in a larger system, they each embed their own copy of the standard library or shared utility code. This duplication bloats the final payload and wastes memory, as the Wasm engine cannot deduplicate identical code across separate instances.

The Solution: Shared Modules

Dynamic linking allows us to split a project into a "Core" module and multiple "Feature" modules. The Core module contains the shared logic, memory management, and exported tables, while the Feature modules act as dynamic libraries.

When you compile a module to be dynamically linked, you instruct the linker to treat certain functions as imports provided by the host environment or a shared Wasm module.

// Core Module: Provides the shared logic
#[no_mangle]
pub fn shared_utility_function(a: i32, b: i32) -> i32 {
    a + b
}

// Feature Module: Compiled to import the utility
extern "C" {
    fn shared_utility_function(a: i32, b: i32) -> i32;
}

pub fn run_feature() {
    let result = unsafe { shared_utility_function(10, 20) };
    // ...
}

Managing the Shared Table

The true power of dynamic linking in Wasm relies on the Table index. Instead of hard-coding function addresses, the dynamic linker places shared functions into a Table. When your Feature module initializes, the host environment populates the function imports from the Core module’s export table.

This architecture means that if you update the Core module (e.g., to fix a bug in a shared library), you only need to redeploy the Core. Your Feature modules remain small and essentially "link" against the memory address space and function table provided by the runtime at instantiation. This reduces the cold-start footprint significantly because the engine only needs to compile and validate the shared library once.

Key Takeaway: Dynamic linking uses shared Wasm modules to store common logic in a single function table, enabling code deduplication and smaller, modular deployment units.