diff --git a/Cargo.lock b/Cargo.lock
index 13791313ef63285cc513593ab15d7aa884fba41d..e220fcdc378c5e2d3a31210ad5357cc8d3852f65 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1332,6 +1332,16 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "dashmap"
+version = "4.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
+dependencies = [
+ "cfg-if 1.0.0",
+ "num_cpus",
+]
+
 [[package]]
 name = "deflate"
 version = "0.8.6"
@@ -1353,6 +1363,17 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "desync"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f27dcf5aa323a4d6fe62caa089e59f280445a5fa64734ffdbe4cdccf2d927a"
+dependencies = [
+ "futures",
+ "lazy_static",
+ "num_cpus",
+]
+
 [[package]]
 name = "diff-struct"
 version = "0.3.1"
@@ -1459,6 +1480,23 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e"
 
+[[package]]
+name = "flo_binding"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711a65cd60b91114a1cecbf6a9d533c3fde6e38532506cde25bc5f7bc87d2fa0"
+dependencies = [
+ "desync",
+ "flo_rope",
+ "futures",
+]
+
+[[package]]
+name = "flo_rope"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "934e2de58fcae0ada41e86f12f49f169d2a0349ebd27fc4cfb3d3ba34db827be"
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1499,17 +1537,53 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "futures"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
 [[package]]
 name = "futures-core"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
+checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
 
 [[package]]
 name = "futures-io"
-version = "0.3.17"
+version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
+checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
 
 [[package]]
 name = "futures-lite"
@@ -1526,6 +1600,47 @@ dependencies = [
  "waker-fn",
 ]
 
+[[package]]
+name = "futures-macro"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
+
+[[package]]
+name = "futures-task"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
+
+[[package]]
+name = "futures-util"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
 [[package]]
 name = "fxhash"
 version = "0.2.1"
