diff --git a/src/lib.rs b/src/lib.rs
index ccc9682dd334a549d074f51925b414aed39a127a..44daf96cc79de47ea3efd0ea499965537c6b3e3e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,6 +15,8 @@ mod utils;
 mod crdt;
 use crdt::{EventListener, IntervalUnion, Point, StrokeDelta, StrokeID, CRDT};
 
+mod packing;
+
 #[wasm_bindgen]
 extern "C" {
     #[derive(Clone)]
@@ -43,13 +45,13 @@ impl EventListener for WasmEventListener {
     }
 
     fn on_deltas(&self, deltas: HashMap<StrokeID, StrokeDelta>) {
-        self.on_deltas(bincode::serialize(&deltas).unwrap().into_boxed_slice())
+        self.on_deltas(packing::pack(&bincode::serialize(&deltas).unwrap()).into_boxed_slice())
     }
 
     fn on_deltas_from_state(&self, user: String, deltas: HashMap<StrokeID, StrokeDelta>) {
         self.on_deltas_from_state(
             user,
-            bincode::serialize(&deltas).unwrap().into_boxed_slice(),
+            packing::pack(&bincode::serialize(&deltas).unwrap()).into_boxed_slice(),
         )
     }
 }
@@ -115,7 +117,7 @@ impl WasmCRDT {
     }
 
     pub fn apply_deltas(&mut self, deltas: Box<[u8]>) -> Result<(), JsValue> {
-        let deltas = match bincode::deserialize(&deltas) {
+        let deltas = match bincode::deserialize(&packing::unpack(&deltas)) {
             Ok(deltas) => deltas,
             Err(error) => return Err(Error::new(&format!("{:?}", error)).into()),
         };
@@ -124,9 +126,7 @@ impl WasmCRDT {
     }
 
     pub fn get_state_vector(&self) -> Box<[u8]> {
-        bincode::serialize(&self.0.get_state_vector())
-            .unwrap()
-            .into_boxed_slice()
+        packing::pack(&bincode::serialize(&self.0.get_state_vector()).unwrap()).into_boxed_slice()
     }
 
     pub fn fetch_deltas_from_state_vector(
@@ -134,7 +134,7 @@ impl WasmCRDT {
         user: String,
         remote_state: Box<[u8]>,
     ) -> Result<(), JsValue> {
-        let remote_state = match bincode::deserialize(&remote_state) {
+        let remote_state = match bincode::deserialize(&packing::unpack(&remote_state)) {
             Ok(remote_state) => remote_state,
             Err(error) => return Err(Error::new(&format!("{:?}", error)).into()),
         };
diff --git a/src/packing.rs b/src/packing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0168b2f48705592ce4edfe3f93c2b9949b4dbfe7
--- /dev/null
+++ b/src/packing.rs
@@ -0,0 +1,69 @@
+pub fn pack(bytes: &[u8]) -> Vec<u8> {
+    let mut packed = Vec::with_capacity((((bytes.len() as f64) * 1.125f64).ceil() as usize) + 1);
+
+    let mut buffer = Vec::with_capacity(8);
+
+    for slice in bytes.chunks(8) {
+        let mut mask = 0x00u8;
+        let mut marker = 0x80u8;
+
+        for byte in slice {
+            if *byte != 0x00u8 {
+                mask |= marker;
+                buffer.push(*byte);
+            }
+
+            marker >>= 1;
+        }
+
+        packed.push(mask);
+        packed.append(&mut buffer);
+    }
+
+    match bytes.len() % 8 {
+        0 => (),
+        l => packed.push(0xFFu8.wrapping_shl(8u32 - (l as u32))),
+    };
+
+    packed.shrink_to_fit();
+
+    packed
+}
+
+pub fn unpack(bytes: &[u8]) -> Vec<u8> {
+    let mut unpacked = Vec::with_capacity(bytes.len() * 8);
+
+    let mut bytes_iter = bytes.into_iter().peekable();
+
+    while let Some(byte) = bytes_iter.next() {
+        let mask = *byte;
+
+        if mask != 0x00u8 && bytes_iter.peek().is_none() {
+            unpacked.truncate(unpacked.len() - (mask.count_zeros() as usize));
+
+            break;
+        };
+
+        if mask == 0x00u8 {
+            unpacked.resize(unpacked.len() + 8, 0x00u8);
+
+            continue;
+        };
+
+        let mut marker = 0x80u8;
+
+        for _ in 0..8 {
+            if (mask & marker) != 0x00u8 {
+                unpacked.push(*bytes_iter.next().unwrap())
+            } else {
+                unpacked.push(0x00u8)
+            };
+
+            marker >>= 1;
+        }
+    }
+
+    unpacked.shrink_to_fit();
+
+    unpacked
+}
diff --git a/www/index.js b/www/index.js
index 61ae56850bd74ed89edba0e0d128c522e93d0332..3d286bdff6cd1f6485b42b620a2507c8dd323fba 100644
--- a/www/index.js
+++ b/www/index.js
@@ -18,6 +18,8 @@ const crdt = new wasm.WasmCRDT({
   },
 })
 
+console.log("CRDT original StateVec", crdt.get_state_vector())
+
 crdt.set_user("36577c51-a80b-47d6-b3c3-cfb11f705b87")
 
 let stroke_id = crdt.add_stroke(4, 2, 3.14, "ffff00")
@@ -72,8 +74,3 @@ console.log("CRDT2 StateVec", state2)
 console.log("pre fetch deltas from 1 for 2")
 crdt.fetch_deltas_from_state_vector("moritz", state2)
 console.log("post fetch deltas from 1 for 2")
-
-/*console.log("pre apply 1st deltas + fetch events")
-crdt2.apply_deltas(broadcasts[0])
-crdt2.fetch_events()
-console.log("post apply 1st deltas + fetch events")*/
\ No newline at end of file