diff --git a/src/features/ePocFlow/ePocFlow.vue b/src/features/ePocFlow/ePocFlow.vue
index cd44068116400860068cb36271c3b70b23864a92..bea8182b5eca5410ec985e2f3ed5e2143c94ddb3 100644
--- a/src/features/ePocFlow/ePocFlow.vue
+++ b/src/features/ePocFlow/ePocFlow.vue
@@ -15,6 +15,7 @@ const { vueFlowRef, project, updateEdge, edges, nodes, findNode }  = useVueFlow(
 
 const editorStore = useEditorStore();
 const graphStore = useGraphStore();
+const undoRedoStore = useUndoRedoStore();
 
 const nodeTypes = {
     activity: markRaw(ActivityNode),
@@ -173,6 +174,10 @@ function nodeDrag(event) {
         @edgeclick="onEdgeclick"
         @pane-click="editorStore.closeFormPanel()"
         @connect="connect"
+        @node-drag-start="nodeDragStart"
+        @node-drag-stop="nodeDragStop"
+        @keydown.meta.z="undo"
+        @keydown.meta.y="redo"
     >
         <template #node-custom="{ id, data }">
             <PageNode :id="id" :data="data" />
diff --git a/src/shared/interfaces/index.ts b/src/shared/interfaces/index.ts
index 0ae5d48d5c6ad87d56612c0163be9d930277ad39..3e9e3cb65cc1e6d4d3255108ab4dc483022ec1e7 100644
--- a/src/shared/interfaces/index.ts
+++ b/src/shared/interfaces/index.ts
@@ -5,4 +5,5 @@ export * from './form.interface';
 export * from './nodeElement.interface';
 export * from './formButton.interface';
 export * from './field.interface';
-export * from './pageModel.interface';
\ No newline at end of file
+export * from './pageModel.interface';
+export * from './undoRedo.interface';
\ No newline at end of file
diff --git a/src/shared/interfaces/undoRedo.interface.ts b/src/shared/interfaces/undoRedo.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b35f079f771dd41f8eaeca3da61bcc0d0f73e8c3
--- /dev/null
+++ b/src/shared/interfaces/undoRedo.interface.ts
@@ -0,0 +1,43 @@
+export interface UndoRedoAction {
+    type: string;
+}
+
+export interface NodeMovedAction extends UndoRedoAction {
+    type: 'nodeMoved';
+    nodeId: string;
+    deltaMovement: { x: number; y: number };
+}
+
+//? Is saving an entire node in this situation a good idea?
+export interface NodeAddedAction extends UndoRedoAction {
+    type: 'nodeAdded';
+    //TODO: use the type defined by vue flow
+    node: any;
+    position: { x: number; y: number };
+}
+
+export interface NodeRemovedAction extends UndoRedoAction {
+    type: 'nodeRemoved';
+    node: any;
+    position: { x: number; y: number }
+}
+
+export interface NodeUpdatedAction extends UndoRedoAction {
+    type: 'nodeUpdated';
+    node: any;
+}
+
+export interface EdgeConnectedAction extends UndoRedoAction {
+    type: 'edgeConnected';
+    edge: any;
+}
+
+export interface EdgeUpdatedAction extends UndoRedoAction {
+    type: 'edgeUpdated';
+    edge: any;
+}
+
+export interface EdgeRemovedAction extends UndoRedoAction {
+    type: 'edgeRemoved';
+    edge: any;
+}
\ No newline at end of file
diff --git a/src/shared/stores/undoRedoStore.ts b/src/shared/stores/undoRedoStore.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c364b87e8c657ced8ef67dedfbf117004a8d6472
--- /dev/null
+++ b/src/shared/stores/undoRedoStore.ts
@@ -0,0 +1,94 @@
+import { defineStore } from 'pinia';
+import { UndoRedoAction, NodeMovedAction } from '../interfaces';
+import { useVueFlow } from '@vue-flow/core';
+
+const { findNode } = useVueFlow({ id: 'main' });
+
+interface UndoRedoState {
+    undoStack: UndoRedoAction[];
+    redoStack: UndoRedoAction[];
+}
+
+export const useUndoRedoStore = defineStore('epoc', {
+    state: (): UndoRedoState => ({
+        undoStack: [],
+        redoStack: [],
+    }),
+
+    actions: {
+        undo(): void {
+            if(this.undoStack.length === 0) return;
+
+            const action = this.undoStack.pop();
+            this.executeAction(action, this.redoStack);
+        },
+        redo(): void {
+            if(this.redoStack.length === 0) return;
+
+            const action = this.redoStack.pop();
+            this.executeAction(action, this.undoStack);
+        },
+        addAction(action: UndoRedoAction): void {
+            this.undoStack.push(action);
+            this.redoStack = [];
+        },
+        executeAction(action: UndoRedoAction, reverseStack: UndoRedoAction[]): void {
+            switch(action.type) {
+            case 'nodeMoved':
+                this.moveNode(action, reverseStack);
+                break;
+            case 'nodeRemoved':
+                this.deleteNode(action);
+                break;
+            case 'nodeAdded':
+                this.addNode(action);
+                break;
+            case 'nodeUpdated':
+                this.updateNode(action);
+                break;
+            case 'edgeConnected':
+                this.connectEdge(action);
+                break;
+            case 'edgeUpdated':
+                this.updateEdge(action);
+                break;
+            case 'edgeRemoved':
+                this.deleteEdge(action);
+                break;
+            }
+        },
+        moveNode(action: NodeMovedAction, reverseStack: UndoRedoAction[]): void {
+            const node = findNode(action.nodeId);
+            node.position.x -= action.deltaMovement.x;
+            node.position.y -= action.deltaMovement.y;
+            
+            const reverseAction: NodeMovedAction = {
+                type: 'nodeMoved',
+                nodeId: action.nodeId,
+                deltaMovement: {
+                    x: -action.deltaMovement.x,
+                    y: -action.deltaMovement.y
+                }
+            };
+            reverseStack.push(reverseAction);
+        },
+        deleteNode() {
+            return;
+        },
+        addNode() {
+            return;
+        },
+        updateNode() {
+            return;
+        },
+        connectEdge() {
+            return;
+        },
+        updateEdge() {
+            return;
+        },
+        deleteEdge() {
+            return;
+        }
+    }
+});
\ No newline at end of file