diff --git a/apps/site/components/Common/CodeBox.tsx b/apps/site/components/Common/CodeBox.tsx
index 5d494fe825f3c..049e95196c4df 100644
--- a/apps/site/components/Common/CodeBox.tsx
+++ b/apps/site/components/Common/CodeBox.tsx
@@ -3,11 +3,12 @@
import { CodeBracketIcon } from '@heroicons/react/24/outline';
import BaseCodeBox from '@node-core/ui-components/Common/BaseCodeBox';
import styles from '@node-core/ui-components/Common/BaseCodeBox/index.module.css';
+import { useNotification } from '@node-core/ui-components/Providers/NotificationProvider';
import { useTranslations } from 'next-intl';
import type { FC, PropsWithChildren } from 'react';
import Link from '#site/components/Link';
-import { useCopyToClipboard, useNotification } from '#site/hooks';
+import { useCopyToClipboard } from '#site/hooks';
type CodeBoxProps = {
language: string;
diff --git a/apps/site/hooks/react-client/__tests__/useNotification.test.jsx b/apps/site/hooks/react-client/__tests__/useNotification.test.jsx
deleted file mode 100644
index fcba40ea86091..0000000000000
--- a/apps/site/hooks/react-client/__tests__/useNotification.test.jsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { render } from '@testing-library/react';
-
-import { describe, it } from 'node:test';
-import assert from 'node:assert/strict';
-
-import useNotification from '#site/hooks/react-client/useNotification';
-import { NotificationProvider } from '#site/providers/notificationProvider';
-
-describe('useNotification', () => {
- it('should return the notification dispatch function', () => {
- // Arrange
- const TestComponent = () => {
- const notificationDispatch = useNotification();
- return (
-
- {notificationDispatch ? 'Dispatch available' : 'Dispatch unavailable'}
-
- );
- };
-
- // Act
- const { getByText } = render(
-
-
-
- );
-
- // Assert
- const result = getByText('Dispatch available');
- assert.ok(result.ownerDocument);
- });
-
- it('should return null outside NotificationProvider', () => {
- // Arrange
- const TestComponent = () => {
- const notificationDispatch = useNotification();
- return (
-
- {notificationDispatch ? 'Dispatch available' : 'Dispatch unavailable'}
-
- );
- };
-
- // Act
- const { queryByText } = render();
-
- // Assert
- const result = queryByText((content, element) => {
- return element.textContent === 'Dispatch unavailable';
- });
-
- assert.equal(result, null);
- });
-});
diff --git a/apps/site/hooks/react-client/index.ts b/apps/site/hooks/react-client/index.ts
index 33a9392db1a58..30d4e71478cea 100644
--- a/apps/site/hooks/react-client/index.ts
+++ b/apps/site/hooks/react-client/index.ts
@@ -1,6 +1,5 @@
export { default as useCopyToClipboard } from './useCopyToClipboard';
export { default as useDetectOS } from './useDetectOS';
export { default as useMediaQuery } from './useMediaQuery';
-export { default as useNotification } from './useNotification';
export { default as useClientContext } from './useClientContext';
export { default as useNavigationState } from './useNavigationState';
diff --git a/apps/site/hooks/react-client/useNotification.ts b/apps/site/hooks/react-client/useNotification.ts
deleted file mode 100644
index acac47f606faf..0000000000000
--- a/apps/site/hooks/react-client/useNotification.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-'use client';
-
-import { useContext } from 'react';
-
-import { NotificationDispatch } from '#site/providers/notificationProvider';
-
-const useNotification = () => useContext(NotificationDispatch);
-
-export default useNotification;
diff --git a/apps/site/hooks/react-server/index.ts b/apps/site/hooks/react-server/index.ts
index a6cf9825ba2c2..e4c16cec3c466 100644
--- a/apps/site/hooks/react-server/index.ts
+++ b/apps/site/hooks/react-server/index.ts
@@ -1,5 +1,4 @@
export { default as useCopyToClipboard } from './useCopyToClipboard';
export { default as useDetectOS } from './useDetectOS';
export { default as useMediaQuery } from './useMediaQuery';
-export { default as useNotification } from './useNotification';
export { default as useClientContext } from './useClientContext';
diff --git a/apps/site/hooks/react-server/useNotification.ts b/apps/site/hooks/react-server/useNotification.ts
deleted file mode 100644
index b85483fc24713..0000000000000
--- a/apps/site/hooks/react-server/useNotification.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-const useNotification = () => {
- throw new Error('Attempted to call useNotification from RSC');
-};
-
-export default useNotification;
diff --git a/apps/site/layouts/Base.tsx b/apps/site/layouts/Base.tsx
index 83ff12826ed06..ab7770efb10ef 100644
--- a/apps/site/layouts/Base.tsx
+++ b/apps/site/layouts/Base.tsx
@@ -1,9 +1,9 @@
'use client';
+import { NotificationProvider } from '@node-core/ui-components/Providers/NotificationProvider';
import type { FC, PropsWithChildren } from 'react';
import { NavigationStateProvider } from '#site/providers/navigationStateProvider';
-import { NotificationProvider } from '#site/providers/notificationProvider';
import styles from './layouts.module.css';
diff --git a/apps/site/package.json b/apps/site/package.json
index bdd04d21b59d5..a0d9710f005a0 100644
--- a/apps/site/package.json
+++ b/apps/site/package.json
@@ -44,7 +44,6 @@
"@oramacloud/client": "^2.1.4",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.12",
- "@radix-ui/react-toast": "^1.2.14",
"@radix-ui/react-tooltip": "^1.2.7",
"@tailwindcss/postcss": "~4.1.11",
"@types/node": "catalog:",
diff --git a/apps/site/providers/__tests__/notificationProvider.test.jsx b/apps/site/providers/__tests__/notificationProvider.test.jsx
deleted file mode 100644
index 9a95573ef7511..0000000000000
--- a/apps/site/providers/__tests__/notificationProvider.test.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { describe, it } from 'node:test';
-import assert from 'node:assert/strict';
-
-import { render, act, waitFor } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-
-import {
- NotificationProvider,
- NotificationDispatch,
-} from '#site/providers/notificationProvider';
-
-describe('NotificationProvider', () => {
- it('renders children and shows notification with the provided message', async t => {
- t.mock.timers.enable();
- const testMessage = 'Test Notification';
- const testDuration = 3000;
-
- const { getByText } = render(
-
-
- {dispatch => (
-
- )}
-
-
- );
-
- act(() => {
- userEvent.click(getByText('Show Notification'));
- t.mock.timers.tick(3000);
- });
-
- t.mock.timers.reset();
-
- await waitFor(() => assert.ok(getByText(testMessage).ownerDocument));
- });
-});
diff --git a/apps/site/providers/notificationProvider.tsx b/packages/ui-components/src/Providers/NotificationProvider.tsx
similarity index 87%
rename from apps/site/providers/notificationProvider.tsx
rename to packages/ui-components/src/Providers/NotificationProvider.tsx
index cd07fe6c1e029..743bc50c0f9a8 100644
--- a/apps/site/providers/notificationProvider.tsx
+++ b/packages/ui-components/src/Providers/NotificationProvider.tsx
@@ -1,5 +1,5 @@
-import Notification from '@node-core/ui-components/Common/Notification';
import * as Toast from '@radix-ui/react-toast';
+import { createContext, useContext, useEffect, useState } from 'react';
import type {
Dispatch,
FC,
@@ -7,7 +7,8 @@ import type {
ReactNode,
SetStateAction,
} from 'react';
-import { createContext, useEffect, useState } from 'react';
+
+import Notification from '#ui/Common/Notification';
type NotificationContextType = {
message: string | ReactNode;
@@ -22,6 +23,8 @@ export const NotificationDispatch = createContext<
Dispatch>
>(() => {});
+export const useNotification = () => useContext(NotificationDispatch);
+
export const NotificationProvider: FC> = ({
viewportClassName,
children,
diff --git a/packages/ui-components/src/Providers/__tests__/NotificationProvider.test.jsx b/packages/ui-components/src/Providers/__tests__/NotificationProvider.test.jsx
new file mode 100644
index 0000000000000..33525f1f42509
--- /dev/null
+++ b/packages/ui-components/src/Providers/__tests__/NotificationProvider.test.jsx
@@ -0,0 +1,53 @@
+import { render } from '@testing-library/react';
+
+import { describe, it } from 'node:test';
+import assert from 'node:assert/strict';
+
+import { NotificationProvider, useNotification } from '../NotificationProvider';
+
+describe('useNotification', () => {
+ it('should return the notification dispatch function', () => {
+ // Arrange
+ const TestComponent = () => {
+ const notificationDispatch = useNotification();
+ return (
+
+ {notificationDispatch ? 'Dispatch available' : 'Dispatch unavailable'}
+
+ );
+ };
+
+ // Act
+ const { getByText } = render(
+
+
+
+ );
+
+ // Assert
+ const result = getByText('Dispatch available');
+ assert.ok(result.ownerDocument);
+ });
+
+ it('should return null outside NotificationProvider', () => {
+ // Arrange
+ const TestComponent = () => {
+ const notificationDispatch = useNotification();
+ return (
+
+ {notificationDispatch ? 'Dispatch available' : 'Dispatch unavailable'}
+
+ );
+ };
+
+ // Act
+ const { queryByText } = render();
+
+ // Assert
+ const result = queryByText((content, element) => {
+ return element.textContent === 'Dispatch unavailable';
+ });
+
+ assert.equal(result, null);
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9b3dfd68b48b0..6df9fdce2ce2c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -111,9 +111,6 @@ importers:
'@radix-ui/react-tabs':
specifier: ^1.1.12
version: 1.1.12(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
- '@radix-ui/react-toast':
- specifier: ^1.2.14
- version: 1.2.14(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@radix-ui/react-tooltip':
specifier: ^1.2.7
version: 1.2.7(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)