diff --git a/src/editor/js/structures/graph/graph.ts b/src/editor/js/structures/graph/graph.ts
index b8dc963ac3f09a1074d2acc923e393574ccaab57..9553a532fc96fa9e9da6ac17b21ea84c0d7207ca 100644
--- a/src/editor/js/structures/graph/graph.ts
+++ b/src/editor/js/structures/graph/graph.ts
@@ -157,6 +157,36 @@ export class Graph extends ManagedData {
         };
     }
 
+    /**
+     * Adds a pre-created node type to the graph.
+     * @param nodeType New node type object.
+     * @returns True, if successful.
+     */
+    public addNodeType(nodeType: NodeType) {
+        if (this.data.types.includes(nodeType)) {
+            return true; // Already exists in graph.
+        }
+
+        // Update id
+        nodeType.id = this.nextTypeId;
+        this.nextTypeId += 1;
+
+        // Is valid node?
+        if (nodeType.name == undefined) {
+            nodeType.name = "Unnamed";
+        }
+        if (nodeType.color == undefined) {
+            nodeType.color = "#000000";
+        }
+
+        this.data.types.push(node);
+
+        this.triggerOnChange();
+        this.storeCurrentData("Added node [" + nodeType + "]");
+
+        return true;
+    }
+
     /**
      * Adds a pre-created node to the graph.
      * @param node New node object.
@@ -180,21 +210,59 @@ export class Graph extends ManagedData {
                 // Just give first type in list
                 node.type = this.types[0];
             } else {
-                // Give empty type
-                // TODO: Properly add new type, with proper ID. Implemented this.addType(..);
-                node.type = new NodeType(this);
+                const newType = new NodeType(this);
+                newType.add();
+                node.type = newType;
             }
         }
 
         this.data.nodes.push(node);
 
         this.triggerOnChange();
-        // TODO: Use toString implementation of node
         this.storeCurrentData("Added node [" + node + "]");
 
         return true;
     }
 
+    /**
+     * Deletes a node type from the graph. Only works if at least one type remains after deletion.
+     * @param nodeType Node type object to remove.
+     * @returns True, if successful.
+     */
+    public deleteNodeType(nodeType: NodeType): boolean {
+        // Only allow deletion if at least one other type remains
+        if (this.types.length <= 1) {
+            return false;
+        }
+
+        if (!this.data.types.includes(nodeType)) {
+            return true; // Doesn't even exist in graph to begin with.
+        }
+
+        this.data.types = this.data.types.filter((n: NodeType) => !n.equals(nodeType));
+
+        try {
+            // No save points should be created when replacing usages
+            this.disableStoring();
+
+            // Replace all usages of this type with the first one in the list
+            this.nodes.forEach((n: Node) => {
+                if (n.type.equals(nodeType)) {
+                    n.type = this.types[0];
+                }
+            });
+        } finally {
+            this.enableStoring();
+        }
+
+        this.triggerOnChange();
+        this.storeCurrentData(
+            "Deleted type [" + nodeType + "] and replaced usages"
+        );
+
+        return true;
+    }
+
     /**
      * Deletes a node from the graph.
      * @param node Node object to remove.
@@ -220,7 +288,6 @@ export class Graph extends ManagedData {
         }
 
         this.triggerOnChange();
-        // TODO: Use toString implementation of node
         this.storeCurrentData(
             "Deleted node [" + node + "] and all connected links"
         );
@@ -262,7 +329,6 @@ export class Graph extends ManagedData {
         this.data.links.push(link);
 
         this.triggerOnChange();
-        // TODO: Use toString implementation of link
         this.storeCurrentData("Added link [" + link + "]");
 
         return true;
@@ -281,7 +347,6 @@ export class Graph extends ManagedData {
         this.data.links = this.data.links.filter((l: Link) => !l.equals(link));
 
         this.triggerOnChange();
-        // TODO: Use toString implementation of link
         this.storeCurrentData("Deleted link [" + link + "]");
 
         return true;
diff --git a/src/editor/js/structures/graph/nodetype.ts b/src/editor/js/structures/graph/nodetype.ts
index 430ce90672471298be3ef953f04483acd9fb7e3c..78362ea791496c58395bcf23f5d7adc723118043 100644
--- a/src/editor/js/structures/graph/nodetype.ts
+++ b/src/editor/js/structures/graph/nodetype.ts
@@ -13,13 +13,16 @@ export class NodeType extends GraphElement {
     }
 
     public delete(): boolean {
-        // TODO: Implement
-        throw new Error('Function "delete()" has not been implemented.');
+        return this.graph.deleteNodeType(this);
     }
 
     public add(graph: Graph = this.graph): boolean {
-        // TODO: Implement
-        throw new Error('Function "add(graph)" has not been implemented.');
+        this.graph = graph;
+        if (this.graph == undefined) {
+            return false;
+        }
+
+        return this.graph.addNodeType(this);
     }
 
     public getCleanInstance(): any {