diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9dbd5eb160ea98fae6e971a21a66c0380681416..2e417cd8f361cce276997326194f615a855a0882 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -95,6 +95,7 @@ SET(${PROJECT_NAME}_HEADERS
   include/hpp/manipulation/steering-method/fwd.hh
   include/hpp/manipulation/steering-method/graph.hh
   include/hpp/manipulation/steering-method/end-effector-trajectory.hh
+  include/hpp/manipulation/serialization.hh
   )
 
 SET(${PROJECT_NAME}_SOURCES
diff --git a/include/hpp/manipulation/constraint-set.hh b/include/hpp/manipulation/constraint-set.hh
index 4a080cb56e0fa52aa6ee12759667f6c8bfd19cab..baced7df334912faa075209b9b589b0055c6b3fb 100644
--- a/include/hpp/manipulation/constraint-set.hh
+++ b/include/hpp/manipulation/constraint-set.hh
@@ -62,6 +62,9 @@ namespace hpp {
     private:
       graph::EdgePtr_t edge_;
       ConstraintSetWkPtr_t weak_;
+
+      ConstraintSet() {}
+      HPP_SERIALIZABLE();
     }; // class ConstraintSet
 
     struct ConstraintAndComplement_t {
diff --git a/include/hpp/manipulation/serialization.hh b/include/hpp/manipulation/serialization.hh
new file mode 100644
index 0000000000000000000000000000000000000000..722ad2364cbead984d9e661b99a7cf7b8f979902
--- /dev/null
+++ b/include/hpp/manipulation/serialization.hh
@@ -0,0 +1,59 @@
+//
+// Copyright (c) 2020 CNRS
+// Author: Joseph Mirabel
+//
+// This file is part of hpp-manipulation
+// hpp-manipulation is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation, either version
+// 3 of the License, or (at your option) any later version.
+//
+// hpp-manipulation is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Lesser Public License for more details.  You should have
+// received a copy of the GNU Lesser General Public License along with
+// hpp-manipulation  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef HPP_MANIPULATION_SERIALIZATION_HH
+# define HPP_MANIPULATION_SERIALIZATION_HH
+
+# include <boost/serialization/split_free.hpp>
+# include <boost/serialization/shared_ptr.hpp>
+# include <boost/serialization/weak_ptr.hpp>
+
+# include <hpp/manipulation/fwd.hh>
+
+namespace hpp {
+namespace serialization {
+struct archive_graph_wrapper {
+  manipulation::graph::GraphPtr_t graph;
+  virtual ~archive_graph_wrapper() {}
+};
+} // namespace manipulation
+} // namespace hpp
+
+namespace boost {
+namespace serialization {
+template<class Archive>
+inline void serialize(Archive & ar, hpp::manipulation::graph::EdgePtr_t& e, const unsigned int /*version*/)
+{
+  using hpp::serialization::archive_graph_wrapper;
+  using namespace hpp::manipulation::graph;
+
+  std::size_t id;
+  if (Archive::is_saving::value) id = e->id();
+  ar & BOOST_SERIALIZATION_NVP(id);
+  if (!Archive::is_saving::value) {
+    archive_graph_wrapper* agw = dynamic_cast<archive_graph_wrapper*>(&ar);
+    if (agw == NULL)
+      throw std::runtime_error("Cannot deserialize edges with a archive_graph_wrapper");
+    GraphComponentPtr_t gc = agw->graph->get(id).lock();
+    e = HPP_DYNAMIC_PTR_CAST(Edge, gc);
+  }
+}
+} // namespace serialization
+} // namespace boost
+
+#endif // HPP_MANIPULATION_SERIALIZATION_HH
diff --git a/src/constraint-set.cc b/src/constraint-set.cc
index 46f96c798c92aa0734d981e46e47df6f9c027f51..472093f7a6dfc2a2b822b90c70966fed24139ce3 100644
--- a/src/constraint-set.cc
+++ b/src/constraint-set.cc
@@ -16,8 +16,11 @@
 
 #include "hpp/manipulation/constraint-set.hh"
 
+#include <hpp/util/serialization.hh>
+
 #include "hpp/manipulation/device.hh"
 #include "hpp/manipulation/graph/edge.hh"
+#include "hpp/manipulation/serialization.hh"
 
 namespace hpp {
   namespace manipulation {
@@ -75,5 +78,17 @@ namespace hpp {
       if (edge_) os << iendl << "Built by edge " << edge_->name();
       return os;
     }
+
+    template<class Archive>
+    void ConstraintSet::serialize(Archive & ar, const unsigned int version)
+    {
+      using namespace boost::serialization;
+      (void) version;
+      ar & make_nvp("base", base_object<core::ConstraintSet>(*this));
+      ar & BOOST_SERIALIZATION_NVP(edge_);
+      ar & BOOST_SERIALIZATION_NVP(weak_);
+    }
+
+    HPP_SERIALIZATION_IMPLEMENT(ConstraintSet);
   } // namespace manipulation
 } // namespace hpp