diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json
index 373990a037cf..9c62488523dd 100644
--- a/dev-packages/browser-integration-tests/package.json
+++ b/dev-packages/browser-integration-tests/package.json
@@ -43,6 +43,7 @@
     "@playwright/test": "~1.50.0",
     "@sentry-internal/rrweb": "2.34.0",
     "@sentry/browser": "9.10.1",
+    "@supabase/supabase-js": "2.49.3",
     "axios": "1.8.2",
     "babel-loader": "^8.2.2",
     "fflate": "0.8.2",
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/init.js b/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/init.js
new file mode 100644
index 000000000000..a88c4cec54f3
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/init.js
@@ -0,0 +1,24 @@
+import * as Sentry from '@sentry/browser';
+
+import { createClient } from '@supabase/supabase-js';
+window.Sentry = Sentry;
+
+const supabase = createClient('https://test.supabase.co', 'test-key');
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  integrations: [Sentry.browserTracingIntegration(), Sentry.supabaseIntegration(supabase)],
+  tracesSampleRate: 1.0,
+});
+
+// Simulate authentication operations
+async function performAuthenticationOperations() {
+  await supabase.auth.signInWithPassword({
+    email: 'test@example.com',
+    password: 'test-password',
+  });
+
+  await supabase.auth.signOut();
+}
+
+performAuthenticationOperations();
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/test.ts b/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/test.ts
new file mode 100644
index 000000000000..494039b64136
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/auth/test.ts
@@ -0,0 +1,140 @@
+import type { Page } from '@playwright/test';
+import { expect } from '@playwright/test';
+import type { Event } from '@sentry/core';
+
+import { sentryTest } from '../../../../utils/fixtures';
+import {
+  getFirstSentryEnvelopeRequest,
+  getMultipleSentryEnvelopeRequests,
+  shouldSkipTracingTest,
+} from '../../../../utils/helpers';
+
+async function mockSupabaseAuthRoutesSuccess(page: Page) {
+  await page.route('**/auth/v1/token?grant_type=password**', route => {
+    return route.fulfill({
+      status: 200,
+      body: JSON.stringify({
+        access_token: 'test-access-token',
+        refresh_token: 'test-refresh-token',
+        token_type: 'bearer',
+        expires_in: 3600,
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+
+  await page.route('**/auth/v1/logout**', route => {
+    return route.fulfill({
+      status: 200,
+      body: JSON.stringify({
+        message: 'Logged out',
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+}
+
+async function mockSupabaseAuthRoutesFailure(page: Page) {
+  await page.route('**/auth/v1/token?grant_type=password**', route => {
+    return route.fulfill({
+      status: 400,
+      body: JSON.stringify({
+        error_description: 'Invalid email or password',
+        error: 'invalid_grant',
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+
+  await page.route('**/auth/v1/logout**', route => {
+    return route.fulfill({
+      status: 400,
+      body: JSON.stringify({
+        error_description: 'Invalid refresh token',
+        error: 'invalid_grant',
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+}
+
+sentryTest('should capture Supabase authentication spans', async ({ getLocalTestUrl, page }) => {
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  await mockSupabaseAuthRoutesSuccess(page);
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
+  const supabaseSpans = eventData.spans?.filter(({ op }) => op?.startsWith('db.supabase.auth'));
+
+  expect(supabaseSpans).toHaveLength(2);
+  expect(supabaseSpans![0]).toMatchObject({
+    description: 'signInWithPassword',
+    parent_span_id: eventData.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: eventData.contexts?.trace?.trace_id,
+    status: 'ok',
+    data: expect.objectContaining({
+      'sentry.op': 'db.supabase.auth.signInWithPassword',
+      'sentry.origin': 'auto.db.supabase',
+    }),
+  });
+
+  expect(supabaseSpans![1]).toMatchObject({
+    description: 'signOut',
+    parent_span_id: eventData.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: eventData.contexts?.trace?.trace_id,
+    status: 'ok',
+    data: expect.objectContaining({
+      'sentry.op': 'db.supabase.auth.signOut',
+      'sentry.origin': 'auto.db.supabase',
+    }),
+  });
+});
+
+sentryTest('should capture Supabase authentication errors', async ({ getLocalTestUrl, page }) => {
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  await mockSupabaseAuthRoutesFailure(page);
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const [errorEvent, transactionEvent] = await getMultipleSentryEnvelopeRequests<Event>(page, 2, { url });
+
+  const supabaseSpans = transactionEvent.spans?.filter(({ op }) => op?.startsWith('db.supabase.auth'));
+
+  expect(errorEvent.exception?.values?.[0].value).toBe('Invalid email or password');
+
+  expect(supabaseSpans).toHaveLength(2);
+  expect(supabaseSpans![0]).toMatchObject({
+    description: 'signInWithPassword',
+    parent_span_id: transactionEvent.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: transactionEvent.contexts?.trace?.trace_id,
+    status: 'unknown_error',
+    data: expect.objectContaining({
+      'sentry.op': 'db.supabase.auth.signInWithPassword',
+      'sentry.origin': 'auto.db.supabase',
+    }),
+  });
+});
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/init.js b/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/init.js
new file mode 100644
index 000000000000..08023f1a38a0
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/init.js
@@ -0,0 +1,38 @@
+import * as Sentry from '@sentry/browser';
+
+import { createClient } from '@supabase/supabase-js';
+window.Sentry = Sentry;
+
+const supabase = createClient(
+  'https://test.supabase.co',
+  'test-key'
+);
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  integrations: [
+    Sentry.browserTracingIntegration(),
+    Sentry.supabaseIntegration(supabase)
+  ],
+  tracesSampleRate: 1.0,
+});
+
+// Simulate database operations
+async function performDatabaseOperations() {
+  try {
+    await supabase
+      .from('todos')
+      .insert([{ title: 'Test Todo' }]);
+
+    await supabase
+      .from('todos')
+      .select('*');
+
+    // Trigger an error to capture the breadcrumbs
+    throw new Error('Test Error');
+  } catch (error) {
+    Sentry.captureException(error);
+  }
+}
+
+performDatabaseOperations();
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/test.ts b/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/test.ts
new file mode 100644
index 000000000000..76abb4881aec
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/db-operations/test.ts
@@ -0,0 +1,82 @@
+import type { Page } from '@playwright/test';
+import { expect } from '@playwright/test';
+import type { Event } from '@sentry/core';
+
+import { sentryTest } from '../../../../utils/fixtures';
+import { getFirstSentryEnvelopeRequest, getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers';
+
+async function mockSupabaseRoute(page: Page) {
+  await page.route('**/rest/v1/todos**', route => {
+    return route.fulfill({
+      status: 200,
+      body: JSON.stringify({
+        userNames: ['John', 'Jane'],
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+}
+
+sentryTest('should capture Supabase database operation breadcrumbs', async ({ getLocalTestUrl, page }) => {
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  await mockSupabaseRoute(page);
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
+
+  expect(eventData.breadcrumbs).toBeDefined();
+  expect(eventData.breadcrumbs).toContainEqual({
+    timestamp: expect.any(Number),
+    type: 'supabase',
+    category: 'db.insert',
+    message: 'from(todos)',
+    data: expect.any(Object),
+  });
+});
+
+sentryTest('should capture multiple Supabase operations in sequence', async ({ getLocalTestUrl, page }) => {
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  await mockSupabaseRoute(page);
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const events = await getMultipleSentryEnvelopeRequests<Event>(page, 2, { url });
+
+  expect(events).toHaveLength(2);
+
+  events.forEach(event => {
+    expect(
+      event.breadcrumbs?.some(breadcrumb => breadcrumb.type === 'supabase' && breadcrumb?.category?.startsWith('db.')),
+    ).toBe(true);
+  });
+});
+
+sentryTest('should include correct data payload in Supabase breadcrumbs', async ({ getLocalTestUrl, page }) => {
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  await mockSupabaseRoute(page);
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
+
+  const supabaseBreadcrumb = eventData.breadcrumbs?.find(b => b.type === 'supabase');
+
+  expect(supabaseBreadcrumb).toBeDefined();
+  expect(supabaseBreadcrumb?.data).toMatchObject({
+    query: expect.arrayContaining([
+      'filter(columns, )'
+    ]),
+  });
+});
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/init.js b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/init.js
new file mode 100644
index 000000000000..7b0fdb096ebc
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/init.js
@@ -0,0 +1,34 @@
+import * as Sentry from '@sentry/browser';
+
+import { createClient } from '@supabase/supabase-js';
+window.Sentry = Sentry;
+
+const queues = createClient('https://test.supabase.co', 'test-key', {
+  db: {
+    schema: 'pgmq_public',
+  },
+});
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  integrations: [Sentry.browserTracingIntegration(), Sentry.supabaseIntegration(queues)],
+  tracesSampleRate: 1.0,
+});
+
+// Simulate queue operations
+async function performQueueOperations() {
+  try {
+    await queues.rpc('enqueue', {
+        queue_name: 'todos',
+        msg: { title: 'Test Todo' },
+      });
+
+      await queues.rpc('dequeue', {
+        queue_name: 'todos',
+      });
+  } catch (error) {
+    Sentry.captureException(error);
+  }
+}
+
+performQueueOperations();
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/test.ts b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/test.ts
new file mode 100644
index 000000000000..8b6ee89e9f81
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-rpc/test.ts
@@ -0,0 +1,64 @@
+import type { Page} from '@playwright/test';
+import { expect } from '@playwright/test';
+import type { Event } from '@sentry/core';
+
+import { sentryTest } from '../../../../utils/fixtures';
+import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
+
+async function mockSupabaseRoute(page: Page) {
+  await page.route('**/rest/v1/rpc**', route => {
+    return route.fulfill({
+      status: 200,
+      body: JSON.stringify({
+        foo: ['bar', 'baz'],
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+}
+
+sentryTest('should capture Supabase queue spans from client.rpc', async ({ getLocalTestUrl, page }) => {
+  await mockSupabaseRoute(page);
+
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const event = await getFirstSentryEnvelopeRequest<Event>(page, url);
+  const queueSpans = event.spans?.filter(({ op }) => op?.startsWith('queue'));
+
+  expect(queueSpans).toHaveLength(2);
+
+  expect(queueSpans![0]).toMatchObject({
+    description: 'supabase.db.rpc',
+    parent_span_id: event.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: event.contexts?.trace?.trace_id,
+    data: expect.objectContaining({
+      'sentry.op': 'queue.publish',
+      'sentry.origin': 'auto.db.supabase',
+      'messaging.destination.name': 'todos',
+      'messaging.message.id': 'Test Todo',
+    }),
+  });
+
+  expect(queueSpans![1]).toMatchObject({
+    description: 'supabase.db.rpc',
+    parent_span_id: event.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: event.contexts?.trace?.trace_id,
+    data: expect.objectContaining({
+      'sentry.op': 'queue.process',
+      'sentry.origin': 'auto.db.supabase',
+      'messaging.destination.name': 'todos',
+    }),
+  });
+});
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/init.js b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/init.js
new file mode 100644
index 000000000000..43c50357f1eb
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/init.js
@@ -0,0 +1,38 @@
+import * as Sentry from '@sentry/browser';
+
+import { createClient } from '@supabase/supabase-js';
+window.Sentry = Sentry;
+
+const queues = createClient('https://test.supabase.co', 'test-key', {
+  db: {
+    schema: 'pgmq_public',
+  },
+});
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  integrations: [Sentry.browserTracingIntegration(), Sentry.supabaseIntegration(queues)],
+  tracesSampleRate: 1.0,
+});
+
+// Simulate queue operations
+async function performQueueOperations() {
+  try {
+    await queues
+      .schema('pgmq_public')
+      .rpc('enqueue', {
+        queue_name: 'todos',
+        msg: { title: 'Test Todo' },
+      });
+
+      await queues
+      .schema('pgmq_public')
+      .rpc('dequeue', {
+        queue_name: 'todos',
+      });
+  } catch (error) {
+    Sentry.captureException(error);
+  }
+}
+
+performQueueOperations();
diff --git a/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/test.ts b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/test.ts
new file mode 100644
index 000000000000..8070a1b17357
--- /dev/null
+++ b/dev-packages/browser-integration-tests/suites/integrations/supabase/queues-schema/test.ts
@@ -0,0 +1,63 @@
+import { type Page, expect } from '@playwright/test';
+import type { Event } from '@sentry/core';
+
+import { sentryTest } from '../../../../utils/fixtures';
+import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
+
+async function mockSupabaseRoute(page: Page) {
+  await page.route('**/rest/v1/rpc**', route => {
+    return route.fulfill({
+      status: 200,
+      body: JSON.stringify({
+        foo: ['bar', 'baz'],
+      }),
+      headers: {
+        'Content-Type': 'application/json',
+      },
+    });
+  });
+}
+
+sentryTest('should capture Supabase queue spans from client.schema(...).rpc', async ({ getLocalTestUrl, page }) => {
+  await mockSupabaseRoute(page);
+
+  if (shouldSkipTracingTest()) {
+    return;
+  }
+
+  const url = await getLocalTestUrl({ testDir: __dirname });
+
+  const event = await getFirstSentryEnvelopeRequest<Event>(page, url);
+  const queueSpans = event.spans?.filter(({ op }) => op?.startsWith('queue'));
+
+  expect(queueSpans).toHaveLength(2);
+
+  expect(queueSpans![0]).toMatchObject({
+    description: 'supabase.db.rpc',
+    parent_span_id: event.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: event.contexts?.trace?.trace_id,
+    data: expect.objectContaining({
+      'sentry.op': 'queue.publish',
+      'sentry.origin': 'auto.db.supabase',
+      'messaging.destination.name': 'todos',
+      'messaging.message.id': 'Test Todo',
+    }),
+  });
+
+  expect(queueSpans![1]).toMatchObject({
+    description: 'supabase.db.rpc',
+    parent_span_id: event.contexts?.trace?.span_id,
+    span_id: expect.any(String),
+    start_timestamp: expect.any(Number),
+    timestamp: expect.any(Number),
+    trace_id: event.contexts?.trace?.trace_id,
+    data: expect.objectContaining({
+      'sentry.op': 'queue.process',
+      'sentry.origin': 'auto.db.supabase',
+      'messaging.destination.name': 'todos',
+    }),
+  });
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/.gitignore b/dev-packages/e2e-tests/test-applications/supabase-nextjs/.gitignore
new file mode 100644
index 000000000000..e7e8ec25eed1
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/.gitignore
@@ -0,0 +1,39 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+# Sentry Config File
+.env.sentry-build-plugin
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/.npmrc b/dev-packages/e2e-tests/test-applications/supabase-nextjs/.npmrc
new file mode 100644
index 000000000000..070f80f05092
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/.npmrc
@@ -0,0 +1,2 @@
+@sentry:registry=http://127.0.0.1:4873
+@sentry-internal:registry=http://127.0.0.1:4873
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/README.md b/dev-packages/e2e-tests/test-applications/supabase-nextjs/README.md
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/components/TodoList.tsx b/dev-packages/e2e-tests/test-applications/supabase-nextjs/components/TodoList.tsx
new file mode 100644
index 000000000000..6fe5b810e05b
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/components/TodoList.tsx
@@ -0,0 +1,125 @@
+import { Database } from '@/lib/schema';
+import { Session, useSupabaseClient } from '@supabase/auth-helpers-react';
+import { useEffect, useState } from 'react';
+
+type Todos = Database['public']['Tables']['todos']['Row'];
+
+export default function TodoList({ session }: { session: Session }) {
+  const supabase = useSupabaseClient<Database>();
+  const [todos, setTodos] = useState<Todos[]>([]);
+  const [newTaskText, setNewTaskText] = useState('');
+  const [errorText, setErrorText] = useState('');
+
+  const user = session.user;
+
+  useEffect(() => {
+    const fetchTodos = async () => {
+      const { data: todos, error } = await supabase.from('todos').select('*').order('id', { ascending: true });
+
+      if (error) console.log('error', error);
+      else setTodos(todos);
+    };
+
+    fetchTodos();
+  }, [supabase]);
+
+  const addTodo = async (taskText: string) => {
+    let task = taskText.trim();
+    if (task.length) {
+      const { data: todo, error } = await supabase.from('todos').insert({ task, user_id: user.id }).select().single();
+
+      if (error) {
+        setErrorText(error.message);
+      } else {
+        setTodos([...todos, todo]);
+        setNewTaskText('');
+      }
+    }
+  };
+
+  const deleteTodo = async (id: number) => {
+    try {
+      await supabase.from('todos').delete().eq('id', id).throwOnError();
+      setTodos(todos.filter(x => x.id != id));
+    } catch (error) {
+      console.log('error', error);
+    }
+  };
+
+  return (
+    <div>
+      <h1>Todo List.</h1>
+      <form
+        onSubmit={e => {
+          e.preventDefault();
+          addTodo(newTaskText);
+        }}
+      >
+        <input
+          id="new-task-text"
+          type="text"
+          value={newTaskText}
+          onChange={e => {
+            setErrorText('');
+            setNewTaskText(e.target.value);
+          }}
+        />
+        <button id="add-task" type="submit">Add</button>
+      </form>
+      {!!errorText && <Alert text={errorText} />}
+      <ul>
+        {todos.map(todo => (
+          <Todo key={todo.id} todo={todo} onDelete={() => deleteTodo(todo.id)} />
+        ))}
+      </ul>
+    </div>
+  );
+}
+
+const Todo = ({ todo, onDelete }: { todo: Todos; onDelete: () => void }) => {
+  const supabase = useSupabaseClient<Database>();
+  const [isCompleted, setIsCompleted] = useState(todo.is_complete);
+
+  const toggle = async () => {
+    try {
+      const { data } = await supabase
+        .from('todos')
+        .update({ is_complete: !isCompleted })
+        .eq('id', todo.id)
+        .throwOnError()
+        .select()
+        .single();
+
+      if (data) setIsCompleted(data.is_complete);
+    } catch (error) {
+      console.log('error', error);
+    }
+  };
+
+  return (
+    <li>
+      <div>
+        <div>
+          <div>{todo.task}</div>
+        </div>
+        <div>
+          <input
+            className="cursor-pointer"
+            onChange={e => toggle()}
+            type="checkbox"
+            checked={isCompleted ? true : false}
+          />
+        </div>
+        <button
+          onClick={e => {
+            e.preventDefault();
+            e.stopPropagation();
+            onDelete();
+          }}
+        ></button>
+      </div>
+    </li>
+  );
+};
+
+const Alert = ({ text }: { text: string }) => <div>{text}</div>;
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/instrumentation.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/instrumentation.ts
new file mode 100644
index 000000000000..964f937c439a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/instrumentation.ts
@@ -0,0 +1,13 @@
+import * as Sentry from '@sentry/nextjs';
+
+export async function register() {
+  if (process.env.NEXT_RUNTIME === 'nodejs') {
+    await import('./sentry.server.config');
+  }
+
+  if (process.env.NEXT_RUNTIME === 'edge') {
+    await import('./sentry.edge.config');
+  }
+}
+
+export const onRequestError = Sentry.captureRequestError;
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAdmin.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAdmin.ts
new file mode 100644
index 000000000000..b5381132cf32
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAdmin.ts
@@ -0,0 +1,19 @@
+import { createClient } from '@supabase/supabase-js';
+import * as Sentry from '@sentry/nextjs';
+
+// These are the default development keys for a local Supabase instance
+const NEXT_PUBLIC_SUPABASE_URL = 'http://localhost:54321';
+const SUPABASE_SERVICE_ROLE_KEY =
+  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU';
+
+export const supabaseClient = createClient(NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, {
+  auth: {
+    persistSession: false,
+    autoRefreshToken: false,
+    detectSessionInUrl: false,
+  },
+});
+
+Sentry.addIntegration(
+  Sentry.supabaseIntegration(supabaseClient),
+);
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAnon.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAnon.ts
new file mode 100644
index 000000000000..3e4f1b1cf7ac
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/initSupabaseAnon.ts
@@ -0,0 +1,11 @@
+import { createClient } from '@supabase/supabase-js';
+import * as Sentry from '@sentry/nextjs';
+
+// These are the default development keys for a local Supabase instance
+const NEXT_PUBLIC_SUPABASE_URL = 'http://localhost:54321';
+const NEXT_PUBLIC_SUPABASE_ANON_KEY =
+  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImV4cGxvcmV0ZXN0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2';
+
+export const supabaseClient = createClient(NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY);
+
+Sentry.addIntegration(Sentry.supabaseIntegration(supabaseClient));
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/schema.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/schema.ts
new file mode 100644
index 000000000000..ec8b8f854b2a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/lib/schema.ts
@@ -0,0 +1,49 @@
+export type Json =
+  | string
+  | number
+  | boolean
+  | null
+  | { [key: string]: Json }
+  | Json[]
+
+export interface Database {
+  public: {
+    Tables: {
+      todos: {
+        Row: {
+          id: number
+          inserted_at: string
+          is_complete: boolean | null
+          task: string | null
+          user_id: string
+        }
+        Insert: {
+          id?: number
+          inserted_at?: string
+          is_complete?: boolean | null
+          task?: string | null
+          user_id: string
+        }
+        Update: {
+          id?: number
+          inserted_at?: string
+          is_complete?: boolean | null
+          task?: string | null
+          user_id?: string
+        }
+      }
+    }
+    Views: {
+      [_ in never]: never
+    }
+    Functions: {
+      [_ in never]: never
+    }
+    Enums: {
+      [_ in never]: never
+    }
+    CompositeTypes: {
+      [_ in never]: never
+    }
+  }
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/next.config.js b/dev-packages/e2e-tests/test-applications/supabase-nextjs/next.config.js
new file mode 100644
index 000000000000..003a6cb03964
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/next.config.js
@@ -0,0 +1,51 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+  reactStrictMode: true,
+}
+
+module.exports = nextConfig
+
+
+// Injected content via Sentry wizard below
+
+const { withSentryConfig } = require("@sentry/nextjs");
+
+module.exports = withSentryConfig(
+  module.exports,
+  {
+    // For all available options, see:
+    // https://www.npmjs.com/package/@sentry/webpack-plugin#options
+
+    org: "sentry-sdks",
+    project: "sentry-javascript-nextjs",
+
+    // Only print logs for uploading source maps in CI
+    silent: !process.env.CI,
+
+    // For all available options, see:
+    // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
+
+    // Upload a larger set of source maps for prettier stack traces (increases build time)
+    widenClientFileUpload: true,
+
+    // Automatically annotate React components to show their full name in breadcrumbs and session replay
+    reactComponentAnnotation: {
+      enabled: true,
+    },
+
+    // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
+    // This can increase your server load as well as your hosting bill.
+    // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
+    // side errors will fail.
+    tunnelRoute: "/monitoring",
+
+    // Automatically tree-shake Sentry logger statements to reduce bundle size
+    disableLogger: false,
+
+    // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
+    // See the following for more information:
+    // https://docs.sentry.io/product/crons/
+    // https://vercel.com/docs/cron-jobs
+    automaticVercelMonitors: true,
+  }
+);
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/package.json b/dev-packages/e2e-tests/test-applications/supabase-nextjs/package.json
new file mode 100644
index 000000000000..639bb6e64698
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/package.json
@@ -0,0 +1,40 @@
+{
+  "name": "supabase-nextjs-e2e-test-app",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "dev": "concurrently \"next dev\"",
+    "build": "next build",
+    "start": "next start",
+    "clean": "npx rimraf node_modules pnpm-lock.yaml .next",
+    "start-local-supabase": "supabase init --force --workdir . && supabase start -o env",
+    "test:prod": "TEST_ENV=production playwright test",
+    "test:build": "pnpm install && pnpm start-local-supabase && pnpm build",
+    "test:assert": "pnpm test:prod"
+  },
+  "dependencies": {
+    "@next/font": "14.2.15",
+    "@sentry/nextjs": "latest || *",
+    "@supabase/auth-helpers-react": "0.5.0",
+    "@supabase/auth-ui-react": "0.4.7",
+    "@supabase/supabase-js": "2.49.1",
+    "@types/node": "18.14.0",
+    "@types/react": "18.0.28",
+    "@types/react-dom": "18.0.11",
+    "concurrently": "7.6.0",
+    "next": "14.2.25",
+    "react": "18.2.0",
+    "react-dom": "18.2.0",
+    "supabase": "2.19.7",
+    "typescript": "4.9.5"
+  },
+  "devDependencies": {
+    "@playwright/test": "~1.50.0",
+    "@sentry-internal/test-utils": "link:../../../test-utils",
+    "eslint": "8.34.0",
+    "eslint-config-next": "14.2.25"
+  },
+  "volta": {
+    "extends": "../../package.json"
+  }
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_app.tsx b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_app.tsx
new file mode 100644
index 000000000000..3405946d0a8d
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_app.tsx
@@ -0,0 +1,11 @@
+import { supabaseClient } from '@/lib/initSupabaseAnon'
+import { SessionContextProvider } from '@supabase/auth-helpers-react'
+import type { AppProps } from 'next/app'
+
+export default function App({ Component, pageProps }: AppProps) {
+  return (
+    <SessionContextProvider supabaseClient={supabaseClient}>
+      <Component {...pageProps} />
+    </SessionContextProvider>
+  )
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_document.tsx b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_document.tsx
new file mode 100644
index 000000000000..54e8bf3e2a29
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_document.tsx
@@ -0,0 +1,13 @@
+import { Html, Head, Main, NextScript } from 'next/document'
+
+export default function Document() {
+  return (
+    <Html lang="en">
+      <Head />
+      <body>
+        <Main />
+        <NextScript />
+      </body>
+    </Html>
+  )
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_error.jsx b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_error.jsx
new file mode 100644
index 000000000000..46a61d690c38
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/_error.jsx
@@ -0,0 +1,17 @@
+import * as Sentry from "@sentry/nextjs";
+import Error from "next/error";
+
+const CustomErrorComponent = (props) => {
+  return <Error statusCode={props.statusCode} />;
+};
+
+CustomErrorComponent.getInitialProps = async (contextData) => {
+  // In case this is running in a serverless function, await this in order to give Sentry
+  // time to send the error before the lambda exits
+  await Sentry.captureUnderscoreErrorException(contextData);
+
+  // This will contain the status code of the response
+  return Error.getInitialProps(contextData);
+};
+
+export default CustomErrorComponent;
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/add-todo-entry.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/add-todo-entry.ts
new file mode 100644
index 000000000000..6d49348cf886
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/add-todo-entry.ts
@@ -0,0 +1,46 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import type { NextApiRequest, NextApiResponse } from 'next';
+import { supabaseClient } from '@/lib/initSupabaseAdmin';
+
+type Data = {
+  data: any;
+  error: any;
+};
+
+async function login() {
+  const { data, error } = await supabaseClient.auth.signInWithPassword({
+    email: 'test@sentry.test',
+    password: 'sentry.test',
+  });
+
+  if (error) {
+    console.log('error', error);
+  }
+
+  return data;
+}
+
+async function addTodoEntry(userId?: string) {
+  const { error } = await supabaseClient.from('todos').insert({ task: 'test', user_id: userId }).select().single();
+
+  if (error) {
+    console.log('error', error);
+  }
+}
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
+  const { user } = await login();
+
+  await addTodoEntry(user?.id);
+
+  const { data, error } = await supabaseClient.from('todos').select('*');
+
+  if (error) {
+    console.log('error', error);
+  }
+
+  res.status(200).json({
+    data,
+    error,
+  });
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/create-test-user.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/create-test-user.ts
new file mode 100644
index 000000000000..996d3d0ffdb6
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/api/create-test-user.ts
@@ -0,0 +1,32 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import type { NextApiRequest, NextApiResponse } from 'next';
+import { supabaseClient } from '@/lib/initSupabaseAdmin';
+
+type Data = {
+  data: any;
+  error: any;
+};
+
+async function deleteExistingUsers() {
+  const { data: { users }, error } = await supabaseClient.auth.admin.listUsers()
+
+  for (const user of users) {
+    const { error } = await supabaseClient.auth.admin.deleteUser(user.id, true);
+    if (error) console.log('error', error);
+  }
+}
+
+export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
+  await deleteExistingUsers();
+
+  const { data, error } = await supabaseClient.auth.admin.createUser({
+    email: 'test@sentry.test',
+    password: 'sentry.test',
+    email_confirm: true,
+  });
+
+  res.status(200).json({
+    data,
+    error,
+   });
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/index.tsx b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/index.tsx
new file mode 100644
index 000000000000..e3b04bb22534
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/pages/index.tsx
@@ -0,0 +1,39 @@
+import Head from 'next/head';
+import { useSession, useSupabaseClient } from '@supabase/auth-helpers-react';
+import { Auth } from '@supabase/auth-ui-react';
+import TodoList from '@/components/TodoList';
+
+export default function Home() {
+  const session = useSession();
+  const supabase = useSupabaseClient();
+
+  return (
+    <>
+      <Head>
+        <title>Create Next App</title>
+        <meta name="description" />
+        <meta name="viewport" />
+      </Head>
+      <div>
+        {!session ? (
+          <div>
+            <span>Login</span>
+            <Auth supabaseClient={supabase} />
+          </div>
+        ) : (
+          <div>
+            <TodoList session={session} />
+            <button
+              onClick={async () => {
+                const { error } = await supabase.auth.signOut();
+                if (error) console.log('Error logging out:', error.message);
+              }}
+            >
+              Logout
+            </button>
+          </div>
+        )}
+      </div>
+    </>
+  );
+}
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/supabase-nextjs/playwright.config.mjs
new file mode 100644
index 000000000000..a35fe82a4001
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/playwright.config.mjs
@@ -0,0 +1,8 @@
+import { getPlaywrightConfig } from '@sentry-internal/test-utils';
+
+const config = getPlaywrightConfig({
+  startCommand: `pnpm dev`,
+  port: 3030,
+});
+
+export default config;
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.client.config.ts
new file mode 100644
index 000000000000..acd2f0768675
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.client.config.ts
@@ -0,0 +1,31 @@
+// This file configures the initialization of Sentry on the client.
+// The config you add here will be used whenever a users loads a page in their browser.
+// https://docs.sentry.io/platforms/javascript/guides/nextjs/
+
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  environment: 'qa', // dynamic sampling bias to keep transactions
+
+  // Add optional integrations for additional features
+  integrations: [
+    Sentry.replayIntegration(),
+  ],
+  tunnel: 'http://localhost:3031/', // proxy server
+
+  // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
+  tracesSampleRate: 1,
+
+  // Define how likely Replay events are sampled.
+  // This sets the sample rate to be 10%. You may want this to be 100% while
+  // in development and sample at a lower rate in production
+  replaysSessionSampleRate: 0.1,
+
+  // Define how likely Replay events are sampled when an error occurs.
+  replaysOnErrorSampleRate: 1.0,
+  transportOptions: {
+    // We expect the app to send a lot of events in a short time
+    bufferSize: 1000,
+  },
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.edge.config.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.edge.config.ts
new file mode 100644
index 000000000000..59ad9eb6befe
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.edge.config.ts
@@ -0,0 +1,17 @@
+// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).
+// The config you add here will be used whenever one of the edge features is loaded.
+// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.
+// https://docs.sentry.io/platforms/javascript/guides/nextjs/
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  environment: 'qa', // dynamic sampling bias to keep transactions
+  sendDefaultPii: true,
+  tracesSampleRate: 1,
+  tunnel: 'http://localhost:3031/', // proxy server
+  transportOptions: {
+    // We expect the app to send a lot of events in a short time
+    bufferSize: 1000,
+  },
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.server.config.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.server.config.ts
new file mode 100644
index 000000000000..aa1d2031926f
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.server.config.ts
@@ -0,0 +1,17 @@
+// This file configures the initialization of Sentry on the server.
+// The config you add here will be used whenever the server handles a request.
+// https://docs.sentry.io/platforms/javascript/guides/nextjs/
+
+import * as Sentry from "@sentry/nextjs";
+
+Sentry.init({
+  dsn: 'https://public@dsn.ingest.sentry.io/1337',
+  environment: 'qa', // dynamic sampling bias to keep transactions
+  tracesSampleRate: 1,
+  sendDefaultPii: true,
+  tunnel: 'http://localhost:3031/', // proxy server
+  transportOptions: {
+    // We expect the app to send a lot of events in a short time
+    bufferSize: 1000,
+  },
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/supabase-nextjs/start-event-proxy.mjs
new file mode 100644
index 000000000000..2f41cb42d4ee
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/start-event-proxy.mjs
@@ -0,0 +1,6 @@
+import { startEventProxyServer } from '@sentry-internal/test-utils';
+
+startEventProxyServer({
+  port: 3031,
+  proxyServerName: 'supabase-nextjs',
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/.gitignore b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/.gitignore
new file mode 100644
index 000000000000..a735017e0d2a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/.gitignore
@@ -0,0 +1,13 @@
+# Supabase
+.branches
+.temp
+.env
+
+# Supabase
+.branches
+.temp
+
+# dotenvx
+.env.keys
+.env.local
+.env.*.local
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/config.toml b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/config.toml
new file mode 100644
index 000000000000..35dcff35bec4
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/config.toml
@@ -0,0 +1,307 @@
+# For detailed configuration reference documentation, visit:
+# https://supabase.com/docs/guides/local-development/cli/config
+# A string used to distinguish different Supabase projects on the same host. Defaults to the
+# working directory name when running `supabase init`.
+project_id = "supabase-nextjs"
+
+[api]
+enabled = true
+# Port to use for the API URL.
+port = 54321
+# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
+# endpoints. `public` and `graphql_public` schemas are included by default.
+schemas = ["public", "graphql_public"]
+# Extra schemas to add to the search_path of every request.
+extra_search_path = ["public", "extensions"]
+# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
+# for accidental or malicious requests.
+max_rows = 1000
+
+[api.tls]
+# Enable HTTPS endpoints locally using a self-signed certificate.
+enabled = false
+
+[db]
+# Port to use for the local database URL.
+port = 54322
+# Port used by db diff command to initialize the shadow database.
+shadow_port = 54320
+# The database major version to use. This has to be the same as your remote database's. Run `SHOW
+# server_version;` on the remote database to check.
+major_version = 15
+
+[db.pooler]
+enabled = false
+# Port to use for the local connection pooler.
+port = 54329
+# Specifies when a server connection can be reused by other clients.
+# Configure one of the supported pooler modes: `transaction`, `session`.
+pool_mode = "transaction"
+# How many server connections to allow per user/database pair.
+default_pool_size = 20
+# Maximum number of client connections allowed.
+max_client_conn = 100
+
+# [db.vault]
+# secret_key = "env(SECRET_VALUE)"
+
+[db.migrations]
+# Specifies an ordered list of schema files that describe your database.
+# Supports glob patterns relative to supabase directory: "./schemas/*.sql"
+schema_paths = []
+
+[db.seed]
+# If enabled, seeds the database after migrations during a db reset.
+enabled = true
+# Specifies an ordered list of seed files to load during db reset.
+# Supports glob patterns relative to supabase directory: "./seeds/*.sql"
+sql_paths = ["./seed.sql"]
+
+[realtime]
+enabled = true
+# Bind realtime via either IPv4 or IPv6. (default: IPv4)
+# ip_version = "IPv6"
+# The maximum length in bytes of HTTP request headers. (default: 4096)
+# max_header_length = 4096
+
+[studio]
+enabled = true
+# Port to use for Supabase Studio.
+port = 54323
+# External URL of the API server that frontend connects to.
+api_url = "http://127.0.0.1"
+# OpenAI API Key to use for Supabase AI in the Supabase Studio.
+openai_api_key = "env(OPENAI_API_KEY)"
+
+# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
+# are monitored, and you can view the emails that would have been sent from the web interface.
+[inbucket]
+enabled = true
+# Port to use for the email testing server web interface.
+port = 54324
+# Uncomment to expose additional ports for testing user applications that send emails.
+# smtp_port = 54325
+# pop3_port = 54326
+# admin_email = "admin@email.com"
+# sender_name = "Admin"
+
+[storage]
+enabled = true
+# The maximum file size allowed (e.g. "5MB", "500KB").
+file_size_limit = "50MiB"
+
+# Image transformation API is available to Supabase Pro plan.
+# [storage.image_transformation]
+# enabled = true
+
+# Uncomment to configure local storage buckets
+# [storage.buckets.images]
+# public = false
+# file_size_limit = "50MiB"
+# allowed_mime_types = ["image/png", "image/jpeg"]
+# objects_path = "./images"
+
+[auth]
+enabled = true
+# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
+# in emails.
+site_url = "http://127.0.0.1:3000"
+# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
+additional_redirect_urls = ["https://127.0.0.1:3000"]
+# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
+jwt_expiry = 3600
+# If disabled, the refresh token will never expire.
+enable_refresh_token_rotation = true
+# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
+# Requires enable_refresh_token_rotation = true.
+refresh_token_reuse_interval = 10
+# Allow/disallow new user signups to your project.
+enable_signup = true
+# Allow/disallow anonymous sign-ins to your project.
+enable_anonymous_sign_ins = false
+# Allow/disallow testing manual linking of accounts
+enable_manual_linking = false
+# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more.
+minimum_password_length = 6
+# Passwords that do not meet the following requirements will be rejected as weak. Supported values
+# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols`
+password_requirements = ""
+
+[auth.rate_limit]
+# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled.
+email_sent = 2
+# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled.
+sms_sent = 30
+# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true.
+anonymous_users = 30
+# Number of sessions that can be refreshed in a 5 minute interval per IP address.
+token_refresh = 150
+# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users).
+sign_in_sign_ups = 30
+# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address.
+token_verifications = 30
+
+
+# Configure one of the supported captcha providers: `hcaptcha`, `turnstile`.
+# [auth.captcha]
+# enabled = true
+# provider = "hcaptcha"
+# secret = ""
+
+[auth.email]
+# Allow/disallow new user signups via email to your project.
+enable_signup = true
+# If enabled, a user will be required to confirm any email change on both the old, and new email
+# addresses. If disabled, only the new email is required to confirm.
+double_confirm_changes = true
+# If enabled, users need to confirm their email address before signing in.
+enable_confirmations = false
+# If enabled, users will need to reauthenticate or have logged in recently to change their password.
+secure_password_change = false
+# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.
+max_frequency = "1s"
+# Number of characters used in the email OTP.
+otp_length = 6
+# Number of seconds before the email OTP expires (defaults to 1 hour).
+otp_expiry = 3600
+
+# Use a production-ready SMTP server
+# [auth.email.smtp]
+# enabled = true
+# host = "smtp.sendgrid.net"
+# port = 587
+# user = "apikey"
+# pass = "env(SENDGRID_API_KEY)"
+# admin_email = "admin@email.com"
+# sender_name = "Admin"
+
+# Uncomment to customize email template
+# [auth.email.template.invite]
+# subject = "You have been invited"
+# content_path = "./supabase/templates/invite.html"
+
+[auth.sms]
+# Allow/disallow new user signups via SMS to your project.
+enable_signup = false
+# If enabled, users need to confirm their phone number before signing in.
+enable_confirmations = false
+# Template for sending OTP to users
+template = "Your code is {{ .Code }}"
+# Controls the minimum amount of time that must pass before sending another sms otp.
+max_frequency = "5s"
+
+# Use pre-defined map of phone number to OTP for testing.
+# [auth.sms.test_otp]
+# 4152127777 = "123456"
+
+# Configure logged in session timeouts.
+# [auth.sessions]
+# Force log out after the specified duration.
+# timebox = "24h"
+# Force log out if the user has been inactive longer than the specified duration.
+# inactivity_timeout = "8h"
+
+# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
+# [auth.hook.custom_access_token]
+# enabled = true
+# uri = "pg-functions://<database>/<schema>/<hook_name>"
+
+# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
+[auth.sms.twilio]
+enabled = false
+account_sid = ""
+message_service_sid = ""
+# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
+auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
+
+# Multi-factor-authentication is available to Supabase Pro plan.
+[auth.mfa]
+# Control how many MFA factors can be enrolled at once per user.
+max_enrolled_factors = 10
+
+# Control MFA via App Authenticator (TOTP)
+[auth.mfa.totp]
+enroll_enabled = false
+verify_enabled = false
+
+# Configure MFA via Phone Messaging
+[auth.mfa.phone]
+enroll_enabled = false
+verify_enabled = false
+otp_length = 6
+template = "Your code is {{ .Code }}"
+max_frequency = "5s"
+
+# Configure MFA via WebAuthn
+# [auth.mfa.web_authn]
+# enroll_enabled = true
+# verify_enabled = true
+
+# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
+# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
+# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
+[auth.external.apple]
+enabled = false
+client_id = ""
+# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
+secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
+# Overrides the default auth redirectUrl.
+redirect_uri = ""
+# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
+# or any other third-party OIDC providers.
+url = ""
+# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.
+skip_nonce_check = false
+
+# Use Firebase Auth as a third-party provider alongside Supabase Auth.
+[auth.third_party.firebase]
+enabled = false
+# project_id = "my-firebase-project"
+
+# Use Auth0 as a third-party provider alongside Supabase Auth.
+[auth.third_party.auth0]
+enabled = false
+# tenant = "my-auth0-tenant"
+# tenant_region = "us"
+
+# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth.
+[auth.third_party.aws_cognito]
+enabled = false
+# user_pool_id = "my-user-pool-id"
+# user_pool_region = "us-east-1"
+
+# Use Clerk as a third-party provider alongside Supabase Auth.
+[auth.third_party.clerk]
+enabled = false
+# Obtain from https://clerk.com/setup/supabase
+# domain = "example.clerk.accounts.dev"
+
+[edge_runtime]
+enabled = true
+# Configure one of the supported request policies: `oneshot`, `per_worker`.
+# Use `oneshot` for hot reload, or `per_worker` for load testing.
+policy = "oneshot"
+# Port to attach the Chrome inspector for debugging edge functions.
+inspector_port = 8083
+
+# [edge_runtime.secrets]
+# secret_key = "env(SECRET_VALUE)"
+
+[analytics]
+enabled = true
+port = 54327
+# Configure one of the supported backends: `postgres`, `bigquery`.
+backend = "postgres"
+
+# Experimental features may be deprecated any time
+[experimental]
+# Configures Postgres storage engine to use OrioleDB (S3)
+orioledb_version = ""
+# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
+s3_host = "env(S3_HOST)"
+# Configures S3 bucket region, eg. us-east-1
+s3_region = "env(S3_REGION)"
+# Configures AWS_ACCESS_KEY_ID for S3 bucket
+s3_access_key = "env(S3_ACCESS_KEY)"
+# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
+s3_secret_key = "env(S3_SECRET_KEY)"
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/migrations/20230712094349_init.sql b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/migrations/20230712094349_init.sql
new file mode 100644
index 000000000000..1b1a98ace2e4
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/supabase/migrations/20230712094349_init.sql
@@ -0,0 +1,16 @@
+create table todos (
+  id bigint generated by default as identity primary key,
+  user_id uuid references auth.users not null,
+  task text check (char_length(task) > 3),
+  is_complete boolean default false,
+  inserted_at timestamp with time zone default timezone('utc'::text, now()) not null
+);
+alter table todos enable row level security;
+create policy "Individuals can create todos." on todos for
+    insert with check (auth.uid() = user_id);
+create policy "Individuals can view their own todos. " on todos for
+    select using (auth.uid() = user_id);
+create policy "Individuals can update their own todos." on todos for
+    update using (auth.uid() = user_id);
+create policy "Individuals can delete their own todos." on todos for
+    delete using (auth.uid() = user_id);
\ No newline at end of file
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/client.performance.test.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/client.performance.test.ts
new file mode 100644
index 000000000000..529412e54b2f
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/client.performance.test.ts
@@ -0,0 +1,70 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Sends client-side Supabase db-operation spans and breadcrumbs to Sentry', async ({ page, baseURL }) => {
+  // Create test user
+  await fetch(`${baseURL}/api/create-test-user`);
+
+  const pageloadTransactionPromise = waitForTransaction('supabase-nextjs', transactionEvent => {
+    return transactionEvent?.contexts?.trace?.op === 'pageload' && transactionEvent?.transaction === '/';
+  });
+
+  await page.goto('/');
+
+  // Fill in login credentials
+  await page.locator('input[name=email]').fill('test@sentry.test');
+  await page.locator('input[name=password]').fill('sentry.test');
+  await page.locator('button[type=submit]').click();
+
+  // Wait for login to complete
+  await page.waitForSelector('button:has-text("Add")');
+
+  // Add a new todo entry
+  await page.locator('input[id=new-task-text]').fill('test');
+  await page.locator('button[id=add-task]').click();
+
+  const transactionEvent = await pageloadTransactionPromise;
+
+  expect(transactionEvent.spans).toContainEqual(
+    expect.objectContaining({
+      description: 'from(todos)',
+      op: 'db.select',
+      parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
+      span_id: expect.stringMatching(/[a-f0-9]{16}/),
+      start_timestamp: expect.any(Number),
+      status: 'ok',
+      timestamp: expect.any(Number),
+      trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+      origin: 'auto.db.supabase',
+    }),
+  );
+
+  expect(transactionEvent.spans).toContainEqual({
+    data: expect.any(Object),
+    description: 'from(todos)',
+    op: 'db.insert',
+    parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
+    span_id: expect.stringMatching(/[a-f0-9]{16}/),
+    start_timestamp: expect.any(Number),
+    status: 'ok',
+    timestamp: expect.any(Number),
+    trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+    origin: 'auto.db.supabase',
+  });
+
+  expect(transactionEvent.breadcrumbs).toContainEqual({
+    timestamp: expect.any(Number),
+    type: 'supabase',
+    category: 'db.select',
+    message: 'from(todos)',
+    data: expect.any(Object),
+  });
+
+  expect(transactionEvent.breadcrumbs).toContainEqual({
+    timestamp: expect.any(Number),
+    type: 'supabase',
+    category: 'db.insert',
+    message: 'from(todos)',
+    data: expect.any(Object),
+  });
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/server.performance.test.ts b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/server.performance.test.ts
new file mode 100644
index 000000000000..887d87e6ce8f
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tests/server.performance.test.ts
@@ -0,0 +1,57 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Sends server-side Supabase db-operation spans and breadcrumbs to Sentry', async ({ page, baseURL }) => {
+  // Create test user
+  await fetch(`${baseURL}/api/create-test-user`);
+
+  const httpTransactionPromise = waitForTransaction('supabase-nextjs', transactionEvent => {
+    return transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /api/add-todo-entry';
+  });
+
+  await fetch(`${baseURL}/api/add-todo-entry`);
+  const transactionEvent = await httpTransactionPromise;
+
+  expect(transactionEvent.spans).toContainEqual(
+    expect.objectContaining({
+      description: 'from(todos)',
+      op: 'db.select',
+      parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
+      span_id: expect.stringMatching(/[a-f0-9]{16}/),
+      start_timestamp: expect.any(Number),
+      status: 'ok',
+      timestamp: expect.any(Number),
+      trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+      origin: 'auto.db.supabase',
+    }),
+  );
+
+  expect(transactionEvent.spans).toContainEqual({
+    data: expect.any(Object),
+    description: 'from(todos)',
+    op: 'db.insert',
+    parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
+    span_id: expect.stringMatching(/[a-f0-9]{16}/),
+    start_timestamp: expect.any(Number),
+    status: 'ok',
+    timestamp: expect.any(Number),
+    trace_id: expect.stringMatching(/[a-f0-9]{32}/),
+    origin: 'auto.db.supabase',
+  });
+
+  expect(transactionEvent.breadcrumbs).toContainEqual({
+    timestamp: expect.any(Number),
+    type: 'supabase',
+    category: 'db.select',
+    message: 'from(todos)',
+    data: expect.any(Object),
+  });
+
+  expect(transactionEvent.breadcrumbs).toContainEqual({
+    timestamp: expect.any(Number),
+    type: 'supabase',
+    category: 'db.insert',
+    message: 'from(todos)',
+    data: expect.any(Object),
+  });
+});
diff --git a/dev-packages/e2e-tests/test-applications/supabase-nextjs/tsconfig.json b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tsconfig.json
new file mode 100644
index 000000000000..f4ab65fd2ebf
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/supabase-nextjs/tsconfig.json
@@ -0,0 +1,24 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "lib": ["dom", "dom.iterable", "esnext"],
+    "allowJs": true,
+    "skipLibCheck": true,
+    "strict": true,
+    "forceConsistentCasingInFileNames": true,
+    "noEmit": true,
+    "esModuleInterop": true,
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "jsx": "preserve",
+    "incremental": true,
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./*"]
+    }
+  },
+  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+  "exclude": ["node_modules"]
+}
diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts
index 6467affd841c..f86e85e9f675 100644
--- a/packages/astro/src/index.server.ts
+++ b/packages/astro/src/index.server.ts
@@ -125,6 +125,7 @@ export {
   withIsolationScope,
   withMonitor,
   withScope,
+  supabaseIntegration,
   zodErrorsIntegration,
   profiler,
   logger,
diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts
index 473b87c793d9..4c7569bb7dcc 100644
--- a/packages/aws-serverless/src/index.ts
+++ b/packages/aws-serverless/src/index.ts
@@ -109,6 +109,7 @@ export {
   spanToBaggageHeader,
   trpcMiddleware,
   updateSpanName,
+  supabaseIntegration,
   zodErrorsIntegration,
   profiler,
   amqplibIntegration,
diff --git a/packages/browser/src/index.bundle.tracing.replay.feedback.ts b/packages/browser/src/index.bundle.tracing.replay.feedback.ts
index a16f07bafaf2..fab33b2726f2 100644
--- a/packages/browser/src/index.bundle.tracing.replay.feedback.ts
+++ b/packages/browser/src/index.bundle.tracing.replay.feedback.ts
@@ -15,6 +15,7 @@ export {
   getSpanDescendants,
   setMeasurement,
   captureFeedback,
+  supabaseIntegration,
 } from '@sentry/core';
 
 export {
diff --git a/packages/browser/src/index.bundle.tracing.replay.ts b/packages/browser/src/index.bundle.tracing.replay.ts
index 37f0da34ae25..9cadf4cb42f7 100644
--- a/packages/browser/src/index.bundle.tracing.replay.ts
+++ b/packages/browser/src/index.bundle.tracing.replay.ts
@@ -14,6 +14,7 @@ export {
   withActiveSpan,
   getSpanDescendants,
   setMeasurement,
+  supabaseIntegration,
 } from '@sentry/core';
 
 export {
diff --git a/packages/browser/src/index.bundle.tracing.ts b/packages/browser/src/index.bundle.tracing.ts
index d540ff0bd6f9..06d533b51e0e 100644
--- a/packages/browser/src/index.bundle.tracing.ts
+++ b/packages/browser/src/index.bundle.tracing.ts
@@ -15,6 +15,7 @@ export {
   withActiveSpan,
   getSpanDescendants,
   setMeasurement,
+  supabaseIntegration,
 } from '@sentry/core';
 
 export {
diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts
index 9103bbab99b5..c5f4165161be 100644
--- a/packages/browser/src/index.ts
+++ b/packages/browser/src/index.ts
@@ -58,6 +58,7 @@ export {
   setHttpStatus,
   makeMultiplexedTransport,
   moduleMetadataIntegration,
+  supabaseIntegration,
   zodErrorsIntegration,
   thirdPartyErrorFilterIntegration,
 } from '@sentry/core';
diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts
index c2aff0f1ca52..6804de816e8d 100644
--- a/packages/bun/src/index.ts
+++ b/packages/bun/src/index.ts
@@ -128,6 +128,7 @@ export {
   spanToBaggageHeader,
   trpcMiddleware,
   updateSpanName,
+  supabaseIntegration,
   zodErrorsIntegration,
   profiler,
   amqplibIntegration,
diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts
index 05fd40fb4c96..08feff91086a 100644
--- a/packages/cloudflare/src/index.ts
+++ b/packages/cloudflare/src/index.ts
@@ -75,6 +75,7 @@ export {
   rewriteFramesIntegration,
   captureConsoleIntegration,
   moduleMetadataIntegration,
+  supabaseIntegration,
   zodErrorsIntegration,
   SEMANTIC_ATTRIBUTE_SENTRY_OP,
   SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 5f5c4e6768b7..f0491b6c54a7 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -106,6 +106,7 @@ export { captureConsoleIntegration } from './integrations/captureconsole';
 export { dedupeIntegration } from './integrations/dedupe';
 export { extraErrorDataIntegration } from './integrations/extraerrordata';
 export { rewriteFramesIntegration } from './integrations/rewriteframes';
+export { supabaseIntegration } from './integrations/supabase';
 export { zodErrorsIntegration } from './integrations/zoderrors';
 export { thirdPartyErrorFilterIntegration } from './integrations/third-party-errors-filter';
 export { profiler } from './profiling';
diff --git a/packages/core/src/integrations/supabase.ts b/packages/core/src/integrations/supabase.ts
new file mode 100644
index 000000000000..9ac1ea7a0d5d
--- /dev/null
+++ b/packages/core/src/integrations/supabase.ts
@@ -0,0 +1,562 @@
+// Based on Kamil Ogórek's work on:
+// https://github.com/supabase-community/sentry-integration-js
+
+/* eslint-disable max-lines */
+import { logger, isPlainObject } from '../utils-hoist';
+
+import type { IntegrationFn } from '../types-hoist';
+import { setHttpStatus, startInactiveSpan, startSpan } from '../tracing';
+import { addBreadcrumb } from '../breadcrumbs';
+import { defineIntegration } from '../integration';
+import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes';
+import { captureException } from '../exports';
+import { SPAN_STATUS_ERROR, SPAN_STATUS_OK } from '../tracing';
+
+export interface SupabaseClientConstructor {
+  prototype: {
+    from: (table: string) => PostgrestQueryBuilder;
+    schema: (schema: string) => { rpc: (...args: unknown[]) => Promise<unknown> };
+  };
+  rpc: (fn: string, params: Record<string, unknown>) => Promise<unknown>;
+}
+
+const AUTH_OPERATIONS_TO_INSTRUMENT = [
+  'reauthenticate',
+  'signInAnonymously',
+  'signInWithOAuth',
+  'signInWithIdToken',
+  'signInWithOtp',
+  'signInWithPassword',
+  'signInWithSSO',
+  'signOut',
+  'signUp',
+  'verifyOtp',
+];
+
+const AUTH_ADMIN_OPERATIONS_TO_INSTRUMENT = [
+  'createUser',
+  'deleteUser',
+  'listUsers',
+  'getUserById',
+  'updateUserById',
+  'inviteUserByEmail',
+];
+
+export const FILTER_MAPPINGS = {
+  eq: 'eq',
+  neq: 'neq',
+  gt: 'gt',
+  gte: 'gte',
+  lt: 'lt',
+  lte: 'lte',
+  like: 'like',
+  'like(all)': 'likeAllOf',
+  'like(any)': 'likeAnyOf',
+  ilike: 'ilike',
+  'ilike(all)': 'ilikeAllOf',
+  'ilike(any)': 'ilikeAnyOf',
+  is: 'is',
+  in: 'in',
+  cs: 'contains',
+  cd: 'containedBy',
+  sr: 'rangeGt',
+  nxl: 'rangeGte',
+  sl: 'rangeLt',
+  nxr: 'rangeLte',
+  adj: 'rangeAdjacent',
+  ov: 'overlaps',
+  fts: '',
+  plfts: 'plain',
+  phfts: 'phrase',
+  wfts: 'websearch',
+  not: 'not',
+};
+
+export const AVAILABLE_OPERATIONS = ['select', 'insert', 'upsert', 'update', 'delete'];
+
+type AuthOperationFn = (...args: unknown[]) => Promise<unknown>;
+type AuthOperationName = (typeof AUTH_OPERATIONS_TO_INSTRUMENT)[number];
+type AuthAdminOperationName = (typeof AUTH_ADMIN_OPERATIONS_TO_INSTRUMENT)[number];
+type PostgrestQueryOperationName = (typeof AVAILABLE_OPERATIONS)[number];
+type PostgrestQueryOperationFn = (...args: unknown[]) => PostgrestFilterBuilder;
+
+export interface SupabaseClientInstance {
+  auth: {
+    admin: Record<AuthAdminOperationName, AuthOperationFn>;
+  } & Record<AuthOperationName, AuthOperationFn>;
+}
+
+export interface PostgrestQueryBuilder {
+  [key: PostgrestQueryOperationName]: PostgrestQueryOperationFn;
+}
+
+export interface PostgrestFilterBuilder {
+  method: string;
+  headers: Record<string, string>;
+  url: URL;
+  schema: string;
+  body: any;
+}
+
+export interface SupabaseResponse {
+  status?: number;
+  error?: {
+    message: string;
+    code?: string;
+    details?: unknown;
+  };
+}
+
+export interface SupabaseError extends Error {
+  code?: string;
+  details?: unknown;
+}
+
+export interface SupabaseBreadcrumb {
+  type: string;
+  category: string;
+  message: string;
+  data?: {
+    query?: string[];
+    body?: Record<string, unknown>;
+  };
+}
+
+export interface PostgrestProtoThenable {
+  then: <T>(
+    onfulfilled?: ((value: T) => T | PromiseLike<T>) | null,
+    onrejected?: ((reason: any) => T | PromiseLike<T>) | null,
+  ) => Promise<T>;
+}
+
+const instrumented = new Map();
+
+/**
+ * Extracts the database operation type from the HTTP method and headers
+ * @param method - The HTTP method of the request
+ * @param headers - The request headers
+ * @returns The database operation type ('select', 'insert', 'upsert', 'update', or 'delete')
+ */
+export function extractOperation(method: string, headers: Record<string, string> = {}): string {
+  switch (method) {
+    case 'GET': {
+      return 'select';
+    }
+    case 'POST': {
+      if (headers['Prefer']?.includes('resolution=')) {
+        return 'upsert';
+      } else {
+        return 'insert';
+      }
+    }
+    case 'PATCH': {
+      return 'update';
+    }
+    case 'DELETE': {
+      return 'delete';
+    }
+    default: {
+      return '<unknown-op>';
+    }
+  }
+}
+
+/**
+ * Translates Supabase filter parameters into readable method names for tracing
+ * @param key - The filter key from the URL search parameters
+ * @param query - The filter value from the URL search parameters
+ * @returns A string representation of the filter as a method call
+ */
+export function translateFiltersIntoMethods(key: string, query: string): string {
+  if (query === '' || query === '*') {
+    return 'select(*)';
+  }
+
+  if (key === 'select') {
+    return `select(${query})`;
+  }
+
+  if (key === 'or' || key.endsWith('.or')) {
+    return `${key}${query}`;
+  }
+
+  const [filter, ...value] = query.split('.');
+
+  let method;
+  // Handle optional `configPart` of the filter
+  if (filter?.startsWith('fts')) {
+    method = 'textSearch';
+  } else if (filter?.startsWith('plfts')) {
+    method = 'textSearch[plain]';
+  } else if (filter?.startsWith('phfts')) {
+    method = 'textSearch[phrase]';
+  } else if (filter?.startsWith('wfts')) {
+    method = 'textSearch[websearch]';
+  } else {
+    method = (filter && FILTER_MAPPINGS[filter as keyof typeof FILTER_MAPPINGS]) || 'filter';
+  }
+
+  return `${method}(${key}, ${value.join('.')})`;
+}
+
+function instrumentRpcReturnedFromSchemaCall(SupabaseClient: unknown): void {
+  (SupabaseClient as unknown as SupabaseClientConstructor).prototype.schema = new Proxy(
+    (SupabaseClient as unknown as SupabaseClientConstructor).prototype.schema,
+    {
+      apply(target, thisArg, argumentsList) {
+        const rv = Reflect.apply(target, thisArg, argumentsList);
+
+        return instrumentRpc(rv);
+      },
+    },
+  );
+}
+
+function instrumentRpc(SupabaseClient: unknown): unknown {
+  (SupabaseClient as unknown as SupabaseClientConstructor).rpc = new Proxy(
+    (SupabaseClient as unknown as SupabaseClientConstructor).rpc,
+    {
+      apply(target, thisArg, argumentsList) {
+        const isProducerSpan = argumentsList[0] === 'enqueue';
+        const isConsumerSpan = argumentsList[0] === 'dequeue';
+
+        const maybeQueueParams = argumentsList[1];
+
+        // If the second argument is not an object, it's not a queue operation
+        if (!isPlainObject(maybeQueueParams)) {
+          return Reflect.apply(target, thisArg, argumentsList);
+        }
+
+        const msg = maybeQueueParams?.msg as { title: string };
+
+        const messageId = msg?.title;
+        const queueName = maybeQueueParams?.queue_name as string;
+
+        const op = isProducerSpan ? 'queue.publish' : isConsumerSpan ? 'queue.process' : '';
+
+        // If the operation is not a queue operation, return the original function
+        if (!op) {
+          return Reflect.apply(target, thisArg, argumentsList);
+        }
+
+        return startSpan(
+          {
+            name: 'supabase.db.rpc',
+            attributes: {
+              [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.supabase',
+              [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,
+            },
+          },
+          async span => {
+            return (Reflect.apply(target, thisArg, argumentsList) as Promise<unknown>).then((res: unknown) => {
+              if (messageId) {
+                span.setAttribute('messaging.message.id', messageId);
+              }
+
+              if (queueName) {
+                span.setAttribute('messaging.destination.name', queueName);
+              }
+
+              span.end();
+              return res;
+            });
+          },
+        );
+      },
+    },
+  );
+
+  return SupabaseClient;
+}
+
+function instrumentAuthOperation(operation: AuthOperationFn, isAdmin = false): AuthOperationFn {
+  return new Proxy(operation, {
+    apply(target, thisArg, argumentsList) {
+      return startSpan(
+        {
+          name: operation.name,
+          attributes: {
+            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.supabase',
+            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `db.supabase.auth.${isAdmin ? 'admin.' : ''}${operation.name}`,
+          },
+        },
+        async span => {
+          return Reflect.apply(target, thisArg, argumentsList)
+            .then((res: unknown) => {
+              if (res && typeof res === 'object' && 'error' in res && res.error) {
+                span.setStatus({ code: SPAN_STATUS_ERROR });
+
+                captureException(res.error, {
+                  mechanism: {
+                    handled: false,
+                  },
+                });
+              } else {
+                span.setStatus({ code: SPAN_STATUS_OK });
+              }
+
+              span.end();
+              return res;
+            })
+            .catch((err: unknown) => {
+              span.setStatus({ code: SPAN_STATUS_ERROR });
+              span.end();
+
+              captureException(err, {
+                mechanism: {
+                  handled: false,
+                },
+              });
+
+              throw err;
+            });
+        },
+      );
+    },
+  });
+}
+
+function instrumentSupabaseAuthClient(supabaseClientInstance: SupabaseClientInstance): void {
+  const auth = supabaseClientInstance.auth;
+
+  if (!auth) {
+    return;
+  }
+
+  AUTH_OPERATIONS_TO_INSTRUMENT.forEach((operation: AuthOperationName) => {
+    const authOperation = auth[operation];
+    if (typeof authOperation === 'function') {
+      auth[operation] = instrumentAuthOperation(authOperation);
+    }
+  });
+
+  AUTH_ADMIN_OPERATIONS_TO_INSTRUMENT.forEach((operation: AuthAdminOperationName) => {
+    const authAdminOperation = auth.admin[operation];
+    if (typeof authAdminOperation === 'function') {
+      auth.admin[operation] = instrumentAuthOperation(authAdminOperation);
+    }
+  });
+}
+
+function instrumentSupabaseClientConstructor(SupabaseClientConstructor: unknown): void {
+  if (instrumented.has(SupabaseClientConstructor)) {
+    return;
+  }
+
+  (SupabaseClientConstructor as unknown as SupabaseClientConstructor).prototype.from = new Proxy(
+    (SupabaseClientConstructor as unknown as SupabaseClientConstructor).prototype.from,
+    {
+      apply(target, thisArg, argumentsList) {
+        const rv = Reflect.apply(target, thisArg, argumentsList);
+        const PostgrestQueryBuilder = (rv as PostgrestQueryBuilder).constructor;
+
+        instrumentPostgrestQueryBuilder(PostgrestQueryBuilder as unknown as new () => PostgrestQueryBuilder);
+
+        return rv;
+      },
+    },
+  );
+}
+
+// This is the only "instrumented" part of the SDK. The rest of instrumentation
+// methods are only used as a mean to get to the `PostgrestFilterBuilder` constructor itself.
+function instrumentPostgrestFilterBuilder(PostgrestFilterBuilder: PostgrestFilterBuilder['constructor']): void {
+  if (instrumented.has(PostgrestFilterBuilder)) {
+    return;
+  }
+
+  instrumented.set(PostgrestFilterBuilder, {
+    then: (PostgrestFilterBuilder.prototype as unknown as PostgrestProtoThenable).then,
+  });
+
+  (PostgrestFilterBuilder.prototype as unknown as PostgrestProtoThenable).then = new Proxy(
+    (PostgrestFilterBuilder.prototype as unknown as PostgrestProtoThenable).then,
+    {
+      apply(target, thisArg, argumentsList) {
+        const operations = AVAILABLE_OPERATIONS;
+        const typedThis = thisArg as PostgrestFilterBuilder;
+        const operation = extractOperation(typedThis.method, typedThis.headers);
+
+        if (!operations.includes(operation)) {
+          return Reflect.apply(target, thisArg, argumentsList);
+        }
+
+        if (!typedThis?.url?.pathname || typeof typedThis.url.pathname !== 'string') {
+          return Reflect.apply(target, thisArg, argumentsList);
+        }
+
+        const pathParts = typedThis.url.pathname.split('/');
+        const table = pathParts.length > 0 ? pathParts[pathParts.length - 1] : '';
+        const description = `from(${table})`;
+
+        const query: string[] = [];
+        for (const [key, value] of typedThis.url.searchParams.entries()) {
+          // It's possible to have multiple entries for the same key, eg. `id=eq.7&id=eq.3`,
+          // so we need to use array instead of object to collect them.
+          query.push(translateFiltersIntoMethods(key, value));
+        }
+
+        const body: Record<string, unknown> = {};
+        if (isPlainObject(typedThis.body)) {
+          for (const [key, value] of Object.entries(typedThis.body)) {
+            body[key] = value;
+          }
+        }
+
+        const attributes: Record<string, any> = {
+          'db.table': table,
+          'db.schema': typedThis.schema,
+          'db.url': typedThis.url.origin,
+          'db.sdk': typedThis.headers['X-Client-Info'],
+          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.supabase',
+          [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `db.${operation}`,
+        };
+
+        if (query.length) {
+          attributes['db.query'] = query;
+        }
+
+        if (Object.keys(body).length) {
+          attributes['db.body'] = body;
+        }
+
+        const span = startInactiveSpan({
+          name: description,
+          attributes,
+        });
+
+        return (Reflect.apply(target, thisArg, []) as Promise<SupabaseResponse>)
+          .then(
+            (res: SupabaseResponse) => {
+              if (span) {
+                if (res && typeof res === 'object' && 'status' in res) {
+                  setHttpStatus(span, res.status || 500);
+                }
+                span.end();
+              }
+
+              if (res.error) {
+                const err = new Error(res.error.message) as SupabaseError;
+                if (res.error.code) {
+                  err.code = res.error.code;
+                }
+                if (res.error.details) {
+                  err.details = res.error.details;
+                }
+
+                const supabaseContext: Record<string, unknown> = {};
+                if (query.length) {
+                  supabaseContext.query = query;
+                }
+                if (Object.keys(body).length) {
+                  supabaseContext.body = body;
+                }
+
+                captureException(err, {
+                  contexts: {
+                    supabase: supabaseContext,
+                  },
+                });
+              }
+
+              const breadcrumb: SupabaseBreadcrumb = {
+                type: 'supabase',
+                category: `db.${operation}`,
+                message: description,
+              };
+
+              const data: Record<string, unknown> = {};
+
+              if (query.length) {
+                data.query = query;
+              }
+
+              if (Object.keys(body).length) {
+                data.body = body;
+              }
+
+              if (Object.keys(data).length) {
+                breadcrumb.data = data;
+              }
+
+              addBreadcrumb(breadcrumb);
+
+              return res;
+            },
+            (err: Error) => {
+              if (span) {
+                setHttpStatus(span, 500);
+                span.end();
+              }
+              throw err;
+            },
+          )
+          .then(...argumentsList);
+      },
+    },
+  );
+}
+
+function instrumentPostgrestQueryBuilder(PostgrestQueryBuilder: new () => PostgrestQueryBuilder): void {
+  if (instrumented.has(PostgrestQueryBuilder)) {
+    return;
+  }
+
+  // We need to wrap _all_ operations despite them sharing the same `PostgrestFilterBuilder`
+  // constructor, as we don't know which method will be called first, an we don't want to miss any calls.
+  for (const operation of AVAILABLE_OPERATIONS) {
+    instrumented.set(PostgrestQueryBuilder, {
+      [operation]: (PostgrestQueryBuilder.prototype as Record<string, unknown>)[
+        operation as 'select' | 'insert' | 'upsert' | 'update' | 'delete'
+      ] as (...args: unknown[]) => PostgrestFilterBuilder,
+    });
+
+    type PostgrestOperation = keyof Pick<PostgrestQueryBuilder, 'select' | 'insert' | 'upsert' | 'update' | 'delete'>;
+    (PostgrestQueryBuilder.prototype as Record<string, any>)[operation as PostgrestOperation] = new Proxy(
+      (PostgrestQueryBuilder.prototype as Record<string, any>)[operation as PostgrestOperation],
+      {
+        apply(target, thisArg, argumentsList) {
+          const rv = Reflect.apply(target, thisArg, argumentsList);
+          const PostgrestFilterBuilder = (rv as PostgrestFilterBuilder).constructor;
+
+          logger.log(`Instrumenting ${operation} operation's PostgrestFilterBuilder`);
+
+          instrumentPostgrestFilterBuilder(PostgrestFilterBuilder);
+
+          return rv;
+        },
+      },
+    );
+  }
+}
+
+const instrumentSupabase = (supabaseClientInstance: unknown): void => {
+  if (!supabaseClientInstance) {
+    throw new Error('Supabase client instance is not available.');
+  }
+  const SupabaseClientConstructor =
+    supabaseClientInstance.constructor === Function ? supabaseClientInstance : supabaseClientInstance.constructor;
+
+  instrumentSupabaseClientConstructor(SupabaseClientConstructor);
+  instrumentRpcReturnedFromSchemaCall(SupabaseClientConstructor);
+  instrumentRpc(supabaseClientInstance as SupabaseClientInstance);
+  instrumentSupabaseAuthClient(supabaseClientInstance as SupabaseClientInstance);
+};
+
+const INTEGRATION_NAME = 'Supabase';
+
+const _supabaseIntegration = (supabaseClient => {
+  return {
+    name: INTEGRATION_NAME,
+    setupOnce() {
+      instrumentSupabase(supabaseClient);
+    },
+  };
+}) satisfies IntegrationFn;
+
+export const supabaseIntegration = defineIntegration((supabaseClient: unknown) => {
+  return {
+    ..._supabaseIntegration(supabaseClient),
+    name: INTEGRATION_NAME,
+  };
+}) satisfies IntegrationFn;
diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts
index a906197b40c2..b25d810cd3c8 100644
--- a/packages/deno/src/index.ts
+++ b/packages/deno/src/index.ts
@@ -71,6 +71,7 @@ export {
   dedupeIntegration,
   extraErrorDataIntegration,
   rewriteFramesIntegration,
+  supabaseIntegration,
   zodErrorsIntegration,
   SEMANTIC_ATTRIBUTE_SENTRY_OP,
   SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
diff --git a/packages/google-cloud-serverless/src/index.ts b/packages/google-cloud-serverless/src/index.ts
index 83a18f62c6df..4cd74254a502 100644
--- a/packages/google-cloud-serverless/src/index.ts
+++ b/packages/google-cloud-serverless/src/index.ts
@@ -108,6 +108,7 @@ export {
   spanToBaggageHeader,
   trpcMiddleware,
   updateSpanName,
+  supabaseIntegration,
   zodErrorsIntegration,
   profiler,
   amqplibIntegration,
diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts
index decfbd578c68..2aad43fa06e8 100644
--- a/packages/node/src/index.ts
+++ b/packages/node/src/index.ts
@@ -128,6 +128,7 @@ export {
   spanToBaggageHeader,
   trpcMiddleware,
   updateSpanName,
+  supabaseIntegration,
   zodErrorsIntegration,
   profiler,
 } from '@sentry/core';
diff --git a/packages/remix/src/cloudflare/index.ts b/packages/remix/src/cloudflare/index.ts
index 5d15be8edee7..8093088a0171 100644
--- a/packages/remix/src/cloudflare/index.ts
+++ b/packages/remix/src/cloudflare/index.ts
@@ -95,6 +95,7 @@ export {
   rewriteFramesIntegration,
   captureConsoleIntegration,
   moduleMetadataIntegration,
+  supabaseIntegration,
   zodErrorsIntegration,
   SEMANTIC_ATTRIBUTE_SENTRY_OP,
   SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
diff --git a/packages/remix/src/server/index.ts b/packages/remix/src/server/index.ts
index 7809455ce3fa..a8fe49dea42b 100644
--- a/packages/remix/src/server/index.ts
+++ b/packages/remix/src/server/index.ts
@@ -111,6 +111,7 @@ export {
   withIsolationScope,
   withMonitor,
   withScope,
+  supabaseIntegration,
   zodErrorsIntegration,
   logger,
 } from '@sentry/node';
diff --git a/packages/solidstart/src/server/index.ts b/packages/solidstart/src/server/index.ts
index a36b7fbfaad1..127804e8f5eb 100644
--- a/packages/solidstart/src/server/index.ts
+++ b/packages/solidstart/src/server/index.ts
@@ -114,6 +114,7 @@ export {
   withIsolationScope,
   withMonitor,
   withScope,
+  supabaseIntegration,
   zodErrorsIntegration,
   logger,
 } from '@sentry/node';
diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts
index 9df3ddd688c8..a14849d64585 100644
--- a/packages/sveltekit/src/server/index.ts
+++ b/packages/sveltekit/src/server/index.ts
@@ -116,6 +116,7 @@ export {
   withIsolationScope,
   withMonitor,
   withScope,
+  supabaseIntegration,
   zodErrorsIntegration,
   logger,
 } from '@sentry/node';
diff --git a/packages/sveltekit/src/worker/index.ts b/packages/sveltekit/src/worker/index.ts
index 8e0e549440ca..ed5263ac4897 100644
--- a/packages/sveltekit/src/worker/index.ts
+++ b/packages/sveltekit/src/worker/index.ts
@@ -78,6 +78,7 @@ export {
   withIsolationScope,
   withMonitor,
   withScope,
+  supabaseIntegration,
   zodErrorsIntegration,
 } from '@sentry/cloudflare';
 
diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts
index eb6429c441fa..20645293a359 100644
--- a/packages/vercel-edge/src/index.ts
+++ b/packages/vercel-edge/src/index.ts
@@ -75,6 +75,7 @@ export {
   rewriteFramesIntegration,
   captureConsoleIntegration,
   moduleMetadataIntegration,
+  supabaseIntegration,
   zodErrorsIntegration,
   SEMANTIC_ATTRIBUTE_SENTRY_OP,
   SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
diff --git a/yarn.lock b/yarn.lock
index 27c0b61bb063..841e1e278651 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7210,6 +7210,63 @@
   dependencies:
     "@testing-library/dom" "^9.3.1"
 
+"@supabase/auth-js@2.69.1":
+  version "2.69.1"
+  resolved "https://registry.yarnpkg.com/@supabase/auth-js/-/auth-js-2.69.1.tgz#fcf310d24dfab823ffbf22191e6ceaef933360d8"
+  integrity sha512-FILtt5WjCNzmReeRLq5wRs3iShwmnWgBvxHfqapC/VoljJl+W8hDAyFmf1NVw3zH+ZjZ05AKxiKxVeb0HNWRMQ==
+  dependencies:
+    "@supabase/node-fetch" "^2.6.14"
+
+"@supabase/functions-js@2.4.4":
+  version "2.4.4"
+  resolved "https://registry.yarnpkg.com/@supabase/functions-js/-/functions-js-2.4.4.tgz#45fcd94d546bdfa66d01f93a796ca0304ec154b8"
+  integrity sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==
+  dependencies:
+    "@supabase/node-fetch" "^2.6.14"
+
+"@supabase/node-fetch@2.6.15", "@supabase/node-fetch@^2.6.14":
+  version "2.6.15"
+  resolved "https://registry.yarnpkg.com/@supabase/node-fetch/-/node-fetch-2.6.15.tgz#731271430e276983191930816303c44159e7226c"
+  integrity sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==
+  dependencies:
+    whatwg-url "^5.0.0"
+
+"@supabase/postgrest-js@1.19.2":
+  version "1.19.2"
+  resolved "https://registry.yarnpkg.com/@supabase/postgrest-js/-/postgrest-js-1.19.2.tgz#cb721860fefd9ec2818bbafc56de4314c0ebca81"
+  integrity sha512-MXRbk4wpwhWl9IN6rIY1mR8uZCCG4MZAEji942ve6nMwIqnBgBnZhZlON6zTTs6fgveMnoCILpZv1+K91jN+ow==
+  dependencies:
+    "@supabase/node-fetch" "^2.6.14"
+
+"@supabase/realtime-js@2.11.2":
+  version "2.11.2"
+  resolved "https://registry.yarnpkg.com/@supabase/realtime-js/-/realtime-js-2.11.2.tgz#7f7399c326be717eadc9d5e259f9e2690fbf83dd"
+  integrity sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==
+  dependencies:
+    "@supabase/node-fetch" "^2.6.14"
+    "@types/phoenix" "^1.5.4"
+    "@types/ws" "^8.5.10"
+    ws "^8.18.0"
+
+"@supabase/storage-js@2.7.1":
+  version "2.7.1"
+  resolved "https://registry.yarnpkg.com/@supabase/storage-js/-/storage-js-2.7.1.tgz#761482f237deec98a59e5af1ace18c7a5e0a69af"
+  integrity sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==
+  dependencies:
+    "@supabase/node-fetch" "^2.6.14"
+
+"@supabase/supabase-js@2.49.3":
+  version "2.49.3"
+  resolved "https://registry.yarnpkg.com/@supabase/supabase-js/-/supabase-js-2.49.3.tgz#789b01074b9e62ea6e41657ad65b3c06610ea3c5"
+  integrity sha512-42imTuAm9VEQGlXT0O6zrSwNnsIblU1eieqrAWj8HSmFaYkxepk/IuUVw1M5hKelk0ZYlqDKNwRErI1rF1EL4w==
+  dependencies:
+    "@supabase/auth-js" "2.69.1"
+    "@supabase/functions-js" "2.4.4"
+    "@supabase/node-fetch" "2.6.15"
+    "@supabase/postgrest-js" "1.19.2"
+    "@supabase/realtime-js" "2.11.2"
+    "@supabase/storage-js" "2.7.1"
+
 "@sveltejs/kit@^2.0.2":
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-2.0.2.tgz#bd02523fe570ddaf89148bffb1eb2233c458054b"
@@ -8041,6 +8098,11 @@
     pg-protocol "*"
     pg-types "^2.2.0"
 
+"@types/phoenix@^1.5.4":
+  version "1.6.6"
+  resolved "https://registry.yarnpkg.com/@types/phoenix/-/phoenix-1.6.6.tgz#3c1ab53fd5a23634b8e37ea72ccacbf07fbc7816"
+  integrity sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==
+
 "@types/prop-types@*":
   version "15.7.3"
   resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
@@ -8250,10 +8312,10 @@
   dependencies:
     "@types/webidl-conversions" "*"
 
-"@types/ws@^8.5.1":
-  version "8.5.10"
-  resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787"
-  integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==
+"@types/ws@^8.5.1", "@types/ws@^8.5.10":
+  version "8.18.0"
+  resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.0.tgz#8a2ec491d6f0685ceaab9a9b7ff44146236993b5"
+  integrity sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==
   dependencies:
     "@types/node" "*"