diff --git a/psc-package.json b/psc-package.json
index f1037dd01c67c5283de6f39ce37c9a383503806a..ad3d96866eb498c080236ea859c7911c940b7840 100644
--- a/psc-package.json
+++ b/psc-package.json
@@ -27,6 +27,7 @@
     "random",
     "reactix",
     "read",
+    "record-extra",
     "routing",
     "sequences",
     "smolder",
diff --git a/src/Gargantext/Components/Forest/Tree.purs b/src/Gargantext/Components/Forest/Tree.purs
index 820c221783cfb81f1d913027c96ebf6ebb21f0d6..c47aab476c57e08c78cce5f0165b5ced71c25cc8 100644
--- a/src/Gargantext/Components/Forest/Tree.purs
+++ b/src/Gargantext/Components/Forest/Tree.purs
@@ -8,6 +8,11 @@ import Data.Tuple (Tuple(..), fst, snd)
 import Data.Tuple.Nested ((/\))
 import Effect.Aff (Aff)
 import Effect.Class (liftEffect)
+import Reactix as R
+import Reactix.DOM.HTML as H
+import Record as Record
+import Record.Extra as RecordE
+
 import Gargantext.Components.Forest.Tree.Node.Action (Action(..), CreateValue(..), FTree, ID, LNode(..), NTree(..), Reload, RenameValue(..), Tree, createNode, deleteNode, loadNode, renameNode)
 import Gargantext.Components.Forest.Tree.Node.Action.Upload (uploadFile)
 import Gargantext.Components.Forest.Tree.Node.Box (nodeMainSpan)
@@ -17,8 +22,6 @@ import Gargantext.Prelude (Unit, bind, const, discard, map, pure, void, ($), (+)
 import Gargantext.Routes (AppRoute)
 import Gargantext.Sessions (OpenNodes, Session, mkNodeId)
 import Gargantext.Types as GT
-import Reactix as R
-import Reactix.DOM.HTML as H
 
 type CommonProps =
   (
@@ -82,18 +85,19 @@ type ToHtmlProps =
   )
 
 toHtml :: Record ToHtmlProps -> R.Element
-toHtml { frontends
-       , mCurrentRoute
-       , openNodes
-       , reload: reload@(_ /\ setReload)
-       , session
-       , tasks: tasks@(asyncTasks /\ setAsyncTasks)
-       , tree: tree@(NTree (LNode {id, name, nodeType}) ary) } = R.createElement el {} []
+toHtml p@{ frontends
+         , mCurrentRoute
+         , openNodes
+         , reload: reload@(_ /\ setReload)
+         , session
+         , tasks: tasks@(asyncTasks /\ setAsyncTasks)
+         , tree: tree@(NTree (LNode {id, name, nodeType}) ary) } = R.createElement el {} []
   where
     el = R.hooksComponent "NodeView" cpt
-    pAction = performAction {openNodes, reload, session, tasks, tree}
+    commonProps = RecordE.pick p :: Record CommonProps
+    pAction = performAction (RecordE.pick p :: Record PerformActionProps)
 
-    cpt props _ = do
+    cpt _ _ = do
       let nodeId = mkNodeId session id
       let folderIsOpen = Set.member nodeId (fst openNodes)
       let setFn = if folderIsOpen then Set.delete else Set.insert
@@ -115,7 +119,9 @@ toHtml { frontends
                            , onAsyncTaskFinish
                            , session
                            } ]
-            <> childNodes {children: ary, folderOpen, frontends, mCurrentRoute, openNodes, reload, session }
+            <> childNodes (Record.merge commonProps
+                                        { children: ary
+                                        , folderOpen })
           )
         ]
 
@@ -137,9 +143,10 @@ type ChildNodesProps =
 childNodes :: Record ChildNodesProps -> Array R.Element
 childNodes { children: [] } = []
 childNodes { folderOpen: (false /\ _) } = []
