diff --git a/bevy_kayak_ui/src/render/unified/font/extract.rs b/bevy_kayak_ui/src/render/unified/font/extract.rs
index 3e609e616e0513e85ce25475b5f37d2424ab23ec..71903034e3e0bc35c0779102439f348a62c7dcc7 100644
--- a/bevy_kayak_ui/src/render/unified/font/extract.rs
+++ b/bevy_kayak_ui/src/render/unified/font/extract.rs
@@ -4,7 +4,7 @@ use bevy::{
     sprite2::Rect,
 };
 use kayak_core::render_primitive::RenderPrimitive;
-use kayak_font::{CoordinateSystem, KayakFont};
+use kayak_font::{Alignment, CoordinateSystem, KayakFont};
 
 use crate::{
     render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
@@ -54,8 +54,11 @@ pub fn extract_texts(
 
         let chars_layouts = font.get_layout(
             CoordinateSystem::PositiveYDown,
+            Alignment::Start,
             Vec2::new(layout.posx, layout.posy),
+            Vec2::new(layout.width, layout.height),
             content,
+            font_size * 1.2,
             font_size,
         );
 
diff --git a/kayak_font/examples/bevy.rs b/kayak_font/examples/bevy.rs
index 1fa0e5a6b101202f235dcda432d6b1a28fcb78ff..622d39f4afda084db92de1bc4a638b306fba6d7f 100644
--- a/kayak_font/examples/bevy.rs
+++ b/kayak_font/examples/bevy.rs
@@ -5,7 +5,7 @@ use bevy::{
     window::WindowDescriptor,
     PipelinedDefaultPlugins,
 };
-use kayak_font::{KayakFont, KayakFontPlugin};
+use kayak_font::{Alignment, KayakFont, KayakFontPlugin};
 
 mod renderer;
 use renderer::FontRenderPlugin;
@@ -19,11 +19,39 @@ fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
     commands
         .spawn()
         .insert(Text {
+            horz_alignment: Alignment::Start,
             color: Color::WHITE,
-            content: "Hello World!".into(),
+            content: "Hello World! This text should wrap because its super long!".into(),
             font_size: 32.0,
+            line_height: 32.0 * 1.2, // Firefox method of calculating default line heights see: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
             position: Vec2::new(5.0, 5.0),
-            size: Vec2::new(100.0, 100.0),
+            size: Vec2::new(250.0, 100.0),
+        })
+        .insert(font_handle.clone());
+
+    commands
+        .spawn()
+        .insert(Text {
+            horz_alignment: Alignment::End,
+            color: Color::WHITE,
+            content: "This is some text that will wrap and also be aligned to the right.".into(),
+            font_size: 32.0,
+            line_height: 32.0 * 1.2, // Firefox method of calculating default line heights see: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+            position: Vec2::new(-255.0, 5.0),
+            size: Vec2::new(250.0, 100.0),
+        })
+        .insert(font_handle.clone());
+
+    commands
+        .spawn()
+        .insert(Text {
+            horz_alignment: Alignment::Middle,
+            color: Color::WHITE,
+            content: "This is some text that will wrap and also be aligned in the middle.".into(),
+            font_size: 32.0,
+            line_height: 32.0 * 1.2, // Firefox method of calculating default line heights see: https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
+            position: Vec2::new(-125.0, -155.0),
+            size: Vec2::new(250.0, 100.0),
         })
         .insert(font_handle);
 }
diff --git a/kayak_font/examples/renderer/extract.rs b/kayak_font/examples/renderer/extract.rs
index 2900f192f62848298ebb1c930c4f133928fa84fe..26f0437c960c8f62df18cb84dc6972e2735c56b3 100644
--- a/kayak_font/examples/renderer/extract.rs
+++ b/kayak_font/examples/renderer/extract.rs
@@ -20,8 +20,11 @@ pub fn extract(
         if let Some(font) = fonts.get(font_handle) {
             let layouts = font.get_layout(
                 CoordinateSystem::PositiveYUp,
+                text.horz_alignment,
                 text.position,
+                text.size,
                 &text.content,
+                text.line_height,
                 text.font_size,
             );
 
diff --git a/kayak_font/examples/renderer/text.rs b/kayak_font/examples/renderer/text.rs
index 845e2e47696dd0b1b2d9f7d2969ca0b4fd5efad1..631611f3c6a9274ee8b18e9452621d33e2339574 100644
--- a/kayak_font/examples/renderer/text.rs
+++ b/kayak_font/examples/renderer/text.rs
@@ -1,10 +1,13 @@
 use bevy::{math::Vec2, prelude::Component, render2::color::Color};
+use kayak_font::Alignment;
 
 #[derive(Component)]
 pub struct Text {
+    pub horz_alignment: Alignment,
     pub content: String,
     pub position: Vec2,
     pub size: Vec2,
     pub font_size: f32,
+    pub line_height: f32,
     pub color: Color,
 }
diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs
index 000aeb6c1ef35d279553fc95f37e47f852dff3a4..09e9acaf3da3882a84a79b062857be9b529bc64e 100644
--- a/kayak_font/src/font.rs
+++ b/kayak_font/src/font.rs
@@ -25,12 +25,19 @@ pub struct LayoutRect {
     pub content: char,
 }
 
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq)]
 pub enum CoordinateSystem {
     PositiveYUp,
     PositiveYDown,
 }
 
+#[derive(Copy, Clone, PartialEq)]
+pub enum Alignment {
+    Start,
+    Middle,
+    End,
+}
+
 impl KayakFont {
     pub fn new(sdf: Sdf, atlas_image: Handle<Image>) -> Self {
         Self {
@@ -52,11 +59,36 @@ impl KayakFont {
         self.char_ids.get(&c).and_then(|id| Some(*id))
     }
 
+    pub fn get_word_width(&self, word: &str, font_size: f32) -> f32 {
+        let mut width = 0.0;
+        for c in word.chars() {
+            if let Some(glyph) = self.sdf.glyphs.iter().find(|glyph| glyph.unicode == c) {
+                let plane_bounds = glyph.plane_bounds.as_ref();
+                let (_, _, char_width, _) = match plane_bounds {
+                    Some(val) => (
+                        val.left,
+                        val.top,
+                        val.size().x * font_size,
+                        val.size().y * font_size,
+                    ),
+                    None => (0.0, 0.0, 0.0, 0.0),
+                };
+
+                width += char_width;
+            }
+        }
+
+        width
+    }
+
     pub fn get_layout(
         &self,
         axis_alignment: CoordinateSystem,
+        alignment: Alignment,
         position: Vec2,
+        max_size: Vec2,
         content: &String,
+        line_height: f32,
         font_size: f32,
     ) -> Vec<LayoutRect> {
         let mut positions_and_size = Vec::new();
@@ -64,35 +96,90 @@ impl KayakFont {
         let font_ratio = font_size / self.sdf.atlas.size;
         let resized_max_glyph_size = (max_glyph_size.x * font_ratio, max_glyph_size.y * font_ratio);
 
-        let mut x = 0.0;
-        for c in content.chars() {
-            if let Some(glyph) = self.sdf.glyphs.iter().find(|glyph| glyph.unicode == c) {
-                let plane_bounds = glyph.plane_bounds.as_ref();
-                let (left, top, _width, _height) = match plane_bounds {
-                    Some(val) => (
-                        val.left,
-                        val.top,
-                        val.size().x * font_size,
-                        val.size().y * font_size,
-                    ),
-                    None => (0.0, 0.0, 0.0, 0.0),
-                };
+        // TODO: Make this configurable?
+        let split_chars = vec![' ', '\t', '-', '\n'];
+        let missing_chars: Vec<char> = content
+            .chars()
+            .filter(|c| split_chars.iter().any(|c2| c == c2))
+            .collect();
 
-                let shift_sign = match axis_alignment {
-                    CoordinateSystem::PositiveYDown => -1.0,
-                    CoordinateSystem::PositiveYUp => 1.0,
-                };
+        let shift_sign = match axis_alignment {
+            CoordinateSystem::PositiveYDown => -1.0,
+            CoordinateSystem::PositiveYUp => 1.0,
+        };
 
-                let position_x = position.x + x + left * font_size;
-                let position_y = (position.y + (shift_sign * top * font_size)) + font_size;
+        let mut line_widths = Vec::new();
 
-                positions_and_size.push(LayoutRect {
-                    position: Vec2::new(position_x, position_y),
-                    size: Vec2::new(resized_max_glyph_size.0, resized_max_glyph_size.1),
-                    content: c,
-                });
+        let mut x = 0.0;
+        let mut y = 0.0;
+        let mut i = 0;
+        let mut line_starting_index = 0;
+        let mut last_width = 0.0;
+        for word in content.split(&split_chars[..]) {
+            let word_width = self.get_word_width(word, font_size);
+            if x + word_width > max_size.x {
+                y -= shift_sign * line_height;
+                line_widths.push((x, line_starting_index, positions_and_size.len()));
+                line_starting_index = positions_and_size.len();
+                x = 0.0;
+            }
+            for c in word.chars() {
+                if let Some(glyph) = self.sdf.glyphs.iter().find(|glyph| glyph.unicode == c) {
+                    let plane_bounds = glyph.plane_bounds.as_ref();
+                    let (left, top, width, _height) = match plane_bounds {
+                        Some(val) => (
+                            val.left,
+                            val.top,
+                            val.size().x * font_size,
+                            val.size().y * font_size,
+                        ),
+                        None => (0.0, 0.0, 0.0, 0.0),
+                    };
+
+                    last_width = width;
+
+                    let position_x = x + left * font_size;
+                    let position_y = y + (shift_sign * top * font_size);
+
+                    positions_and_size.push(LayoutRect {
+                        position: Vec2::new(position_x, position_y),
+                        size: Vec2::new(resized_max_glyph_size.0, resized_max_glyph_size.1),
+                        content: c,
+                    });
+
+                    x += glyph.advance * font_size;
+                }
+            }
+            if let Some(next_missing) = missing_chars.get(i) {
+                if let Some(glyph) = self
+                    .sdf
+                    .glyphs
+                    .iter()
+                    .find(|glyph| glyph.unicode == *next_missing)
+                {
+                    x += glyph.advance * font_size;
+                }
+                i += 1;
+            }
+        }
 
-                x += glyph.advance * font_size;
+        line_widths.push((
+            x + last_width,
+            line_starting_index,
+            positions_and_size.len(),
+        ));
+
+        for (line_width, starting_index, end_index) in line_widths {
+            let shift_x = match alignment {
+                Alignment::Start => 0.0,
+                Alignment::Middle => (max_size.x - line_width) / 2.0,
+                Alignment::End => max_size.x - line_width,
+            };
+            for i in starting_index..end_index {
+                let layout_rect = &mut positions_and_size[i];
+
+                layout_rect.position.x += position.x + shift_x;
+                layout_rect.position.y += position.y;
             }
         }