@@ -1886,8 +2001,10 @@ name = "kayak_core"
 version = "0.1.0"
 dependencies = [
  "as-any",
+ "dashmap",
  "derivative",
  "diff-struct",
+ "flo_binding",
  "fontdue",
  "kayak_render_macros",
  "morphorm",
@@ -2506,6 +2623,12 @@ version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
 
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
 [[package]]
 name = "pkg-config"
 version = "0.3.22"
diff --git a/examples/bevy.rs b/examples/bevy.rs
index dc9c042deae3ec846a5b6af15b4de9f4bcc31f72..eade83d0f7e9484a8953b84578d665cfc306b05e 100644
--- a/examples/bevy.rs
+++ b/examples/bevy.rs
@@ -12,10 +12,6 @@ use kayak_ui::core::{rsx, widget};
 
 #[widget]
 fn TestState() {
-    let _new_x = {
-        let x = context.create_state(0.0f32).unwrap();
-        *x + 0.1
-    };
     rsx! {
         <>
             <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Window 1".to_string()}>
diff --git a/examples/counter.rs b/examples/counter.rs
index 4e5c163b199b5711d8466a687c966ed5d7e908af..3e555e729e2f53665343840bad6b60b8983c5578 100644
--- a/examples/counter.rs
+++ b/examples/counter.rs
@@ -8,17 +8,13 @@ use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}
 use kayak_components::{Button, Text, Window};
 use kayak_core::{
     styles::{Style, StyleProp, Units},
-    EventType, Index, OnEvent,
+    Bound, EventType, Index, MutableBound, OnEvent,
 };
 use kayak_ui::components::App;
 use kayak_ui::core::{rsx, widget};
 
 #[widget]
 fn Counter(context: &mut KayakContext) {
-    let count = {
-        let x = context.create_state(0i32).unwrap();
-        *x
-    };
     let text_styles = Style {
         bottom: StyleProp::Value(Units::Stretch(1.0)),
         left: StyleProp::Value(Units::Stretch(1.0)),
@@ -28,19 +24,20 @@ fn Counter(context: &mut KayakContext) {
         ..Default::default()
     };
 
-    let id = self.get_id();
-    let on_event = OnEvent::new(move |context, event| match event.event_type {
+    let count = context.create_state(0i32).unwrap();
+    let cloned_count = count.clone();
+    let on_event = OnEvent::new(move |_, event| match event.event_type {
         EventType::Click => {
-            context.set_current_id(id);
-            context.set_state(count + 1);
+            cloned_count.set(cloned_count.get() + 1);
         }
         _ => {}
     });
 
+    let count_value = count.get();
     rsx! {
         <>
             <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Counter Example".to_string()}>
-                <Text size={32.0} content={format!("Current Count: {}", count).to_string()}>{}</Text>
+                <Text size={32.0} content={format!("Current Count: {}", count_value).to_string()}>{}</Text>
                 <Button on_event={Some(on_event)}>
                     <Text styles={Some(text_styles)} size={24.0} content={"Count!".to_string()}>{}</Text>
                 </Button>
diff --git a/examples/full_ui.rs b/examples/full_ui.rs
index 9eed459c4cd41a86d84a949fc6cc0acd2a0576ca..295d11bd0a8de0ffebc3b86606a5e04f4c1fec3d 100644
--- a/examples/full_ui.rs
+++ b/examples/full_ui.rs
@@ -9,7 +9,7 @@ use kayak_components::{NinePatch, Text};
 use kayak_core::{
     layout_cache::Space,
     styles::{LayoutType, Style, StyleProp, Units},
-    widget, Children, EventType, Index, OnEvent,
+    widget, Bound, Children, EventType, Index, MutableBound, OnEvent,
 };
 use kayak_ui::components::App;
 use kayak_ui::core::rsx;
@@ -41,7 +41,7 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>)
         (blue_button_handle, blue_button_hover_handle)
     };
 
-    let current_button_handle = *context.create_state::<u16>(blue_button_handle).unwrap();
+    let current_button_handle = context.create_state::<u16>(blue_button_handle).unwrap();
 
     let button_styles = Style {
         width: StyleProp::Value(Units::Pixels(200.0)),
@@ -53,15 +53,13 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>)
         ..styles.clone().unwrap_or_default()
     };
 
-    let button_id = self.get_id();
-    let on_event = OnEvent::new(move |context, event| match event.event_type {
+    let cloned_current_button_handle = current_button_handle.clone();
+    let on_event = OnEvent::new(move |_context, event| match event.event_type {
         EventType::MouseIn => {
-            context.set_current_id(button_id);
-            context.set_state::<u16>(blue_button_hover_handle);
+            cloned_current_button_handle.set(blue_button_hover_handle);
         }
         EventType::MouseOut => {
-            context.set_current_id(button_id);
-            context.set_state::<u16>(blue_button_handle);
+            cloned_current_button_handle.set(blue_button_handle);
         }
         _ => (),
     });
@@ -74,7 +72,7 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>)
                 top: 10.0,
                 bottom: 10.0,
             }}
-            handle={current_button_handle}
+            handle={current_button_handle.get()}
             styles={Some(button_styles)}
             on_event={Some(on_event)}
         >
diff --git a/kayak_core/Cargo.toml b/kayak_core/Cargo.toml
index 1f1eb406add78c7fc40e27691abdd060d8716e45..10e71dafb74a2aea95e8a99e319082dd9625bddb 100644
--- a/kayak_core/Cargo.toml
+++ b/kayak_core/Cargo.toml
@@ -7,11 +7,11 @@ edition = "2021"
 
 [dependencies]
 as-any = "0.2"
+dashmap = "4.0"
 diff-struct = "0.3"
 derivative = "2.2"
+flo_binding = "2.0.1"
 fontdue = "0.6"
-
 kayak_render_macros = { path = "../kayak_render_macros" }
 morphorm = { git = "https://github.com/geom3trik/morphorm" }
-# dyn_partial_eq = "0.1"
 resources = "1.1"
diff --git a/kayak_core/examples/test3.rs b/kayak_core/examples/test3.rs
index 5907f5b84014c2d2c7b2f00e91a9837e9da10239..e88e0ef3f8ec06ac3cdeed3f4dfc1e7d681a5ae8 100644
--- a/kayak_core/examples/test3.rs
+++ b/kayak_core/examples/test3.rs
@@ -2,12 +2,12 @@ use kayak_core::color::Color;
 use kayak_core::context::KayakContext;
 use kayak_core::render_command::RenderCommand;
 use kayak_core::styles::{Style, StyleProp};
-use kayak_core::{rsx, widget, Children, Index};
+use kayak_core::{rsx, widget, Bound, Children, Index, MutableBound};
 use morphorm::{PositionType, Units};
 
 #[widget]
 fn MyWidget(context: &mut KayakContext, children: Children) {
-    let number = *context.create_state::<u32>(0).unwrap();
+    let number = context.create_state::<u32>(0).unwrap();
     let my_styles = Style {
         render_command: StyleProp::Value(RenderCommand::Quad),
         width: StyleProp::Value(Units::Pixels(300.0)),
@@ -16,7 +16,7 @@ fn MyWidget(context: &mut KayakContext, children: Children) {
         ..Style::default()
     };
     rsx! {
-        <MyWidget2 styles={Some(my_styles)} test={number}>
+        <MyWidget2 styles={Some(my_styles)} test={number.get()}>
             {children}
         </MyWidget2>
     }
@@ -24,7 +24,7 @@ fn MyWidget(context: &mut KayakContext, children: Children) {
 
 #[widget]
 fn MyWidget2(test: u32, children: Children) {
-    let _test = test;
+    dbg!(test);
     rsx! {
         <>
             {children}
@@ -52,7 +52,8 @@ fn main() {
     let mut my_widget = context.widget_manager.take(widget_id);
     my_widget.render(&mut context);
     context.set_current_id(widget_id);
-    context.set_state::<u32>(1);
+    let number = context.create_state::<u32>(0).unwrap();
+    number.set(1);
     my_widget.render(&mut context);
     context.widget_manager.repossess(my_widget);
 
diff --git a/kayak_core/src/binding.rs b/kayak_core/src/binding.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f1221a4063ad8cd6b9dbb60da25e1f54d1dba377
--- /dev/null
+++ b/kayak_core/src/binding.rs
@@ -0,0 +1 @@
+pub use flo_binding::{bind, notify, Binding, Bound, Changeable, MutableBound, Releasable};
diff --git a/kayak_core/src/context.rs b/kayak_core/src/context.rs
index 895ea2aaea2b604e1a1830a1a3a8cb4e3604f55c..582f36514a408b6948cb191aee4ae87730ceb0a0 100644
--- a/kayak_core/src/context.rs
+++ b/kayak_core/src/context.rs
@@ -1,10 +1,11 @@
-use resources::Ref;
+use flo_binding::Changeable;
 use std::collections::HashMap;
 
 use crate::{node::NodeIndex, widget_manager::WidgetManager, Event, EventType, Index, InputEvent};
 
 pub struct KayakContext {
     component_states: HashMap<crate::Index, resources::Resources>,
+    // component_state_lifetimes: DashMap<crate::Index, Vec<Box<dyn crate::Releasable>>>,
     current_id: Index,
     pub widget_manager: WidgetManager,
     last_mouse_position: (f32, f32),
@@ -24,6 +25,7 @@ impl KayakContext {
     pub fn new() -> Self {
         Self {
             component_states: HashMap::new(),
+            // component_state_lifetimes: DashMap::new(),
             current_id: crate::Index::default(),
             widget_manager: WidgetManager::new(),
             last_mouse_position: (0.0, 0.0),
@@ -36,50 +38,94 @@ impl KayakContext {
         self.current_id = id;
     }
 
-    pub fn create_state<T: resources::Resource + Clone>(
+    pub fn create_state<T: resources::Resource + Clone + PartialEq>(
         &mut self,
         initial_state: T,
-    ) -> Option<Ref<T>> {
+    ) -> Option<crate::Binding<T>> {
         if self.component_states.contains_key(&self.current_id) {
             let states = self.component_states.get_mut(&self.current_id).unwrap();
-            if !states.contains::<T>() {
-                states.insert(initial_state);
+            if !states.contains::<crate::Binding<T>>() {
+                let state = crate::bind(initial_state);
+                let dirty_nodes = self.widget_manager.dirty_nodes.clone();
+                let cloned_id = self.current_id;
+                let mut lifetime = state.when_changed(crate::notify(move || {
+                    if let Ok(mut dirty_nodes) = dirty_nodes.lock() {
+                        dirty_nodes.insert(cloned_id);
+                    }
+                }));
+                lifetime.keep_alive();
+                // Self::insert_state_lifetime(
+                //     &mut self.component_state_lifetimes,
+                //     self.current_id,
+                //     lifetime,
+                // );
+                states.insert(state);
             }
         } else {
             let mut states = resources::Resources::default();
-            states.insert(initial_state);
+            let state = crate::bind(initial_state);
+            let dirty_nodes = self.widget_manager.dirty_nodes.clone();
+            let cloned_id = self.current_id;
+            let mut lifetime = state.when_changed(crate::notify(move || {
+                if let Ok(mut dirty_nodes) = dirty_nodes.lock() {
+                    dirty_nodes.insert(cloned_id);
+                }
+            }));
+            lifetime.keep_alive();
+            // Self::insert_state_lifetime(
+            //     &mut self.component_state_lifetimes,
+            //     self.current_id,
+            //     lifetime,
+            // );
+            states.insert(state);
             self.component_states.insert(self.current_id, states);
         }
         return self.get_state();
     }
 
-    fn get_state<T: resources::Resource + Clone>(&self) -> Option<Ref<T>> {
+    // fn insert_state_lifetime(
+    //     lifetimes: &mut DashMap<crate::Index, Vec<Box<dyn crate::Releasable>>>,
+    //     id: Index,
+    //     lifetime: Box<dyn crate::Releasable>,
+    // ) {
+    //     if lifetimes.contains_key(&id) {
+    //         if let Some(mut lifetimes) = lifetimes.get_mut(&id) {
+    //             lifetimes.push(lifetime);
+    //         }
+    //     } else {
+    //         lifetimes.insert(id, vec![lifetime]);
+    //     }
+    // }
+
+    fn get_state<T: resources::Resource + Clone + PartialEq>(&self) -> Option<T> {
         if self.component_states.contains_key(&self.current_id) {
             let states = self.component_states.get(&self.current_id).unwrap();
             if let Ok(state) = states.get::<T>() {
-                return Some(state);
+                return Some(state.clone());
             }
         }
         return None;
     }
 
-    pub fn set_state<T: resources::Resource + Clone>(&mut self, state: T) {
-        if self.component_states.contains_key(&self.current_id) {
-            let states = self.component_states.get(&self.current_id).unwrap();
-            if states.contains::<T>() {
-                let mut mutate_t = states.get_mut::<T>().unwrap();
-                self.widget_manager.dirty_nodes.insert(self.current_id);
-                *mutate_t = state;
-            } else {
-                panic!(
-                    "No specific state created for component with id: {:?}!",
-                    self.current_id
-                );
-            }
-        } else {
-            // Do nothing..
-        }
-    }
+    // pub fn set_state<T: resources::Resource + Clone>(&mut self, state: T) {
+    //     if self.component_states.contains_key(&self.current_id) {
+    //         let states = self.component_states.get(&self.current_id).unwrap();
+    //         if states.contains::<T>() {
+    //             let mut mutate_t = states.get_mut::<T>().unwrap();
+    //             if let Ok(mut dirty_nodes) = self.widget_manager.dirty_nodes.lock() {
+    //                 dirty_nodes.insert(self.current_id);
+    //             }
+    //             *mutate_t = state;
+    //         } else {
+    //             panic!(
+    //                 "No specific state created for component with id: {:?}!",
+    //                 self.current_id
+    //             );
+    //         }
+    //     } else {
+    //         // Do nothing..
+    //     }
+    // }
 
     pub fn set_global_state<T: resources::Resource>(&mut self, state: T) {
         self.global_state.insert(state);
@@ -96,7 +142,12 @@ impl KayakContext {
     }
 
     pub fn render(&mut self) {
-        let dirty_nodes: Vec<_> = self.widget_manager.dirty_nodes.drain().collect();
+        let dirty_nodes: Vec<_> =
+            if let Ok(mut dirty_nodes) = self.widget_manager.dirty_nodes.lock() {
+                dirty_nodes.drain().collect()
+            } else {
+                panic!("Couldn't get lock on dirty nodes!")
+            };
         for node_index in dirty_nodes {
             // if self
             //     .widget_manager
@@ -104,9 +155,9 @@ impl KayakContext {
             //     .iter()
             //     .any(|dirty_index| node_index == *dirty_index)
             // {
-                let mut widget = self.widget_manager.take(node_index);
-                widget.render(self);
-                self.widget_manager.repossess(widget);
+            let mut widget = self.widget_manager.take(node_index);
+            widget.render(self);
+            self.widget_manager.repossess(widget);
             // }
         }
 
diff --git a/kayak_core/src/lib.rs b/kayak_core/src/lib.rs
index 43a1b59fab9e97c0e3a11bdef34d3f84f71e57d7..d5735a447e872319ed76ebca06517e6dd0b51391 100644
--- a/kayak_core/src/lib.rs
+++ b/kayak_core/src/lib.rs
@@ -1,3 +1,4 @@
+mod binding;
 pub mod color;
 pub mod context;
 pub mod event;
@@ -15,6 +16,7 @@ pub mod widget_manager;
 
 use std::sync::{Arc, RwLock};
 
+pub use binding::*;
 pub use context::*;
 pub use event::*;
 pub use fragment::Fragment;
diff --git a/kayak_core/src/widget_manager.rs b/kayak_core/src/widget_manager.rs
index cee0ceafc7582ec01acad79e677c17563c93498b..02e73407d432688d159ec11a283e16d060b58bbc 100644
--- a/kayak_core/src/widget_manager.rs
+++ b/kayak_core/src/widget_manager.rs
@@ -1,4 +1,7 @@
-use std::collections::HashSet;
+use std::{
+    collections::HashSet,
+    sync::{Arc, Mutex},
+};
 
 use crate::{
     layout_cache::LayoutCache,
@@ -15,7 +18,7 @@ use crate::{
 pub struct WidgetManager {
     pub(crate) current_widgets: Arena<Option<Box<dyn Widget>>>,
     pub(crate) dirty_render_nodes: Vec<Index>,
-    pub(crate) dirty_nodes: HashSet<Index>,
+    pub(crate) dirty_nodes: Arc<Mutex<HashSet<Index>>>,
     pub(crate) nodes: Arena<Option<Node>>,
     pub tree: Tree,
     pub node_tree: Tree,
@@ -28,7 +31,7 @@ impl WidgetManager {
         Self {
             current_widgets: Arena::new(),
             dirty_render_nodes: Vec::new(),
-            dirty_nodes: HashSet::new(),
+            dirty_nodes: Arc::new(Mutex::new(HashSet::new())),
             nodes: Arena::new(),
             tree: Tree::default(),
             node_tree: Tree::default(),
@@ -42,12 +45,14 @@ impl WidgetManager {
     /// Can be slow.
     pub fn dirty(&mut self, force: bool) {
         // Force tree to re-render from root.
-        self.dirty_nodes.insert(self.tree.root_node);
+        if let Ok(mut dirty_nodes) = self.dirty_nodes.lock() {
+            dirty_nodes.insert(self.tree.root_node);
 
-        if force {
-            for (node_index, _) in self.current_widgets.iter() {
-                self.dirty_nodes.insert(node_index);
-                self.dirty_render_nodes.push(node_index);
+            if force {
+                for (node_index, _) in self.current_widgets.iter() {
+                    dirty_nodes.insert(node_index);
+                    self.dirty_render_nodes.push(node_index);
+                }
             }
         }
     }
diff --git a/kayak_core/tests/mod.rs b/kayak_core/tests/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6b9848f243c01a755677df80fc6465dda4f3d9ca
--- /dev/null
+++ b/kayak_core/tests/mod.rs
@@ -0,0 +1,31 @@
+#[test]
+fn flo_binding_test() {
+    use flo_binding::{Binding, Bound, Changeable, MutableBound};
+
+    #[derive(Clone, PartialEq)]
+    struct TestState {
+        pub value: u32,
+    }
+
+    let mut some_state = resources::Resources::default();
+
+    let test_state = flo_binding::bind(TestState { value: 0 });
+
+    let mut lifetime = test_state.when_changed(flo_binding::notify(|| {
+        dbg!("Changed!");
+    }));
+
+    some_state.insert(test_state);
+
+    if let Ok(test_state) = some_state.get::<Binding<TestState>>() {
+        assert!(test_state.get().value == 0);
+
+        test_state.set(TestState { value: 2 });
+
+        assert!(test_state.get().value == 2);
+ 
+        lifetime.done();
+    };
+
+    panic!();
+}