-childNodes { children, folderOpen: (true /\ _), frontends, mCurrentRoute, openNodes, reload, session } =
+childNodes props@{ children } =
   map (\ctree -> childNode {tree: ctree, asyncTasks: []}) $ sorted children
     where
+      commonProps = RecordE.pick props :: Record CommonProps
       sorted :: Array FTree -> Array FTree
       sorted = A.sortWith (\(NTree (LNode {id}) _) -> id)
       childNode :: Tree -> R.Element
@@ -147,13 +154,18 @@ childNodes { children, folderOpen: (true /\ _), frontends, mCurrentRoute, openNo
       el = R.hooksComponent "ChildNodeView" cpt
       cpt {tree, asyncTasks} _ = do
         tasks <- R.useState' asyncTasks
-        pure $ toHtml { frontends, mCurrentRoute, openNodes, reload, session, tasks, tree }
+        pure $ toHtml (Record.merge commonProps
+                                    { tasks, tree })
+
+type PerformActionProps =
+  ( openNodes :: R.State OpenNodes
+  , reload :: R.State Reload
+  , session :: Session
+  , tasks :: R.State (Array GT.AsyncTaskWithType)
+  , tree :: FTree
+  )
 
-performAction :: { openNodes :: R.State OpenNodes
-                 , reload :: R.State Reload
-                 , session :: Session
-                 , tasks :: R.State (Array GT.AsyncTaskWithType)
-                 , tree :: FTree }
+performAction :: Record PerformActionProps
               -> Action
               -> Aff Unit
 performAction { openNodes: (_ /\ setOpenNodes)
diff --git a/src/Gargantext/Components/Forest/Tree/Node/Box.purs b/src/Gargantext/Components/Forest/Tree/Node/Box.purs
index e02700807785de6283f92dd3760d7e43b7c591df..090f6997a629fdd281026955e45a6dfbaf60f0c4 100644
--- a/src/Gargantext/Components/Forest/Tree/Node/Box.purs
+++ b/src/Gargantext/Components/Forest/Tree/Node/Box.purs
@@ -110,7 +110,7 @@ nodeMainSpan p@{ dispatch, folderOpen, frontends, session } = R.createElement el
     popOverIcon =
       H.a { className: "settings fa fa-cog" } []
 
-    mNodePopupView props@{asyncTasks, id, nodeType} onPopoverClose =
+    mNodePopupView props@{id, nodeType} onPopoverClose =
       nodePopupView { id
                     , dispatch
                     , name: name' props
diff --git a/src/Gargantext/Components/GraphExplorer.purs b/src/Gargantext/Components/GraphExplorer.purs
index 1955a8f103fc816d55e20c14086b0feba938a6aa..ad5299cdedf7cbbd9ebba0e61248ace587c300d5 100644
--- a/src/Gargantext/Components/GraphExplorer.purs
+++ b/src/Gargantext/Components/GraphExplorer.purs
@@ -34,12 +34,13 @@ import Math (log)
 import Partial.Unsafe (unsafePartial)
 import Reactix as R
 import Reactix.DOM.HTML as RH
+import Record as Record
 
 type GraphId = Int
 
 type LayoutProps =
-  ( graphId :: GraphId
-  , frontends :: Frontends
+  ( frontends :: Frontends
+  , graphId :: GraphId
   , mCurrentRoute :: AppRoute
   , session :: Session
   , sessions :: Sessions
@@ -69,19 +70,11 @@ explorerLayoutView :: R.State Int -> Record LayoutProps -> R.Element
 explorerLayoutView graphVersion p = R.createElement el p []
   where
     el = R.hooksComponent "G.C.GE.explorerLayoutView" cpt
-    cpt {frontends, graphId, mCurrentRoute, session, sessions, showLogin } _ = do
+    cpt props@{graphId, session} _ = do
       useLoader graphId (getNodes session graphVersion) handler
       where
         handler loaded =
-          explorer { frontends
-                   , graph
-                   , graphId
-                   , graphVersion
-                   , mCurrentRoute
-                   , mMetaData
-                   , session
-                   , sessions
-                   , showLogin }
+          explorer (Record.merge props { graph, graphVersion, mMetaData })
           where (Tuple mMetaData graph) = convert loaded
 
 --------------------------------------------------------------
@@ -91,7 +84,7 @@ explorer props = R.createElement explorerCpt props []
 explorerCpt :: R.Component Props
 explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
   where
-    cpt {frontends, graph, graphId, graphVersion, mCurrentRoute, mMetaData, session, sessions, showLogin } _ = do
+    cpt props@{frontends, graph, graphId, graphVersion, mCurrentRoute, mMetaData, session, sessions, showLogin } _ = do
       dataRef <- R.useRef graph
       graphRef <- R.useRef null
       graphVersionRef <- R.useRef (fst graphVersion)
@@ -169,25 +162,21 @@ explorerCpt = R.hooksComponent "G.C.GraphExplorer.explorer" cpt
       RH.div {className: "col-md-2 graph-tree"} [forest {sessions, route, frontends, showLogin }]
 
     mSidebar :: Maybe GET.MetaData
-             -> { frontends :: Frontends
-                , graph :: SigmaxT.SGraph
-                , graphVersion :: R.State Int
-                , removedNodeIds :: R.State SigmaxT.NodeIds
-                , showSidePanel :: GET.SidePanelState
-                , selectedNodeIds :: R.State SigmaxT.NodeIds
-                , session :: Session }
+             -> Record MSidebarProps
              -> R.Element
     mSidebar Nothing _ = RH.div {} []
-    mSidebar (Just metaData) {frontends, graph, graphVersion, removedNodeIds, session, selectedNodeIds, showSidePanel} =
-      Sidebar.sidebar { frontends
-                      , graph
-                      , graphVersion
-                      , metaData
-                      , removedNodeIds
-                      , session
-                      , selectedNodeIds
-                      , showSidePanel
-                      }
+    mSidebar (Just metaData) props =
+      Sidebar.sidebar (Record.merge props { metaData })
+
+type MSidebarProps =
+  ( frontends :: Frontends
+  , graph :: SigmaxT.SGraph
+  , graphVersion :: R.State Int
+  , removedNodeIds :: R.State SigmaxT.NodeIds
+  , showSidePanel :: GET.SidePanelState
+  , selectedNodeIds :: R.State SigmaxT.NodeIds
+  , session :: Session
+  )
 
 type GraphProps = (
     controls :: Record Controls.Controls
@@ -255,18 +244,20 @@ convert (GET.GraphData r) = Tuple r.metaData $ SigmaxT.Graph {nodes, edges}
         gargType =  unsafePartial $ fromJust $ Types.modeFromString n.type_
     nodesMap = SigmaxT.nodesMap nodes
     edges = foldMapWithIndex edgeFn $ A.sortWith (\(GET.Edge {weight}) -> weight) r.edges
-    edgeFn i (GET.Edge e) = Seq.singleton { id : e.id_
-                                          , color
-                                          , confluence : e.confluence
-                                          , hidden : false
-                                          , size: 1.0
-                                          , source : e.source
-                                          , sourceNode
-                                          , target : e.target
-                                          , targetNode
-                                          , weight : e.weight
-                                          , weightIdx: i
-                                          }
+    edgeFn i (GET.Edge e) =
+      Seq.singleton
+        { id : e.id_
+        , color
+        , confluence : e.confluence
+        , hidden : false
+        , size: 1.0
+        , source : e.source
+        , sourceNode
+        , target : e.target
+        , targetNode
+        , weight : e.weight
+        , weightIdx: i
+        }
       where
         sourceNode = unsafePartial $ fromJust $ Map.lookup e.source nodesMap
         targetNode = unsafePartial $ fromJust $ Map.lookup e.target nodesMap