diff --git a/src/editor/js/editor.js b/src/editor/js/editor.ts
similarity index 87%
rename from src/editor/js/editor.js
rename to src/editor/js/editor.ts
index c45f59c2d835642f4606aed087da4aec7c019fe0..7ab52e0298cfca52ea80ac380df9888a2455a10f 100644
--- a/src/editor/js/editor.js
+++ b/src/editor/js/editor.ts
@@ -1,13 +1,13 @@
 import { State } from "./state";
-import * as Graph from "./graph";
 import { loadGraphJson } from "../../datasets";
 import ForceGraph from "force-graph";
 import * as Interactions from "./interactions";
 import { setSpace, SPACE } from "../../config";
+import { Graph } from "./structures/graph/graph";
 
-export var state = undefined;
-export var graph = undefined;
-export var renderer;
+export let state: any = undefined;
+export let graph: Graph = undefined;
+export let renderer: any;
 
 window.onload = function () {
     // Only execute, if corresponding dom is present
@@ -23,7 +23,7 @@ window.onload = function () {
     loadSpace(SPACE);
 };
 
-export function loadSpace(spaceId) {
+export function loadSpace(spaceId: string) {
     if (state !== undefined && spaceId === SPACE) {
         return;
     }
@@ -31,14 +31,14 @@ export function loadSpace(spaceId) {
 
     return loadGraphJson(SPACE).then((graphConfig) => {
         state = new State();
-        graph = new Graph.Graph(graphConfig);
+        graph = Graph.parse(graphConfig);
         load();
 
-        graph.restartSimulation();
+        // graph.restartSimulation();
     });
 }
 
-function extractPositions(event) {
+function extractPositions(event: any) {
     return {
         graph: renderer.screen2GraphCoords(event.layerX, event.layerY),
         window: { x: event.clientX, y: event.clientY },
@@ -53,7 +53,7 @@ function load() {
         .height(600)
         .width(width)
         .graphData(graph.data)
-        .nodeLabel(Graph.NODE_LABEL)
+        .nodeLabel("label")
         .linkColor((link) => state.linkColor(link))
         .nodeColor((node) => state.nodeColor(node))
         .onNodeClick((node) => state.onNodeClick(node))
diff --git a/src/editor/js/structures/graph/graph.ts b/src/editor/js/structures/graph/graph.ts
index 7a68061bdccaf99ca5117ce5ce9b07fc72046e80..b7a5ea851829c23e1186ea0df8836027758aa21d 100644
--- a/src/editor/js/structures/graph/graph.ts
+++ b/src/editor/js/structures/graph/graph.ts
@@ -24,9 +24,23 @@ export class Graph extends ManagedData {
         super(data);
         this.onChangeCallbacks = [];
 
+        this.connectElementsToGraph();
         this.prepareIds(data);
     }
 
+    /**
+     * Sets the correct graph object for all the graph elements in data.
+     */
+    connectElementsToGraph() {
+        this.data.nodes.forEach((n) => (n.graph = this));
+        this.data.links.forEach((l) => {
+            l.graph = this;
+            l.source = this.getNode(l.sourceId);
+            l.target = this.getNode(l.targetId);
+        });
+        this.data.types.forEach((t) => (t.graph = this));
+    }
+
     /**
      * Intuitive getter for links.
      * @returns All links associated with the graph.
@@ -105,7 +119,11 @@ export class Graph extends ManagedData {
     }
 
     protected storableData(data: GraphData): any {
-        let clean: GraphData;
+        const clean: GraphData = {
+            nodes: [],
+            links: [],
+            types: []
+        };
 
         clean.links = data.links.map((link) => link.getCleanInstance());
         clean.nodes = data.nodes.map((node) => node.getCleanInstance());
@@ -186,6 +204,10 @@ export class Graph extends ManagedData {
         return true;
     }
 
+    getNode(id: number): Node {
+        return this.nodes.find((n) => n.id === id);
+    }
+
     /**
      * Adds a pre-created link to the graph.
      * @param link New link object.
@@ -227,4 +249,52 @@ export class Graph extends ManagedData {
 
         return true;
     }
+
+    public static parse(raw: any): Graph {
+        const data: GraphData = {
+            nodes: [],
+            links: [],
+            types: []
+        };
+
+        // Parse nodes
+        if (raw.nodes === undefined) {
+            throw new Error(
+                "Invalid graph data format. Could not find any nodes."
+            );
+        }
+        raw.nodes.forEach((rawNode: any) => {
+            data.nodes.push(Node.parse(rawNode));
+        });
+
+        // Parse links
+        if (raw.links === undefined) {
+            throw new Error(
+                "Invalid graph data format. Could not find any links."
+            );
+        }
+        raw.links.forEach((rawLink: any) => {
+            data.links.push(Link.parse(rawLink));
+            // No need to replace node ids with proper node objects, since that should be done in the graph itself. Only have to prepare valid GraphData
+        });
+
+        // Collect all node types
+        // TODO: Remove, when types are directly parsed and not just implicit
+        data.nodes.forEach((node) => {
+            const sharedType: NodeType = data.types.find(
+                // TODO: Use id instead, but not defined at the moment
+                (type) => type.name === node.type.name
+            );
+
+            if (sharedType !== undefined) {
+                node.type = sharedType; // Assign it the stored type, to make sure that it has the same reference as every other node to this type
+                return;
+            }
+
+            // Doesn't exist in list yet, so add
+            data.types.push(node.type);
+        });
+
+        return new Graph(data);
+    }
 }
diff --git a/src/editor/js/structures/graph/graphelement.ts b/src/editor/js/structures/graph/graphelement.ts
index 4072b75849f837100bd527fa1d51f1d18ea15ecb..85d0c20c1dbc0bba86444f000f226425318b0b1c 100644
--- a/src/editor/js/structures/graph/graphelement.ts
+++ b/src/editor/js/structures/graph/graphelement.ts
@@ -5,9 +5,9 @@ export class GraphElement extends SerializableItem {
     protected isNode: boolean;
     protected isLink: boolean;
 
-    protected graph: Graph;
+    public graph: Graph;
 
-    constructor(graph: Graph) {
+    constructor(graph: Graph = undefined) {
         super();
         this.graph = graph;
         this.isNode = false;
diff --git a/src/editor/js/structures/graph/link.ts b/src/editor/js/structures/graph/link.ts
index bdfd33e4df1fa14cfaab93f6dc1d114948a59554..b0eac9ba382f85b36c0fc1588c0fae26ab6505b3 100644
--- a/src/editor/js/structures/graph/link.ts
+++ b/src/editor/js/structures/graph/link.ts
@@ -1,7 +1,7 @@
-import {GraphElement} from "./graphelement";
-import {Graph} from "./graph";
-import {Node} from "./node";
-import {GLOBAL_PARAMS} from "../helper/serializableitem";
+import { GraphElement } from "./graphelement";
+import { Graph } from "./graph";
+import { Node } from "./node";
+import { GLOBAL_PARAMS } from "../helper/serializableitem";
 
 const LINK_PARAMS = ["source", "target", ...GLOBAL_PARAMS];
 const LINK_SIM_PARAMS = ["index"];
@@ -10,17 +10,66 @@ export class Link extends GraphElement {
     public source: Node;
     public target: Node;
 
-    constructor(graph: Graph) {
+    private _sourceId: number;
+    private _targetId: number;
+
+    constructor(graph: Graph = undefined) {
         super(graph);
         this.isLink = true;
     }
 
+    /**
+     * Id of the source node.
+     * @returns Source id.
+     */
+    public get sourceId(): number {
+        if (this.source == undefined) {
+            return this._sourceId;
+        }
+
+        return this.source.id;
+    }
+
+    /**
+     * Removes stored node object and just saves the id instead.
+     * @param value New source id value.
+     */
+    public set sourceId(value: number) {
+        this._sourceId = value;
+        this.source = undefined;
+    }
+
+    /**
+     * Id of the target node.
+     * @returns Target id.
+     */
+    public get targetId(): number {
+        if (this.target == undefined) {
+            return this._targetId;
+        }
+
+        return this.target.id;
+    }
+
+    /**
+     * Removes stored node object and just saves the id instead.
+     * @param value New target id value.
+     */
+    public set targetId(value: number) {
+        this._targetId = value;
+        this.target = undefined;
+    }
+
     public delete() {
         return this.graph.deleteLink(this);
     }
 
     public add(graph: Graph = this.graph) {
         this.graph = graph;
+        if (this.graph == undefined) {
+            return false;
+        }
+
         return this.graph.addLink(this);
     }
 
@@ -40,7 +89,16 @@ export class Link extends GraphElement {
     public getCleanInstance(): any {
         return {
             ...this.serialize(),
-            ...this.serializeProperties(LINK_SIM_PARAMS)
+            ...this.serializeProperties(LINK_SIM_PARAMS),
         };
     }
-}
\ No newline at end of file
+
+    public static parse(raw: any): Link {
+        const link: Link = new Link();
+
+        link.sourceId = Number(raw.source);
+        link.targetId = Number(raw.target);
+
+        return link;
+    }
+}
diff --git a/src/editor/js/structures/graph/node.ts b/src/editor/js/structures/graph/node.ts
index 59761376be08e7be90d0099716bd1dad67dd0e03..42db8a1f49716bd2d82d632b9e98b11b9a91b6ce 100644
--- a/src/editor/js/structures/graph/node.ts
+++ b/src/editor/js/structures/graph/node.ts
@@ -1,9 +1,9 @@
-import {Graph} from "./graph";
-import {GraphElement} from "./graphelement"
-import {NodeType} from "./nodetype";
-import {SerializedURL} from "../helper/serializedurl";
-import {Link} from "./link";
-import {GLOBAL_PARAMS} from "../helper/serializableitem";
+import { Graph } from "./graph";
+import { GraphElement } from "./graphelement";
+import { NodeType } from "./nodetype";
+import { SerializedURL } from "../helper/serializedurl";
+import { Link } from "./link";
+import { GLOBAL_PARAMS } from "../helper/serializableitem";
 
 const NODE_PARAMS = [
     "label",
@@ -13,7 +13,7 @@ const NODE_PARAMS = [
     "video",
     "type",
     "banner",
-    ...GLOBAL_PARAMS
+    ...GLOBAL_PARAMS,
 ];
 const NODE_SIM_PARAMS = ["index", "x", "y", "vx", "vy", "fx", "fy"]; // Based on https://github.com/d3/d3-force#simulation_nodes
 
@@ -26,7 +26,7 @@ export class Node extends GraphElement {
     public video: SerializedURL;
     public references: SerializedURL[];
 
-    constructor(graph: Graph) {
+    constructor(graph: Graph = undefined) {
         super(graph);
         this.isNode = true;
     }
@@ -37,6 +37,10 @@ export class Node extends GraphElement {
 
     public add(graph: Graph = this.graph) {
         this.graph = graph;
+        if (this.graph == undefined) {
+            return false;
+        }
+
         return this.graph.addNode(this);
     }
 
@@ -83,7 +87,18 @@ export class Node extends GraphElement {
     public getCleanInstance(): any {
         return {
             ...this.serialize(),
-            ...this.serializeProperties(NODE_SIM_PARAMS)
+            ...this.serializeProperties(NODE_SIM_PARAMS),
         };
     }
-}
\ No newline at end of file
+
+    public static parse(raw: any): Node {
+        const node: Node = new Node();
+
+        node.id = raw.id;
+        node.label = raw.name;
+        node.description = raw.description;
+        node.type = NodeType.parse(raw.type);
+
+        return node;
+    }
+}
diff --git a/src/editor/js/structures/graph/nodetype.ts b/src/editor/js/structures/graph/nodetype.ts
index d2c56b48749ed8c51cbe5df89c542d861001aa1f..2e7d958174173d8295586d90382e7e02e0207f0d 100644
--- a/src/editor/js/structures/graph/nodetype.ts
+++ b/src/editor/js/structures/graph/nodetype.ts
@@ -1,4 +1,4 @@
-import {GLOBAL_PARAMS, SerializableItem} from "../helper/serializableitem";
+import { GLOBAL_PARAMS, SerializableItem } from "../helper/serializableitem";
 import { Graph } from "./graph";
 import { GraphElement } from "./graphelement";
 
@@ -14,15 +14,24 @@ export class NodeType extends GraphElement {
 
     public delete(): boolean {
         // TODO: Implement
-        throw new Error("Function \"delete()\" has not been implemented.");
+        throw new Error('Function "delete()" has not been implemented.');
     }
 
     public add(graph: Graph = this.graph): boolean {
         // TODO: Implement
-        throw new Error("Function \"add(graph)\" has not been implemented.");
+        throw new Error('Function "add(graph)" has not been implemented.');
     }
 
     public getCleanInstance(): any {
         return this.serialize();
     }
-}
\ No newline at end of file
+
+    public static parse(raw: any): NodeType {
+        const type: NodeType = new NodeType();
+
+        type.name = raw;
+        type.color = "#ff0000"
+
+        return type;
+    }
+}
diff --git a/src/editor/js/structures/helper/serializableitem.ts b/src/editor/js/structures/helper/serializableitem.ts
index 793400acc00c85586a9e4c81484336ac40600c01..a5e2313bd98b4128b006203d34cd58c74e323f50 100644
--- a/src/editor/js/structures/helper/serializableitem.ts
+++ b/src/editor/js/structures/helper/serializableitem.ts
@@ -19,8 +19,9 @@ export class SerializableItem {
     /**
      * Creates the current object based on raw, serialized data.
      * @param raw The serialized data.
+     * @returns Parsed data in final form. Could be the finalisd object.
      */
-    public parse(raw: any) {
+    public static parse(raw: any): any {
         throw new Error("Method 'parse()' must be implemented.");
     }