Rust edition: this page follows the live DeepWiki structure but treats the current Rust crates as implementation authority. Non-Rust surfaces are identified at their boundary and are not presented as Rust APIs.
Plugin System
Relevant Rust source files
crates/plugin/src/lib.rscrates/plugin/src/manifest.rscrates/plugin/src/host.rscrates/plugin/src/boundary.rs
The NautilusTrader plugin system, implemented in the nautilus-plugin crate, provides a mechanism for loading separately compiled Rust shared libraries (cdylib) at runtime during LiveNode startup This system enables extending the platform's functionality—specifically custom data types, actors, and strategies—without requiring a full recompilation of the core trading engine
Core Architecture
The system operates across a C-ABI boundary to ensure compatibility between the host process (the LiveNode) and the external plugin libraries This is necessary because Rust's default #[repr(Rust)] layout is unstable across different compilations
Plugin Traits
Plugins implement specific traits that define their behavior. The nautilus-plugin crate provides macro-generated glue to adapt these traits to the C-ABI
| Trait | Purpose | Key Callbacks |
|---|---|---|
PluginCustomData |
Defines custom data types for persistence and streaming | from_json, to_json, ts_event |
PluginActor |
Defines a custom component with lifecycle hooks | on_start, on_data, on_stop |
PluginStrategy |
Defines a trading strategy using the HostVTable for commands |
on_bar, on_order_event, on_data |
The nautilus_plugin! Macro
The nautilus_plugin! macro is the primary entry point for plugin authors It handles:
- Generation of the
extern "C"entry symbolnautilus_plugin_init - Construction of the
#[repr(C)]``PluginManifest - Registration of the plugin components within the static manifest structure
Implementation Details
Plugin Manifest and ABI Versioning
Every plugin returns a 'static PluginManifest The host validates this manifest before registration:
- ABI Version: Must match
NAUTILUS_PLUGIN_ABI_VERSION(currently 1) The host rejects manifest ABI mismatches to prevent crashes - Build ID: Contains the
nautilus-pluginversion, Rust compiler version, and target triple - Precision Mode: The host validates that the plugin's
fixed_precisionmatches the host's (e.g., standard vs high-precision) to ensure memory layout compatibility for model types
C-ABI Boundary Handling
Because many Nautilus types (like OrderBook or InstrumentAny) contain heap-allocated Rust collections, they cannot be #[repr(C)] The system uses Handles and Boundary Logic to pass these across the boundary:
- Handles: Opaque
#[repr(C)]wrappers that box the internal type for the duration of a callback - Thunks: Macro-generated
extern "C"functions that dereference handles and provide a borrowed Rust reference (&T) to the user's trait implementation - Panic Guards: Every thunk uses a panic guard to catch unwinding panics and convert them into error codes, preventing undefined behavior at the FFI boundary
Host Interaction (HostVTable)
The host provides a HostVTable to the plugin during initialization This table contains function pointers for re-entrant calls:
- Logging:
logfunction for the plugin to write to the host's log system - Clock: Access to the system time
- Trading Commands: Strategies use this to call commands which the host routes back into the core engines
System Component Interaction
The following diagrams illustrate the relationship between the plugin system and the core Nautilus components.
Natural Language to Code Entity Space: Plugin Initialization
Plugin loading is an explicit sequence: PluginHost loads the library, resolves nautilus_plugin_init, validates ABI and fixed-precision compatibility from PluginManifest, then exposes registration through PluginContext.
Entity Mapping: Plugin to Core
The C ABI boundary exposes stable manifest, version, precision, component and callback contracts. Host internals wrap those contracts in safe Rust ownership; plugin implementation details remain outside the kernel.
Platform and Build Requirements
The plugin system is primarily designed for Linux production environments
Shared Library Formats
Plugins use the platform-native dynamic library format:
- Linux:
lib<name>.so - macOS:
lib<name>.dylib - Windows:
<name>.dll
Identifier Interning
Nautilus uses Ustr for fast string identifiers. Since each cdylib has its own global string cache, the boundary logic re-interns identifiers (e.g., InstrumentId, ClientOrderId) when crossing the boundary to ensure pointer equality works correctly within each side