diff --git a/src/descriptors/struct_desc.rs b/src/descriptors/struct_desc.rs
index dbeac4d..f0984ff 100644
--- a/src/descriptors/struct_desc.rs
+++ b/src/descriptors/struct_desc.rs
@@ -90,7 +90,7 @@ impl Descriptor for StructDescriptor {
 }
 
 impl StructDescriptor {
-    pub fn new(input: &syn::DataStruct, ident: syn::Ident) -> Self {
+    pub fn new(input: &syn::DataStruct, ident: syn::Ident, packed_struct: bool) -> Self {
         let mut descriptor = StructDescriptor {
             ty: ident,
             version: 1, // struct start at version 1.
@@ -98,17 +98,18 @@ impl StructDescriptor {
         };
 
         // Fills self.fields.
-        descriptor.parse_struct_fields(&input.fields);
+        descriptor.parse_struct_fields(&input.fields, packed_struct);
         descriptor.version = compute_version(&descriptor.fields);
         descriptor
     }
 
-    fn parse_struct_fields(&mut self, fields: &syn::Fields) {
+    fn parse_struct_fields(&mut self, fields: &syn::Fields, packed_struct: bool) {
         match fields {
             syn::Fields::Named(ref named_fields) => {
                 let pairs = named_fields.named.pairs();
                 for field in pairs.into_iter() {
-                    self.fields.push(StructField::new(self.version, field));
+                    self.fields
+                        .push(StructField::new(self.version, field, packed_struct));
                 }
             }
             _ => panic!("Only named fields are supported."),
diff --git a/src/fields/struct_field.rs b/src/fields/struct_field.rs
index 982a50e..4b03b74 100644
--- a/src/fields/struct_field.rs
+++ b/src/fields/struct_field.rs
@@ -14,6 +14,7 @@ pub(crate) struct StructField {
     start_version: u16,
     end_version: u16,
     attrs: HashMap<String, syn::Lit>,
+    packed_struct: bool,
 }
 
 impl Exists for StructField {
@@ -36,6 +37,7 @@ impl StructField {
     pub fn new(
         base_version: u16,
         ast_field: syn::punctuated::Pair<&syn::Field, &syn::token::Comma>,
+        packed_struct: bool,
     ) -> Self {
         let attrs = parse_field_attributes(&ast_field.value().attrs);
 
@@ -45,6 +47,7 @@ impl StructField {
             start_version: get_start_version(&attrs).unwrap_or(base_version),
             end_version: get_end_version(&attrs).unwrap_or_default(),
             attrs,
+            packed_struct,
         }
     }
 
@@ -87,9 +90,18 @@ impl StructField {
                     Versionize::serialize(element, writer, version_map, app_version)?;
                 }
             },
-            syn::Type::Path(_) => quote! {
-                Versionize::serialize(&copy_of_self.#field_ident, writer, version_map, app_version)?;
-            },
+            syn::Type::Path(_) => {
+                if self.packed_struct {
+                    quote! {
+                        let copy = copy_of_self.#field_ident;
+                        Versionize::serialize(&copy, writer, version_map, app_version)?;
+                    }
+                } else {
+                    quote! {
+                        Versionize::serialize(&copy_of_self.#field_ident, writer, version_map, app_version)?;
+                    }
+                }
+            }
             syn::Type::Reference(_) => quote! {
                 copy_of_self.#field_ident.serialize(writer, version_map, app_version)?;
             },
diff --git a/src/lib.rs b/src/lib.rs
index 3bcf6a2..3c2303a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,8 +33,9 @@ mod helpers;
 use common::Descriptor;
 use descriptors::{enum_desc::EnumDescriptor, struct_desc::StructDescriptor};
 use proc_macro::TokenStream;
+use proc_macro2::TokenTree;
 use quote::quote;
-use syn::{parse_macro_input, DeriveInput};
+use syn::{parse::ParseStream, parse_macro_input, DeriveInput};
 
 pub(crate) const ATTRIBUTE_NAME: &str = "version";
 
@@ -215,10 +216,26 @@ pub fn impl_versionize(input: TokenStream) -> proc_macro::TokenStream {
     let ident = input.ident.clone();
     let generics = input.generics.clone();
 
-    let descriptor: Box<dyn Descriptor> = match &input.data {
-        syn::Data::Struct(data_struct) => {
-            Box::new(StructDescriptor::new(&data_struct, ident.clone()))
+    let mut is_packed = false;
+    for attr in &input.attrs {
+        if attr.path.is_ident("repr") {
+            let _ = attr.parse_args_with(|input: ParseStream| {
+                while let Some(token) = input.parse()? {
+                    if let TokenTree::Ident(ident) = token {
+                        is_packed |= ident == "packed";
+                    }
+                }
+                Ok(())
+            });
         }
+    }
+
+    let descriptor: Box<dyn Descriptor> = match &input.data {
+        syn::Data::Struct(data_struct) => Box::new(StructDescriptor::new(
+            &data_struct,
+            ident.clone(),
+            is_packed,
+        )),
         syn::Data::Enum(data_enum) => Box::new(EnumDescriptor::new(&data_enum, ident.clone())),
         syn::Data::Union(_) => {
             return (quote! {