Native Runtimes, Microsecond Calls

Each language runs in its own original runtime — no VMs, interpreters, or recompilation. Cross-language calls complete in microseconds.

Two Ways to Call

Load and call dynamically at runtime, or generate typed stubs with the host compiler for IDE autocomplete and type safety. Your choice.

No Bridge Code in Your App

No JNI wrappers, CPython embedding, or cgo in your application code. Write your host code in one language only.

Quick Taste

Use Apache log4j from Python — no JVM bridge code, no compilation step:

from metaffi import MetaFFIRuntime, MetaFFITypes
from metaffi.metaffi_types import new_metaffi_type_info

runtime = MetaFFIRuntime("openjdk")
module = runtime.load_module("log4j-api-2.21.1.jar;log4j-core-2.21.1.jar")

getLogger = module.load_entity(
    "class=org.apache.logging.log4j.LogManager,callable=getLogger",
    [new_metaffi_type_info(MetaFFITypes.metaffi_string8_type)],
    [new_metaffi_type_info(MetaFFITypes.metaffi_handle_type)])

error = module.load_entity(
    "class=org.apache.logging.log4j.Logger,callable=error,instance_required",
    [new_metaffi_type_info(MetaFFITypes.metaffi_handle_type),
     new_metaffi_type_info(MetaFFITypes.metaffi_string8_type)],
    None)

logger = getLogger("mylogger")
error(logger, "Hello from Python!")

No bridge code. No rewrites. Just load and call — or generate stubs and call.

See more examples Host Compiler docs

Supported Languages

Language Runtime Status
Go Go runtime via cgo v1.22+
JVM OpenJDK via JNI JDK 11, 21, 22
Python 3 CPython via CPython API v3.11+

Supported Operating Systems

OS Tested
Windows Windows 11, Server 2022
Ubuntu 22.04

How It Works

MetaFFI works like dlopen/LoadLibrary + dlsym/GetProcAddress, but for language modules instead of native binaries. It uses Foreign Function Interface (FFI) and embedding mechanisms to link language runtimes together through a C-based hub. Each language continues to run in its own original runtime — there is no virtual machine, interpreter, or recompilation involved.

The system uses an entity path string to locate functions, methods, fields, and constructors within foreign modules, and a capabilities-based XCall calling convention to marshal data between runtimes using Common Data Types.

Two usage modes: You can call foreign code dynamically using the MetaFFI API, or use the host compiler to generate typed stubs that wrap the API calls for you. Both modes use the same runtime — stubs change ergonomics, not performance.

Read the paper Getting Started Performance