diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa5684843d..7c07131e66 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,12 @@
 
 ## Unreleased
 
+### Changes
+
+- Use `Replay` interface for `browserReplayIntegration` return type ([#4858](https://github.com/getsentry/sentry-react-native/pull/4858))
+- Allow using `browserReplayIntegration` without `isWeb` guard ([#4858](https://github.com/getsentry/sentry-react-native/pull/4858))
+  - The integration returns noop in non-browser environments
+
 ### Dependencies
 
 - Bump Android SDK from v8.11.1 to v8.12.0 ([#4847](https://github.com/getsentry/sentry-react-native/pull/4847))
@@ -59,7 +65,7 @@ Version 7 of the SDK is compatible with Sentry self-hosted versions 24.4.2 or hi
 
 - Fork `scope` if custom scope is passed to `startSpanManual` or `startSpan`
 - On React Native Web, `browserSessionIntegration` is added when `enableAutoSessionTracking` is set to `True` ([#4732](https://github.com/getsentry/sentry-react-native/pull/4732))
-Change `Cold/Warm App Start` span description to `Cold/Warm Start` ([#4636](https://github.com/getsentry/sentry-react-native/pull/4636))
+- Change `Cold/Warm App Start` span description to `Cold/Warm Start` ([#4636](https://github.com/getsentry/sentry-react-native/pull/4636))
 
 ### Dependencies
 
diff --git a/packages/core/src/js/replay/browserReplay.ts b/packages/core/src/js/replay/browserReplay.ts
index b72c0be69f..a918b7e8f1 100644
--- a/packages/core/src/js/replay/browserReplay.ts
+++ b/packages/core/src/js/replay/browserReplay.ts
@@ -1,8 +1,30 @@
 import { replayIntegration } from '@sentry/react';
 
-const browserReplayIntegration = (
-  options: Parameters<typeof replayIntegration>[0] = {},
-): ReturnType<typeof replayIntegration> => {
+import { notWeb } from '../utils/environment';
+import type { Replay } from './replayInterface';
+
+/**
+ * ReplayConfiguration for browser replay integration.
+ *
+ * See the [Configuration documentation](https://docs.sentry.io/platforms/javascript/session-replay/configuration/) for more information.
+ */
+type ReplayConfiguration = Parameters<typeof replayIntegration>[0];
+
+// https://github.com/getsentry/sentry-javascript/blob/e00cb04f1bbf494067cd8475d392266ba296987a/packages/replay-internal/src/integration.ts#L109
+const INTEGRATION_NAME = 'Replay';
+
+/**
+ * Browser Replay integration for React Native.
+ *
+ * See the [Browser Replay documentation](https://docs.sentry.io/platforms/javascript/session-replay/) for more information.
+ */
+const browserReplayIntegration = (options: ReplayConfiguration = {}): Replay => {
+  if (notWeb()) {
+    // This is required because `replayIntegration` browser check doesn't
+    // work for React Native.
+    return browserReplayIntegrationNoop();
+  }
+
   return replayIntegration({
     ...options,
     mask: ['.sentry-react-native-mask', ...(options.mask || [])],
@@ -10,4 +32,18 @@ const browserReplayIntegration = (
   });
 };
 
+const browserReplayIntegrationNoop = (): Replay => {
+  return {
+    name: INTEGRATION_NAME,
+    // eslint-disable-next-line @typescript-eslint/no-empty-function
+    start: () => {},
+    // eslint-disable-next-line @typescript-eslint/no-empty-function
+    startBuffering: () => {},
+    stop: () => Promise.resolve(),
+    flush: () => Promise.resolve(),
+    getReplayId: () => undefined,
+    getRecordingMode: () => undefined,
+  };
+};
+
 export { browserReplayIntegration };
diff --git a/packages/core/src/js/replay/mobilereplay.ts b/packages/core/src/js/replay/mobilereplay.ts
index 3b63e40957..b55bf5950d 100644
--- a/packages/core/src/js/replay/mobilereplay.ts
+++ b/packages/core/src/js/replay/mobilereplay.ts
@@ -150,9 +150,6 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau
   // https://github.com/getsentry/sentry-javascript/blob/develop/packages/replay-internal/src/integration.ts#L45
   return {
     name: MOBILE_REPLAY_INTEGRATION_NAME,
-    setupOnce() {
-      /* Noop */
-    },
     setup,
     processEvent,
     options: options,
@@ -162,9 +159,6 @@ export const mobileReplayIntegration = (initOptions: MobileReplayOptions = defau
 const mobileReplayIntegrationNoop = (): MobileReplayIntegration => {
   return {
     name: MOBILE_REPLAY_INTEGRATION_NAME,
-    setupOnce() {
-      /* Noop */
-    },
     options: defaultOptions,
   };
 };
diff --git a/packages/core/src/js/replay/replayInterface.ts b/packages/core/src/js/replay/replayInterface.ts
new file mode 100644
index 0000000000..0308a5a385
--- /dev/null
+++ b/packages/core/src/js/replay/replayInterface.ts
@@ -0,0 +1,57 @@
+import type { Integration, ReplayRecordingMode } from '@sentry/core';
+
+// Based on Replay Class https://github.com/getsentry/sentry-javascript/blob/e00cb04f1bbf494067cd8475d392266ba296987a/packages/replay-internal/src/integration.ts#L50
+
+/**
+ * Common interface for React Native Replay integrations.
+ *
+ * Both browser and mobile replay integrations should implement this interface
+ * to allow user manually control the replay.
+ */
+export interface Replay extends Integration {
+  /**
+   * Start a replay regardless of sampling rate. Calling this will always
+   * create a new session. Will log a message if replay is already in progress.
+   *
+   * Creates or loads a session, attaches listeners to varying events (DOM,
+   * PerformanceObserver, Recording, Sentry SDK, etc)
+   */
+  start(): void;
+
+  /**
+   * Start replay buffering. Buffers until `flush()` is called or, if
+   * `replaysOnErrorSampleRate` > 0, until an error occurs.
+   */
+  startBuffering(): void;
+
+  /**
+   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK
+   * does not support a teardown
+   */
+  stop(): Promise<void>;
+
+  /**
+   * If not in "session" recording mode, flush event buffer which will create a new replay.
+   * If replay is not enabled, a new session replay is started.
+   * Unless `continueRecording` is false, the replay will continue to record and
+   * behave as a "session"-based replay.
+   *
+   * Otherwise, queue up a flush.
+   */
+  flush(options?: { continueRecording?: boolean }): Promise<void>;
+
+  /**
+   * Get the current session ID.
+   */
+  getReplayId(): string | undefined;
+
+  /**
+   * Get the current recording mode. This can be either `session` or `buffer`.
+   *
+   * `session`: Recording the whole session, sending it continuously
+   * `buffer`: Always keeping the last 60s of recording, requires:
+   *   - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs
+   *   - or calling `flush()` to send the replay
+   */
+  getRecordingMode(): ReplayRecordingMode | undefined;
+}
diff --git a/packages/core/test/replay/browserReplay.test.ts b/packages/core/test/replay/browserReplay.test.ts
new file mode 100644
index 0000000000..be12c27e21
--- /dev/null
+++ b/packages/core/test/replay/browserReplay.test.ts
@@ -0,0 +1,24 @@
+import { describe, test } from '@jest/globals';
+import * as SentryReact from '@sentry/react';
+import { spyOn } from 'jest-mock';
+
+import { browserReplayIntegration } from '../../src/js/replay/browserReplay';
+import * as environment from '../../src/js/utils/environment';
+
+describe('Browser Replay', () => {
+  afterEach(() => {
+    jest.clearAllMocks();
+  });
+
+  test('should not call replayIntegration if not web', () => {
+    spyOn(environment, 'notWeb').mockReturnValue(true);
+    spyOn(SentryReact, 'replayIntegration').mockImplementation(() => {
+      throw new Error('replayIntegration should not be called');
+    });
+
+    const integration = browserReplayIntegration();
+
+    expect(integration).toBeDefined();
+    expect(SentryReact.replayIntegration).not.toHaveBeenCalled();
+  });
+});
diff --git a/samples/expo/app/_layout.tsx b/samples/expo/app/_layout.tsx
index b3836cf6d3..f8a06db99f 100644
--- a/samples/expo/app/_layout.tsx
+++ b/samples/expo/app/_layout.tsx
@@ -10,7 +10,6 @@ import * as Sentry from '@sentry/react-native';
 import { ErrorEvent } from '@sentry/core';
 import { isExpoGo } from '../utils/isExpoGo';
 import { LogBox } from 'react-native';
-import { isWeb } from '../utils/isWeb';
 import * as ImagePicker from 'expo-image-picker';
 
 export {
@@ -58,13 +57,19 @@ Sentry.init({
       }),
       navigationIntegration,
       Sentry.reactNativeTracingIntegration(),
+      Sentry.mobileReplayIntegration({
+        maskAllImages: true,
+        maskAllText: true,
+        maskAllVectors: true,
+      }),
+      Sentry.browserReplayIntegration({
+        maskAllInputs: true,
+        maskAllText: true,
+      }),
       Sentry.feedbackIntegration({
         imagePicker: ImagePicker,
       }),
     );
-    if (isWeb()) {
-      integrations.push(Sentry.browserReplayIntegration());
-    }
     return integrations.filter(i => i.name !== 'Dedupe');
   },
   enableAutoSessionTracking: true,