diff --git a/apps/web/src/app/App.tsx b/apps/web/src/app/App.tsx
index 4e7d91e70248d6e3fcf5f710c080baa745ac31e4..960f48480c6ab9f55692520cfcbea1cd6c4068f9 100644
--- a/apps/web/src/app/App.tsx
+++ b/apps/web/src/app/App.tsx
@@ -23,7 +23,7 @@ import { SideNavTab, Sidebar } from '@graphpolaris/shared/lib/sidebar';
 import { InspectorPanel } from '@graphpolaris/shared/lib/inspector';
 import { SearchBar } from '@graphpolaris/shared/lib/sidebar/search/SearchBar';
 import { Schema } from '@graphpolaris/shared/lib/schema/panel';
-import { ErrorBoundary } from '../components/ErrorBoundary/ErrorBoundary';
+import { ErrorBoundary } from '@graphpolaris/shared/lib/components/ErrorBoundary/ErrorBoundary';
 
 export type App = {
   load?: string;
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index 5b58d4e9def1b0d4318612131e222754e76abed7..95858a9dbbdcbaca7fa4646214fe2a744ac7521c 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -45,7 +45,7 @@
     "postcss.config.js", // excludes PostCSS configuration file
     "tsconfig.tsbuildinfo" // excludes TypeScript build info file
   ],
-  "include": ["vite.config.ts", "src/**/*"],
+  "include": ["vite.config.ts", "src/**/*", "../../libs/shared/lib/components/ErrorBoundary"],
   "files": ["vite.config.ts"],
   "references": []
 }
diff --git a/apps/web/src/components/ErrorBoundary/ErrorBoundary.tsx b/libs/shared/lib/components/ErrorBoundary/ErrorBoundary.tsx
similarity index 96%
rename from apps/web/src/components/ErrorBoundary/ErrorBoundary.tsx
rename to libs/shared/lib/components/ErrorBoundary/ErrorBoundary.tsx
index a8cf8123496a885f3c1359e8b0e4c8bb88a46def..20470b3ab2c8f3f47feb91afcd995918d58f694f 100644
--- a/apps/web/src/components/ErrorBoundary/ErrorBoundary.tsx
+++ b/libs/shared/lib/components/ErrorBoundary/ErrorBoundary.tsx
@@ -1,5 +1,5 @@
-import { Button } from '@graphpolaris/shared';
 import React, { ReactNode } from 'react';
+import { Button } from '../buttons';
 
 interface ErrorBoundaryProps {
   fallback: ReactNode;
diff --git a/libs/shared/lib/vis/components/VisualizationPanel.tsx b/libs/shared/lib/vis/components/VisualizationPanel.tsx
index 94b3300af746b1aa0960901ff7129dedf2ae7d6c..39ed4d1122352318a0fc2bdd82e514d2ca135d7d 100644
--- a/libs/shared/lib/vis/components/VisualizationPanel.tsx
+++ b/libs/shared/lib/vis/components/VisualizationPanel.tsx
@@ -15,6 +15,7 @@ import { Recommender, NoData, Querying } from '../views';
 import { resultSetFocus, resultSetSelection, unSelect } from '../../data-access/store/interactionSlice';
 import { updateVisualization, addVisualization } from '../../data-access/store/visualizationSlice';
 import { VisualizationPropTypes, VISComponentType } from '../common';
+import { ErrorBoundary } from '../../components/ErrorBoundary/ErrorBoundary';
 
 type PromiseFunc = () => Promise<{ default: VISComponentType<any> }>;
 export const Visualizations: Record<string, PromiseFunc> = {
@@ -84,37 +85,39 @@ export const VisualizationPanel = ({ fullSize }: { fullSize: () => void }) => {
       onMouseDownCapture={() => dispatch(resultSetFocus({ focusType: 'visualization' }))}
     >
       <VisualizationTabBar fullSize={fullSize} />
-      <div className="grow overflow-y-auto" style={graphQueryResult.nodes.length === 0 ? { overflow: 'hidden' } : {}}>
-        {graphQueryResult.queryingBackend ? (
-          <Querying />
-        ) : graphQueryResult.nodes.length === 0 ? (
-          <NoData dataAvailable={query.nodes.length > 0} />
-        ) : openVisualizationArray.length === 0 ? (
-          <Recommender />
-        ) : (
-          <div className="w-full h-full flex">
-            <Suspense fallback={<div>Loading...</div>}>
-              {!!viz &&
-                activeVisualizationIndex !== -1 &&
-                openVisualizationArray?.[activeVisualizationIndex] &&
-                viz.id === openVisualizationArray[activeVisualizationIndex].id &&
-                graphMetadata && (
-                  <viz.component
-                    data={graphQueryResult}
-                    schema={schema}
-                    ml={ml}
-                    settings={openVisualizationArray[activeVisualizationIndex]}
-                    dispatch={dispatch}
-                    handleSelect={handleSelect}
-                    graphMetadata={graphMetadata}
-                    updateSettings={updateSettings}
-                    handleHover={() => {}}
-                  />
-                )}
-            </Suspense>
-          </div>
-        )}
-      </div>
+      <ErrorBoundary fallback={<p>Visualization component failed</p>}>
+        <div className="grow overflow-y-auto" style={graphQueryResult.nodes.length === 0 ? { overflow: 'hidden' } : {}}>
+          {graphQueryResult.queryingBackend ? (
+            <Querying />
+          ) : graphQueryResult.nodes.length === 0 ? (
+            <NoData dataAvailable={query.nodes.length > 0} />
+          ) : openVisualizationArray.length === 0 ? (
+            <Recommender />
+          ) : (
+            <div className="w-full h-full flex">
+              <Suspense fallback={<div>Loading...</div>}>
+                {!!viz &&
+                  activeVisualizationIndex !== -1 &&
+                  openVisualizationArray?.[activeVisualizationIndex] &&
+                  viz.id === openVisualizationArray[activeVisualizationIndex].id &&
+                  graphMetadata && (
+                    <viz.component
+                      data={graphQueryResult}
+                      schema={schema}
+                      ml={ml}
+                      settings={openVisualizationArray[activeVisualizationIndex]}
+                      dispatch={dispatch}
+                      handleSelect={handleSelect}
+                      graphMetadata={graphMetadata}
+                      updateSettings={updateSettings}
+                      handleHover={() => {}}
+                    />
+                  )}
+              </Suspense>
+            </div>
+          )}
+        </div>
+      </ErrorBoundary>
     </div>
   );
 };