diff --git a/src/libRender/RadiumNBR/NodeGraph/Node.cpp b/src/libRender/RadiumNBR/NodeGraph/Node.cpp
index 1a5787cee473a5f90614760acf43847e5bb570f7..780853fb2d82ca7817f872d839a4cf6ac72a5158 100644
--- a/src/libRender/RadiumNBR/NodeGraph/Node.cpp
+++ b/src/libRender/RadiumNBR/NodeGraph/Node.cpp
@@ -33,7 +33,16 @@ std::string Node::getUuid() const {
     return struuid;
 }
 
-
+bool Node::setUuid(const std::string& uid) {
+    if ( m_uuid.is_nil() ) {
+        auto id = uuids::uuid::from_string(uid);
+        if ( id ) {
+            m_uuid = id.value();
+            return true;
+        }
+    }
+    return false;
+}
 
 Node::Node( const std::string& instanceName, const std::string& typeName ) :
     m_typeName{ typeName }, m_instanceName{ instanceName } {}
diff --git a/src/libRender/RadiumNBR/NodeGraph/Node.hpp b/src/libRender/RadiumNBR/NodeGraph/Node.hpp
index b2cd52f26b7b6a259af4a973761ad4d09671f820..2dfe18d787ce63fc5f8380d81cec7c9fd7287aa7 100644
--- a/src/libRender/RadiumNBR/NodeGraph/Node.hpp
+++ b/src/libRender/RadiumNBR/NodeGraph/Node.hpp
@@ -118,6 +118,10 @@ class NodeBasedRenderer_LIBRARY_API Node
     /// Gets the UUID of the node as a string
     std::string getUuid() const;
 
+    /// Sets the UUID of the node from a valid string string
+    /// @return true if the uuid is set, false if the node already have a valid uid
+    bool setUuid(const std::string& uid);
+
     /// return the deletable status of the node
     /// Default is true. If a node must not be deleted (e.g. RenderObjectSource Node in the rendergraph), override this method.
     bool isDeletable() { return m_isDeletable;}
diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp
index 2bbd6570e4d1633fd749451bfc8ed355e22c93d9..84706e514102db668e233e9e9f5241b7c9961034 100644
--- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp
+++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp
@@ -115,13 +115,25 @@ void RenderGraph::loadFromJson( const std::string& jsonFilePath ) {
         std::string name = n["model"]["name"];
         std::string id   = n["id"];
         if ( name == "RenderObjects" )
-        { nodeById.emplace( id, getDataNode<NodeTypeRenderObject>() ); }
+        {
+            getDataNode<NodeTypeRenderObject>()->fromJson( n );
+            nodeById.emplace( id, getDataNode<NodeTypeRenderObject>() );
+        }
         else if ( name == "Cameras" )
-        { nodeById.emplace( id, getDataNode<NodeTypeCamera>() ); }
+        {
+            getDataNode<NodeTypeCamera>()->fromJson( n );
+            nodeById.emplace( id, getDataNode<NodeTypeCamera>() );
+        }
         else if ( name == "Lights" )
-        { nodeById.emplace( id, getDataNode<NodeTypeLight>() ); }
+        {
+            getDataNode<NodeTypeLight>()->fromJson( n );
+            nodeById.emplace( id, getDataNode<NodeTypeLight>() );
+        }
         else if ( name == "Display Sink" )
-        { nodeById.emplace( id, getDisplayNode() ); }
+        {
+            getDisplayNode()->fromJson( n );
+            nodeById.emplace( id, getDisplayNode() );
+        }
         else
         {
             auto newNode = NodeFactory::createNode( name, n );
@@ -196,6 +208,43 @@ void RenderGraph::loadFromJson( const std::string& jsonFilePath ) {
                       << std::endl;
         }
     }
+
+}
+
+void RenderGraph::saveToJson( const std::string& jsonFilePath ) {
+    nlohmann::json nodes = nlohmann::json::array();
+    nlohmann::json connections = nlohmann::json::array();
+    for(const auto&n : m_nodes) {
+        nlohmann::json nodeData;
+        n->toJson(nodeData);
+        nodes.push_back(nodeData);
+        int numPort=0;
+        for( const auto & input : n->getInputs() ) {
+            if( input->isLinked() ) {
+                nlohmann::json link = nlohmann::json::object();
+                link["in_id"] = n->getUuid();
+                link["in_index"] = numPort;
+                auto portOut = input->getLink();
+                auto nodeOut = portOut->getNode();
+                int outPortIndex = 0;
+                for( const auto& p : nodeOut->getOutputs() ) {
+                    if ( p.get() == portOut ) {
+                        break;
+                    }
+                    outPortIndex++;
+                }
+                link["out_id"] = nodeOut->getUuid();
+                link["out_index"] = outPortIndex;
+                connections.push_back( link );
+            }
+            numPort++;
+        }
+    }
+    nlohmann::json graphJson;
+    graphJson["nodes"] = nodes;
+    graphJson["connections"] = connections;
+    std::ofstream file(jsonFilePath);
+    file << std::setw(4) << graphJson << std::endl;
 }
 
 bool RenderGraph::addNode( Node* newNode ) {
diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp
index 0a415fa8cca7b455a85733edcfab3e8b9d8352f7..bb2d764c1573fbe0ca95b078664db68a062fffec 100644
--- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp
+++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.hpp
@@ -39,6 +39,10 @@ class NodeBasedRenderer_LIBRARY_API RenderGraph : public Node
     /// @param jsonFilePath The path to the JSON file.
     void loadFromJson( const std::string& jsonFilePath );
 
+    /// Saves nodes and links to a JSON file.
+    /// @param jsonFilePath The path to the JSON file.
+    void saveToJson( const std::string& jsonFilePath );
+
     /// Adds a node to the render graph.
     /// @param newNode The node to add to the render graph.
     bool addNode( Node* newNode );