diff --git a/espanso-modulo/src/sys/interop/interop.h b/espanso-modulo/src/sys/interop/interop.h
index abe072c..7c6c5ed 100644
--- a/espanso-modulo/src/sys/interop/interop.h
+++ b/espanso-modulo/src/sys/interop/interop.h
@@ -87,4 +87,28 @@ typedef struct SearchResults {
 typedef struct SearchMetadata {
   const char *windowTitle;
   const char *iconPath;
-} SearchMetadata;
\ No newline at end of file
+} SearchMetadata;
+
+// WIZARD
+
+typedef struct WizardMetadata {
+  const char *version;
+
+  const int is_welcome_page_enabled; 
+  const int is_move_bundle_page_enabled; 
+  const int is_legacy_version_page_enabled; 
+  const int is_migrate_page_enabled; 
+  const int is_add_path_page_enabled; 
+  const int is_accessibility_page_enabled; 
+
+  const char *window_icon_path;
+  const char *accessibility_image_1_path;
+  const char *accessibility_image_2_path;
+
+  // METHODS
+  int (*is_legacy_version_running)();
+  int (*backup_and_migrate)();
+  int (*add_to_path)();
+  int (*enable_accessibility)();
+  int (*is_accessibility_enabled)();
+} WizardMetadata;
\ No newline at end of file
diff --git a/espanso-modulo/src/sys/interop/mod.rs b/espanso-modulo/src/sys/interop/mod.rs
index 1ec8281..9f99451 100644
--- a/espanso-modulo/src/sys/interop/mod.rs
+++ b/espanso-modulo/src/sys/interop/mod.rs
@@ -18,6 +18,7 @@
  */
 
 use std::ffi::c_void;
+use std::os::raw::{c_char, c_int};
 
 pub(crate) trait Interoperable {
   fn as_ptr(&self) -> *const c_void;
@@ -106,7 +107,28 @@ pub struct SearchMetadata {
   pub iconPath: *const ::std::os::raw::c_char,
 }
 
-use std::os::raw::{c_char, c_int};
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct WizardMetadata {
+  pub version: *const c_char,
+
+  pub is_welcome_page_enabled: c_int,
+  pub is_move_bundle_page_enabled: c_int,
+  pub is_legacy_version_page_enabled: c_int,
+  pub is_migrate_page_enabled: c_int,
+  pub is_add_path_page_enabled: c_int,
+  pub is_accessibility_page_enabled: c_int,
+
+  pub window_icon_path: *const c_char,
+  pub accessibility_image_1_path: *const c_char,
+  pub accessibility_image_2_path: *const c_char,
+
+  pub is_legacy_version_running: extern fn() -> c_int,
+  pub backup_and_migrate: extern fn() -> c_int,
+  pub add_to_path: extern fn() -> c_int,
+  pub enable_accessibility: extern fn() -> c_int,
+  pub is_accessibility_enabled: extern fn() -> c_int,
+}
 
 // Native bindings
 
@@ -132,5 +154,5 @@ extern "C" {
   pub(crate) fn update_items(app: *const c_void, items: *const SearchItem, itemCount: c_int);
 
   // WIZARD
-  pub(crate) fn interop_show_wizard();
+  pub(crate) fn interop_show_wizard(metadata: *const WizardMetadata);
 }
diff --git a/espanso-modulo/src/sys/wizard/mod.rs b/espanso-modulo/src/sys/wizard/mod.rs
index 9b35438..3aa6bba 100644
--- a/espanso-modulo/src/sys/wizard/mod.rs
+++ b/espanso-modulo/src/sys/wizard/mod.rs
@@ -17,156 +17,175 @@
  * along with modulo.  If not, see .
  */
 
-use std::ffi::CStr;
-use std::os::raw::{c_char, c_int, c_void};
+use std::os::raw::{c_char, c_int};
+use std::{ffi::CString, sync::Mutex};
 
-pub mod types {
-  // #[derive(Debug)]
-  // pub struct Search {
-  //   pub title: String,
-  //   pub icon: Option,
-  //   pub items: Vec,
-  // }
+use crate::{
+  sys::interop::WizardMetadata,
+  wizard::{WizardHandlers, WizardOptions},
+};
+
+lazy_static! {
+  static ref HANDLERS: Mutex