diff --git a/Cargo.lock b/Cargo.lock
index 6c03d61194bc176606665f4ccb634032aad37355..fd5004613e29881582d6c631fe27fac3bc42ae51 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1252,27 +1252,6 @@ dependencies = [
  "num_cpus",
 ]
 
-[[package]]
-name = "diff-struct"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f30a0f0aafc8da0d598388b1897310646f45f47f17e31d581b4390f9dd88e826"
-dependencies = [
- "diff_derive",
- "serde",
-]
-
-[[package]]
-name = "diff_derive"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56f9c37d395456d9c1785499421c6288931b6e3dbc2500acb95b8adaa0e69db3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "difference"
 version = "1.0.0"
@@ -1381,16 +1360,6 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
-[[package]]
-name = "fontdue"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8669141fd879e023ac6fcfe1d90dfe3f83ca7e322781ddf3f5be59147e4b8113"
-dependencies = [
- "hashbrown",
- "ttf-parser 0.12.3",
-]
-
 [[package]]
 name = "foreign-types"
 version = "0.3.2"
@@ -1873,9 +1842,7 @@ version = "0.1.0"
 dependencies = [
  "as-any",
  "derivative",
- "diff-struct",
  "flo_binding",
- "fontdue",
  "kayak_render_macros",
  "morphorm",
  "resources",
@@ -1900,6 +1867,7 @@ version = "0.1.0"
 dependencies = [
  "kayak_core",
  "pretty_assertions",
+ "proc-macro-crate 1.1.0",
  "proc-macro-error",
  "proc-macro2",
  "quote",
@@ -1915,15 +1883,6 @@ dependencies = [
  "kayak_core",
  "kayak_font",
  "kayak_render_macros",
- "kayak_widgets",
-]
-
-[[package]]
-name = "kayak_widgets"
-version = "0.1.0"
-dependencies = [
- "bevy",
- "kayak_ui",
 ]
 
 [[package]]
@@ -2473,7 +2432,7 @@ version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "65ee3f72636e6f164cc41c9f9057f4e58c4e13507699ea7f5e5242b64b8198ee"
 dependencies = [
- "ttf-parser 0.13.4",
+ "ttf-parser",
 ]
 
 [[package]]
@@ -3185,12 +3144,6 @@ dependencies = [
  "wasm-bindgen",
 ]
 
-[[package]]
-name = "ttf-parser"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6"
-
 [[package]]
 name = "ttf-parser"
 version = "0.13.4"
diff --git a/Cargo.toml b/Cargo.toml
index 4357ec419d5526a98ea7d84af17a55c5349d53fa..fbbbdafd8bc6bf3a75edbdc8c309c317715e9e3b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,20 +5,14 @@ edition = "2021"
 resolver = "2"
 
 [workspace]
-members = [
-    "bevy_kayak_ui",
-    "kayak_widgets",
-    "kayak_core",
-    "kayak_render_macros",
-    "kayak_font",
-]
+members = ["bevy_kayak_ui", "kayak_core", "kayak_render_macros", "kayak_font"]
 
 [features]
 default = ["bevy_renderer"]
-bevy_renderer = ["bevy_kayak_ui", "kayak_font"]
-internal = ["kayak_core/internal", "kayak_render_macros/internal"]
+bevy_renderer = ["bevy_kayak_ui", "kayak_font", "bevy"]
 
 [dependencies]
+bevy = { git = "https://github.com/bevyengine/bevy", rev = "9a16a4d01830297987db40b45f03382ed3acad62", optional = true }
 kayak_core = { path = "kayak_core" }
 bevy_kayak_ui = { path = "bevy_kayak_ui", optional = true }
 kayak_font = { path = "kayak_font", optional = true }
@@ -26,7 +20,6 @@ kayak_render_macros = { path = "kayak_render_macros" }
 
 [dev-dependencies]
 bevy = { git = "https://github.com/bevyengine/bevy", rev = "9a16a4d01830297987db40b45f03382ed3acad62" }
-kayak_widgets = { path = "kayak_widgets", features = ["bevy_renderer"] }
 
 [[example]]
 name = "todo"
diff --git a/examples/bevy.rs b/examples/bevy.rs
index 99f9f43c7ccb503d6727a51606c03b4f0884f73a..20c50e813d3d8f4dac69c2e0ff331bac0a37c906 100644
--- a/examples/bevy.rs
+++ b/examples/bevy.rs
@@ -6,7 +6,7 @@ use bevy::{
 use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle};
 use kayak_ui::core::Index;
 use kayak_ui::core::{render, rsx, widget};
-use kayak_widgets::{App, Window};
+use kayak_ui::widgets::{App, Window};
 
 #[widget]
 fn CustomWidget() {
diff --git a/examples/clipping.rs b/examples/clipping.rs
index 84d279635579f51abf8326e2a87e30af0fbac8ba..96c592296c9622c71415b35aba00bcb73edcd05d 100644
--- a/examples/clipping.rs
+++ b/examples/clipping.rs
@@ -10,7 +10,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     Index,
 };
-use kayak_widgets::{App, Clip, NinePatch, Text};
+use kayak_ui::widgets::{App, Clip, NinePatch, Text};
 
 fn startup(
     mut commands: Commands,
diff --git a/examples/counter.rs b/examples/counter.rs
index 8df23d6e9cbce9d3ebd5ad82aa7bf7f1f8792fbe..4c829c4893365ba250d766525bc69c8f3d2858af 100644
--- a/examples/counter.rs
+++ b/examples/counter.rs
@@ -9,7 +9,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     use_state, widget, Bound, EventType, Index, MutableBound, OnEvent,
 };
-use kayak_widgets::{App, Button, Text, Window};
+use kayak_ui::widgets::{App, Button, Text, Window};
 
 #[widget]
 fn Counter(context: &mut KayakContext) {
diff --git a/examples/full_ui.rs b/examples/full_ui.rs
index b32f72e2fc5fa93070e6392e97e47403477ee2b1..9c8a445800a329ba0cbc51439b965a736e2e1f96 100644
--- a/examples/full_ui.rs
+++ b/examples/full_ui.rs
@@ -10,7 +10,7 @@ use kayak_ui::core::{
     styles::{LayoutType, Style, StyleProp, Units},
     widget, Bound, Children, EventType, Index, MutableBound, OnEvent,
 };
-use kayak_widgets::{App, NinePatch, Text};
+use kayak_ui::widgets::{App, NinePatch, Text};
 
 #[widget]
 fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>) {
diff --git a/examples/global_counter.rs b/examples/global_counter.rs
index e6f0ee7cf0ee7dc38bfaacfbba9a07145bc479a7..072b7d83ef96936f91ac230c473db754e157ea22 100644
--- a/examples/global_counter.rs
+++ b/examples/global_counter.rs
@@ -5,7 +5,7 @@ use bevy::{
 };
 use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle};
 use kayak_ui::core::{bind, render, rsx, widget, Binding, Bound, Index, MutableBound};
-use kayak_widgets::{App, Text, Window};
+use kayak_ui::widgets::{App, Text, Window};
 
 #[derive(Clone, PartialEq)]
 struct GlobalCount(pub u32);
diff --git a/examples/if.rs b/examples/if.rs
index 2fb918b45d45a271fad0b008b695df8e57ef5f7d..237718811f794496acea717ca4bc97c190a4b2cf 100644
--- a/examples/if.rs
+++ b/examples/if.rs
@@ -9,7 +9,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     widget, Bound, EventType, Index, MutableBound, OnEvent,
 };
-use kayak_widgets::{App, Button, If, Text, Window};
+use kayak_ui::widgets::{App, Button, If, Text, Window};
 
 #[widget]
 fn Removal(context: &mut KayakContext) {
diff --git a/examples/image.rs b/examples/image.rs
index e8ca07f45e7299dd9904d4c32c0003d2e4f2b1d3..9ec14ed303f69d2e4a1fc48d29358bd8aebcefe6 100644
--- a/examples/image.rs
+++ b/examples/image.rs
@@ -9,7 +9,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     Index,
 };
-use kayak_widgets::{App, Image};
+use kayak_ui::widgets::{App, Image};
 
 fn startup(
     mut commands: Commands,
diff --git a/examples/nine_patch.rs b/examples/nine_patch.rs
index 0262434e435e409ac46bf77962e389f85f621cf7..0498f7aaf810ae640e9512c9d1805cb9ad17ef1c 100644
--- a/examples/nine_patch.rs
+++ b/examples/nine_patch.rs
@@ -10,7 +10,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     Index,
 };
-use kayak_widgets::{App, NinePatch};
+use kayak_ui::widgets::{App, NinePatch};
 
 fn startup(
     mut commands: Commands,
diff --git a/examples/text_box.rs b/examples/text_box.rs
index bbf01ecf85817d091a3c009443266ac9daf0efab..1a1ffe3fceee20da39f1797c1d9e5e69f7265a5a 100644
--- a/examples/text_box.rs
+++ b/examples/text_box.rs
@@ -9,7 +9,7 @@ use kayak_ui::core::{
     styles::{Style, StyleProp, Units},
     widget, Bound, Index, MutableBound,
 };
-use kayak_widgets::{App, OnChange, TextBox, Window};
+use kayak_ui::widgets::{App, OnChange, TextBox, Window};
 
 #[widget]
 fn TextBoxExample(context: &mut KayakContext) {
diff --git a/examples/todo/add_button.rs b/examples/todo/add_button.rs
index febec9746dc9d0d23c8fba8d91d734cc74ef367c..3aeec1229d3d9ff2b4921300cad97aaffe60b6b4 100644
--- a/examples/todo/add_button.rs
+++ b/examples/todo/add_button.rs
@@ -6,7 +6,7 @@ use kayak_ui::core::{
     use_state, widget, Bound, Children, EventType, MutableBound, OnEvent,
 };
 
-use kayak_widgets::{Background, Text};
+use kayak_ui::widgets::{Background, Text};
 
 #[widget]
 pub fn AddButton(children: Children, styles: Option<Style>) {
diff --git a/examples/todo/card.rs b/examples/todo/card.rs
index 15c6d03748afea9df7dda0a62be45414d803f96f..06cf2217bc24beb08bacff3bf51ff771864b2e3a 100644
--- a/examples/todo/card.rs
+++ b/examples/todo/card.rs
@@ -1,9 +1,9 @@
-use kayak_core::{
+use kayak_ui::core::{
     rsx,
     styles::{LayoutType, Style, StyleProp, Units},
     widget, Color, EventType, Handler, OnEvent,
 };
-use kayak_widgets::{Background, Text};
+use kayak_ui::widgets::{Background, Text};
 
 use super::delete_button::DeleteButton;
 
diff --git a/examples/todo/cards.rs b/examples/todo/cards.rs
index 5307aba481643aa53eebfed2cacca473ae42bff9..96b6661173ef15f1adaaa1f96fe4508d000c5286 100644
--- a/examples/todo/cards.rs
+++ b/examples/todo/cards.rs
@@ -1,5 +1,5 @@
-use kayak_core::{constructor, rsx, widget, Handler, VecTracker};
-use kayak_widgets::Element;
+use kayak_ui::core::{constructor, rsx, widget, Handler, VecTracker};
+use kayak_ui::widgets::Element;
 
 use super::{card::Card, Todo};
 
diff --git a/examples/todo/delete_button.rs b/examples/todo/delete_button.rs
index e7a59719072753e5021c779cf87b2ee0d644e2a4..3720ba4872cbec95583f8ac0520861a872c2eba2 100644
--- a/examples/todo/delete_button.rs
+++ b/examples/todo/delete_button.rs
@@ -6,7 +6,7 @@ use kayak_ui::core::{
     use_state, widget, Bound, Children, EventType, MutableBound, OnEvent,
 };
 
-use kayak_widgets::{Background, Text};
+use kayak_ui::widgets::{Background, Text};
 
 #[widget]
 pub fn DeleteButton(children: Children, styles: Option<Style>) {
diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs
index 4e16a2194ad2f4dafe63ccb95278996ad74ae6b6..de0c5943c949be051c0fbabee273e311ce2ae7ec 100644
--- a/examples/todo/todo.rs
+++ b/examples/todo/todo.rs
@@ -9,7 +9,7 @@ use kayak_ui::core::{
     styles::{LayoutType, Style, StyleProp, Units},
     use_state, widget, Bound, EventType, Handler, Index, MutableBound, OnEvent,
 };
-use kayak_widgets::{App, Element, OnChange, TextBox, Window};
+use kayak_ui::widgets::{App, Element, OnChange, TextBox, Window};
 
 mod add_button;
 mod card;
diff --git a/examples/vec_widget.rs b/examples/vec_widget.rs
index 03d5f2f82de9297e6fb9775581283190a994eb02..eddaa6a0fbcc9cf42366b5a4a6ae8866163c79d5 100644
--- a/examples/vec_widget.rs
+++ b/examples/vec_widget.rs
@@ -3,10 +3,9 @@ use bevy::{
     window::WindowDescriptor,
     DefaultPlugins,
 };
-use kayak_core::constructor;
 use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle};
-use kayak_ui::core::{render, Index, VecTracker};
-use kayak_widgets::{App, Text};
+use kayak_ui::core::{constructor, render, Index, VecTracker};
+use kayak_ui::widgets::{App, Text};
 
 fn startup(
     mut commands: Commands,
diff --git a/kayak_core/Cargo.toml b/kayak_core/Cargo.toml
index cfc3d80ea6f25f6c04db574abfa6eee302cfa516..5baddb04782de7d4218520f0e41e9cfc54f0c90e 100644
--- a/kayak_core/Cargo.toml
+++ b/kayak_core/Cargo.toml
@@ -7,14 +7,11 @@ edition = "2021"
 
 [features]
 default = []
-internal = ["kayak_render_macros/internal"]
 
 [dependencies]
 as-any = "0.2"
-diff-struct = "0.3"
 derivative = "2.2"
 flo_binding = { git = "https://github.com/StarArawn/flo_binding.git", rev = "c78431a56df5ec082b7e1c271871e6c0ac75e81e" }
-fontdue = "0.6"
 kayak_render_macros = { path = "../kayak_render_macros" }
 morphorm = { git = "https://github.com/geom3trik/morphorm", rev = "1243152d4cebea46fd3e5098df26402c73acae91" }
 resources = "1.1"
diff --git a/kayak_core/examples/diff_test.rs b/kayak_core/examples/diff_test.rs
deleted file mode 100644
index 68ac8fb1b989aa2fbf6ddd6e9d503cd42b8f2837..0000000000000000000000000000000000000000
--- a/kayak_core/examples/diff_test.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-use kayak_core::{tree::Tree, widget, Arena, Index, Widget};
-
-#[widget]
-fn Widget1() {}
-
-pub fn main() {
-    let widget1 = Widget1 {
-        id: Index::default(),
-        styles: None,
-        children: None,
-        on_event: None,
-    };
-
-    let widget2 = Widget1 {
-        id: Index::default(),
-        styles: None,
-        children: None,
-        on_event: None,
-    };
-
-    let widget3 = Widget1 {
-        id: Index::default(),
-        styles: None,
-        children: None,
-        on_event: None,
-    };
-
-    let widget4 = Widget1 {
-        id: Index::default(),
-        styles: None,
-        children: None,
-        on_event: None,
-    };
-
-    // let widget5 = Widget1 {
-    //     id: Index::default(),
-    //     styles: None,
-    //     children: None,
-    //     on_event: None,
-    // };
-
-    let mut widgets = Arena::<Box<dyn Widget>>::default();
-    let widget1_id = widgets.insert(Box::new(widget1));
-    let widget2_id = widgets.insert(Box::new(widget2));
-    let widget3_id = widgets.insert(Box::new(widget3));
-    let widget4_id = widgets.insert(Box::new(widget4));
-    // let widget5_id = widgets.insert(Box::new(widget5));
-
-    let mut tree1 = Tree::default();
-    tree1.add(widget1_id, None);
-    tree1.add(widget2_id, Some(widget1_id));
-    tree1.add(widget3_id, Some(widget2_id));
-    // tree1.add(1, widget3_id, Some(widget1_id));
-    // tree1.add(2, widget4_id, Some(widget1_id));
-
-    let mut tree2 = Tree::default();
-    tree2.add(widget1_id, None);
-    tree2.add(widget2_id, Some(widget1_id));
-    // tree2.add(0, widget3_id, Some(widget1_id));
-    // tree2.add(1, widget4_id, Some(widget1_id));
-    // tree2.add(2, widget5_id, Some(widget1_id));
-
-    let changes = tree1.diff_children(&tree2, widget1_id);
-    dbg!(&changes);
-    tree1.merge(&tree2, widget1_id, changes);
-
-    let changes = tree1.diff_children(&tree2, widget1_id);
-
-    dbg!(&changes);
-
-    assert!(tree1 == tree2);
-
-    let mut tree1 = Tree::default();
-    tree1.add(widget1_id, None);
-    tree1.add(widget2_id, Some(widget1_id));
-    tree1.add(widget3_id, Some(widget2_id));
-
-    let mut tree2 = Tree::default();
-    tree2.add(widget1_id, None);
-    tree2.add(widget2_id, Some(widget1_id));
-    tree2.add(widget4_id, Some(widget2_id));
-
-    let changes = tree1.diff_children(&tree2, widget1_id);
-    dbg!(&changes);
-
-    tree1.merge(&tree2, widget1_id, changes);
-    let differences = tree1.diff_children(&tree2, widget1_id);
-    dbg!(differences);
-}
diff --git a/kayak_core/examples/test3.rs b/kayak_core/examples/test3.rs
deleted file mode 100644
index e88e0ef3f8ec06ac3cdeed3f4dfc1e7d681a5ae8..0000000000000000000000000000000000000000
--- a/kayak_core/examples/test3.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-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, 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 my_styles = Style {
-        render_command: StyleProp::Value(RenderCommand::Quad),
-        width: StyleProp::Value(Units::Pixels(300.0)),
-        height: StyleProp::Value(Units::Pixels(300.0)),
-        background_color: StyleProp::Value(Color::BLACK),
-        ..Style::default()
-    };
-    rsx! {
-        <MyWidget2 styles={Some(my_styles)} test={number.get()}>
-            {children}
-        </MyWidget2>
-    }
-}
-
-#[widget]
-fn MyWidget2(test: u32, children: Children) {
-    dbg!(test);
-    rsx! {
-        <>
-            {children}
-        </>
-    }
-}
-
-fn main() {
-    let mut context = KayakContext::new();
-
-    let my_widget = MyWidget {
-        id: Index::default(),
-        children: None,
-        styles: Some(Style {
-            position_type: StyleProp::Value(PositionType::SelfDirected),
-            width: StyleProp::Value(Units::Pixels(1280.0)),
-            height: StyleProp::Value(Units::Pixels(720.0)),
-            ..Style::default()
-        }),
-        on_event: None,
-    };
-
-    let (_, widget_id) = context.widget_manager.create_widget(0, my_widget, None);
-
-    let mut my_widget = context.widget_manager.take(widget_id);
-    my_widget.render(&mut context);
-    context.set_current_id(widget_id);
-    let number = context.create_state::<u32>(0).unwrap();
-    number.set(1);
-    my_widget.render(&mut context);
-    context.widget_manager.repossess(my_widget);
-
-    context.widget_manager.render();
-
-    context.widget_manager.calculate_layout();
-
-    dbg!(context.widget_manager.build_render_primitives());
-}
diff --git a/kayak_core/src/lib.rs b/kayak_core/src/lib.rs
index 9aa48f8af93bd76cbe20f455ecf08a0e3a996a20..de1758f63b1ed3303279de448597c7baece81331 100644
--- a/kayak_core/src/lib.rs
+++ b/kayak_core/src/lib.rs
@@ -26,7 +26,6 @@ pub use event::*;
 pub use fragment::Fragment;
 pub use generational_arena::{Arena, Index};
 pub use input_event::*;
-pub use kayak_render_macros::{constructor, render, rsx, use_state, widget};
 pub use keys::KeyCode;
 pub use resources::Resources;
 pub use tree::{Tree, WidgetTree};
diff --git a/kayak_render_macros/Cargo.toml b/kayak_render_macros/Cargo.toml
index b8539a0b19bd09f0a07d240a1c055009d2f796c9..3866bb4e99a880687d51c176f557c10c407ee43b 100644
--- a/kayak_render_macros/Cargo.toml
+++ b/kayak_render_macros/Cargo.toml
@@ -8,13 +8,13 @@ proc-macro = true
 
 [features]
 default = []
-internal = []
 
 [dependencies]
 syn = { version = "1.0", features = ["full"] }
 quote = "1.0"
 proc-macro2 = "1.0"
 proc-macro-error = "1.0"
+proc-macro-crate = "1.1"
 
 [dev-dependencies]
 kayak_core = { path = "../kayak_core", version = "0.1.0" }
diff --git a/kayak_render_macros/src/children.rs b/kayak_render_macros/src/children.rs
index 0d1aea6f31e5aa19df12c7caee3f718fac86e6f4..577ed7448c118a5a5672c64d6dc634332d7fb2bb 100644
--- a/kayak_render_macros/src/children.rs
+++ b/kayak_render_macros/src/children.rs
@@ -52,10 +52,14 @@ impl Children {
     }
 
     pub fn as_option_of_tuples_tokens(&self) -> proc_macro2::TokenStream {
-        #[cfg(feature = "internal")]
-        let kayak_core = quote! { kayak_core };
-        #[cfg(not(feature = "internal"))]
-        let kayak_core = quote! { kayak_ui::core };
+        let found_crate = proc_macro_crate::crate_name("kayak_core").unwrap();
+        let kayak_core = match found_crate {
+            proc_macro_crate::FoundCrate::Itself => quote! { crate },
+            proc_macro_crate::FoundCrate::Name(name) => {
+                let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
+                quote!(#ident)
+            }
+        };
 
         let children_quotes: Vec<_> = self
             .nodes
diff --git a/kayak_render_macros/src/function_component.rs b/kayak_render_macros/src/function_component.rs
index 703f54b45b7115fa9a68a5b5f8bd21807591ad7a..a30d04ec7c4855afc1165faa6f49492c30610feb 100644
--- a/kayak_render_macros/src/function_component.rs
+++ b/kayak_render_macros/src/function_component.rs
@@ -20,10 +20,14 @@ pub fn create_function_widget(f: syn::ItemFn, widget_arguments: WidgetArguments)
     let block = f.block;
     let vis = f.vis;
 
-    #[cfg(feature = "internal")]
-    let kayak_core = quote! { kayak_core };
-    #[cfg(not(feature = "internal"))]
-    let kayak_core = quote! { kayak_ui::core };
+    let found_crate = proc_macro_crate::crate_name("kayak_core").unwrap();
+    let kayak_core = match found_crate {
+        proc_macro_crate::FoundCrate::Itself => quote! { crate },
+        proc_macro_crate::FoundCrate::Name(name) => {
+            let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
+            quote!(#ident)
+        }
+    };
 
     let focusable = widget_arguments.focusable;
 
diff --git a/kayak_render_macros/src/tags.rs b/kayak_render_macros/src/tags.rs
index 0448e81dcf26fcdbd4dff193937778ea929a53a4..508e77491eb278315b114d76647c165a3e7bbd7b 100644
--- a/kayak_render_macros/src/tags.rs
+++ b/kayak_render_macros/src/tags.rs
@@ -12,10 +12,14 @@ pub struct OpenTag {
 }
 
 fn name_or_fragment(maybe_name: Result<syn::Path>) -> syn::Path {
-    #[cfg(feature = "internal")]
-    let kayak_core = "kayak_core";
-    #[cfg(not(feature = "internal"))]
-    let kayak_core = "kayak_ui::core";
+    let found_crate = proc_macro_crate::crate_name("kayak_core").unwrap();
+    let kayak_core = match found_crate {
+        proc_macro_crate::FoundCrate::Itself => quote! { crate },
+        proc_macro_crate::FoundCrate::Name(name) => {
+            let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
+            quote!(#ident)
+        }
+    };
 
     maybe_name.unwrap_or_else(|_| {
         syn::parse_str::<syn::Path>(&format!("::{}::Fragment", kayak_core)).unwrap()
diff --git a/kayak_widgets/.gitignore b/kayak_widgets/.gitignore
deleted file mode 100644
index cdd43adbcc41cc49dcf80afe3af9f0b5e67fee4c..0000000000000000000000000000000000000000
--- a/kayak_widgets/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-target
-
-# These are backup files generated by rustfmt
-**/*.rs.bk
-
-# MSVC Windows builds of rustc generate these, which store debugging information
-*.pdb
\ No newline at end of file
diff --git a/kayak_widgets/Cargo.toml b/kayak_widgets/Cargo.toml
deleted file mode 100644
index eb370679f189f54dbaaf26497657b3708e8e7a47..0000000000000000000000000000000000000000
--- a/kayak_widgets/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "kayak_widgets"
-version = "0.1.0"
-edition = "2021"
-resolver = "2"
-
-[features]
-default = []
-bevy_renderer = ["bevy", "kayak_ui/bevy_renderer"]
-
-[dependencies]
-kayak_ui = { path = "../", version = "0.1.0" }
-bevy = { git = "https://github.com/bevyengine/bevy", rev = "9a16a4d01830297987db40b45f03382ed3acad62", optional = true }
diff --git a/src/lib.rs b/src/lib.rs
index c9e09654668f173533496505ffa6fc36f4977159..b9cbe3777cb6af858295f3fa41a50a2b28372424 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
 pub mod core {
     pub use kayak_core::*;
+    pub use kayak_render_macros::{constructor, render, rsx, use_state, widget};
 }
 
 #[cfg(feature = "bevy_renderer")]
@@ -11,3 +12,5 @@ pub mod font {
 pub mod bevy {
     pub use bevy_kayak_ui::*;
 }
+
+pub mod widgets;
diff --git a/kayak_widgets/src/app.rs b/src/widgets/app.rs
similarity index 83%
rename from kayak_widgets/src/app.rs
rename to src/widgets/app.rs
index 76ff212704287e7894b381f993380d37edefb9de..2d611382aeacea54d51dcdf9b39fd39dc00f5d94 100644
--- a/kayak_widgets/src/app.rs
+++ b/src/widgets/app.rs
@@ -1,12 +1,12 @@
-use kayak_ui::core::derivative::*;
-use kayak_ui::core::{
+use crate::core::derivative::*;
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp},
     widget, Children,
 };
 
-use crate::Clip;
+use crate::widgets::Clip;
 
 #[widget]
 pub fn App(children: Children) {
@@ -17,9 +17,9 @@ pub fn App(children: Children) {
 
     #[cfg(feature = "bevy_renderer")]
     {
-        use kayak_ui::bevy::WindowSize;
-        use kayak_ui::core::styles::Units;
-        use kayak_ui::core::{Binding, Bound};
+        use crate::bevy::WindowSize;
+        use crate::core::styles::Units;
+        use crate::core::{Binding, Bound};
         let window_size = if let Ok(world) = context.get_global_state::<bevy::prelude::World>() {
             if let Some(window_size) = world.get_resource::<Binding<WindowSize>>() {
                 window_size.clone()
diff --git a/kayak_widgets/src/background.rs b/src/widgets/background.rs
similarity index 95%
rename from kayak_widgets/src/background.rs
rename to src/widgets/background.rs
index f084ec1535582b8de54c753054f668586f643d15..abc0a7b075ded572c941a0b8d157e1460bcef7ab 100644
--- a/kayak_widgets/src/background.rs
+++ b/src/widgets/background.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp},
diff --git a/kayak_widgets/src/button.rs b/src/widgets/button.rs
similarity index 97%
rename from kayak_widgets/src/button.rs
rename to src/widgets/button.rs
index 31a36482c4622d370ac8ad054037fdd61e7430b7..5c05b4dedd50dd50cef921c6cb30b1e5fe2b55c9 100644
--- a/kayak_widgets/src/button.rs
+++ b/src/widgets/button.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     color::Color,
     render_command::RenderCommand,
     rsx,
diff --git a/kayak_widgets/src/clip.rs b/src/widgets/clip.rs
similarity index 96%
rename from kayak_widgets/src/clip.rs
rename to src/widgets/clip.rs
index 5c5f212422d873094608e4abc8e8e13ff2fb9661..0a0fec4b10e8d9b20de40167f3c0823924176713 100644
--- a/kayak_widgets/src/clip.rs
+++ b/src/widgets/clip.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp, Units},
diff --git a/kayak_widgets/src/element.rs b/src/widgets/element.rs
similarity index 94%
rename from kayak_widgets/src/element.rs
rename to src/widgets/element.rs
index 3c14e83e21e95384ba1ff4d538c77d4e90e07717..e5fdadcd9ec25a5879bdcf6fc433966314224f32 100644
--- a/kayak_widgets/src/element.rs
+++ b/src/widgets/element.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp},
diff --git a/kayak_widgets/src/if_element.rs b/src/widgets/if_element.rs
similarity index 80%
rename from kayak_widgets/src/if_element.rs
rename to src/widgets/if_element.rs
index c2e29174ae80458c0fbc67180a34ad3ff272dcaf..dfe49a94ffde9adacb2d49bee5162f29aacf92df 100644
--- a/kayak_widgets/src/if_element.rs
+++ b/src/widgets/if_element.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{rsx, widget, Children};
+use crate::core::{rsx, widget, Children};
 
 #[widget]
 pub fn If(children: Children, condition: bool) {
diff --git a/kayak_widgets/src/image.rs b/src/widgets/image.rs
similarity index 94%
rename from kayak_widgets/src/image.rs
rename to src/widgets/image.rs
index c44cb604da9d967b9655e20bd8862b3588c194f9..6b97d32388c7be8ed0ad1a4252e61a600358e581 100644
--- a/kayak_widgets/src/image.rs
+++ b/src/widgets/image.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp},
diff --git a/kayak_widgets/src/lib.rs b/src/widgets/mod.rs
similarity index 100%
rename from kayak_widgets/src/lib.rs
rename to src/widgets/mod.rs
diff --git a/kayak_widgets/src/nine_patch.rs b/src/widgets/nine_patch.rs
similarity index 95%
rename from kayak_widgets/src/nine_patch.rs
rename to src/widgets/nine_patch.rs
index f491da9c2d009b5d1e8fcff892b58693f39dddd7..c462e16ccbe5e8b9f4025a0bb3930fccf30759ee 100644
--- a/kayak_widgets/src/nine_patch.rs
+++ b/src/widgets/nine_patch.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     layout_cache::Space,
     render_command::RenderCommand,
     rsx,
diff --git a/kayak_widgets/src/text.rs b/src/widgets/text.rs
similarity index 95%
rename from kayak_widgets/src/text.rs
rename to src/widgets/text.rs
index c09e6baf6f2e35dc4d0e74ae7c3d6a36435c0c27..14979eef101361836515ec29face106f591b2074 100644
--- a/kayak_widgets/src/text.rs
+++ b/src/widgets/text.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     styles::{Style, StyleProp},
     widget,
diff --git a/kayak_widgets/src/text_box.rs b/src/widgets/text_box.rs
similarity index 98%
rename from kayak_widgets/src/text_box.rs
rename to src/widgets/text_box.rs
index 2a7f61200db0eb59418a59afba399cfa223b35eb..ee5ab760756da333448f0de2dbcd52fe146bd203 100644
--- a/kayak_widgets/src/text_box.rs
+++ b/src/widgets/text_box.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     render_command::RenderCommand,
     rsx,
     styles::{Style, StyleProp, Units},
@@ -6,7 +6,7 @@ use kayak_ui::core::{
 };
 use std::sync::{Arc, RwLock};
 
-use crate::{Background, Clip, Text};
+use crate::widgets::{Background, Clip, Text};
 
 #[derive(Debug, Clone, PartialEq)]
 pub struct ChangeEvent {
diff --git a/kayak_widgets/src/window.rs b/src/widgets/window.rs
similarity index 97%
rename from kayak_widgets/src/window.rs
rename to src/widgets/window.rs
index de54a980172679e51a44601f85331869fc04fd56..cfbe04bba6efe47f3101664b2c4ec1a42a8a7d7c 100644
--- a/kayak_widgets/src/window.rs
+++ b/src/widgets/window.rs
@@ -1,4 +1,4 @@
-use kayak_ui::core::{
+use crate::core::{
     color::Color,
     render_command::RenderCommand,
     rsx,
@@ -6,7 +6,7 @@ use kayak_ui::core::{
     widget, Children,
 };
 
-use crate::{Background, Clip, Element, Text};
+use crate::widgets::{Background, Clip, Element, Text};
 
 #[widget]
 pub fn Window(