diff --git a/packages/html/Cargo.toml b/packages/html/Cargo.toml
index e60fcd8e5..91917ee4b 100644
--- a/packages/html/Cargo.toml
+++ b/packages/html/Cargo.toml
@@ -21,6 +21,8 @@ enumset = "1.0.11"
keyboard-types = "0.6.2"
async-trait = "0.1.58"
serde-value = "0.7.0"
+tokio = { version = "1.27", features = ["fs", "io-util"], optional = true }
+rfd = { version = "0.11.3", optional = true }
[dependencies.web-sys]
optional = true
@@ -48,4 +50,5 @@ serde_json = "1"
default = ["serialize"]
serialize = ["serde", "serde_repr", "euclid/serde", "keyboard-types/serde", "dioxus-core/serialize"]
wasm-bind = ["web-sys", "wasm-bindgen"]
+native-bind = ["tokio", "rfd"]
hot-reload-context = ["dioxus-rsx"]
diff --git a/packages/html/src/lib.rs b/packages/html/src/lib.rs
index 55e2e3f30..e02ba2d5a 100644
--- a/packages/html/src/lib.rs
+++ b/packages/html/src/lib.rs
@@ -20,6 +20,8 @@ pub mod events;
pub mod geometry;
mod global_attributes;
pub mod input_data;
+#[cfg(feature = "native-bind")]
+pub mod native_bind;
mod render_template;
#[cfg(feature = "wasm-bind")]
mod web_sys_bind;
diff --git a/packages/html/src/native_bind/mod.rs b/packages/html/src/native_bind/mod.rs
new file mode 100644
index 000000000..4d84a4ab3
--- /dev/null
+++ b/packages/html/src/native_bind/mod.rs
@@ -0,0 +1,3 @@
+mod native_file_engine;
+
+pub use native_file_engine::*;
diff --git a/packages/html/src/native_bind/native_file_engine.rs b/packages/html/src/native_bind/native_file_engine.rs
new file mode 100644
index 000000000..e3291fa36
--- /dev/null
+++ b/packages/html/src/native_bind/native_file_engine.rs
@@ -0,0 +1,43 @@
+use std::path::PathBuf;
+
+use crate::FileEngine;
+use tokio::fs::File;
+use tokio::io::AsyncReadExt;
+
+pub struct NativeFileEngine {
+ files: Vec,
+}
+
+impl NativeFileEngine {
+ pub fn new(files: Vec) -> Self {
+ Self { files }
+ }
+}
+
+#[async_trait::async_trait(?Send)]
+impl FileEngine for NativeFileEngine {
+ fn files(&self) -> Vec {
+ self.files
+ .iter()
+ .filter_map(|f| Some(f.to_str()?.to_string()))
+ .collect()
+ }
+
+ async fn read_file(&self, file: &str) -> Option> {
+ let mut file = File::open(file).await.ok()?;
+
+ let mut contents = Vec::new();
+ file.read_to_end(&mut contents).await.ok()?;
+
+ Some(contents)
+ }
+
+ async fn read_file_to_string(&self, file: &str) -> Option {
+ let mut file = File::open(file).await.ok()?;
+
+ let mut contents = String::new();
+ file.read_to_string(&mut contents).await.ok()?;
+
+ Some(contents)
+ }
+}