diff --git a/src/lib/fetch.ts b/src/lib/fetch.ts
index c3ec5f42..243238be 100644
--- a/src/lib/fetch.ts
+++ b/src/lib/fetch.ts
@@ -1,27 +1,5 @@
-// @ts-ignore
-import nodeFetch, { Headers as NodeFetchHeaders } from '@supabase/node-fetch'
-
-type Fetch = typeof fetch
-
-export const resolveFetch = (customFetch?: Fetch): Fetch => {
-  let _fetch: Fetch
-  if (customFetch) {
-    _fetch = customFetch
-  } else if (typeof fetch === 'undefined') {
-    _fetch = nodeFetch as unknown as Fetch
-  } else {
-    _fetch = fetch
-  }
-  return (...args: Parameters<Fetch>) => _fetch(...args)
-}
-
-export const resolveHeadersConstructor = () => {
-  if (typeof Headers === 'undefined') {
-    return NodeFetchHeaders
-  }
-
-  return Headers
-}
+import { resolveFetch, resolveHeadersConstructor } from './helpers'
+import { Fetch } from './types'
 
 export const fetchWithAuth = (
   supabaseKey: string,
@@ -29,10 +7,11 @@ export const fetchWithAuth = (
   customFetch?: Fetch
 ): Fetch => {
   const fetch = resolveFetch(customFetch)
-  const HeadersConstructor = resolveHeadersConstructor()
 
   return async (input, init) => {
     const accessToken = (await getAccessToken()) ?? supabaseKey
+
+    const HeadersConstructor = await resolveHeadersConstructor()
     let headers = new HeadersConstructor(init?.headers)
 
     if (!headers.has('apikey')) {
diff --git a/src/lib/helpers.ts b/src/lib/helpers.ts
index d1161d0c..29430f2c 100644
--- a/src/lib/helpers.ts
+++ b/src/lib/helpers.ts
@@ -1,5 +1,5 @@
 // helpers.ts
-import { SupabaseClientOptions } from './types'
+import { Fetch, SupabaseClientOptions } from './types'
 
 export function uuid() {
   return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
@@ -66,3 +66,26 @@ export function applySettingDefaults<
 
   return result
 }
+
+export const resolveFetch = (customFetch?: Fetch): Fetch => {
+  let _fetch: Fetch
+  if (customFetch) {
+    _fetch = customFetch
+  } else if (typeof fetch === 'undefined') {
+    _fetch = (...args) =>
+      import('@supabase/node-fetch' as any).then(({ default: fetch }) => fetch(...args))
+  } else {
+    _fetch = fetch
+  }
+  return (...args: Parameters<Fetch>) => _fetch(...args)
+}
+
+export const resolveHeadersConstructor = async () => {
+  if (typeof Headers === 'undefined') {
+    return import('@supabase/node-fetch' as any).then(
+      ({ Headers: NodeFetchHeaders }) => NodeFetchHeaders as typeof Headers
+    )
+  }
+
+  return Headers
+}
diff --git a/test/helpers.test.ts b/test/helpers.test.ts
index efe6a23e..7140e159 100644
--- a/test/helpers.test.ts
+++ b/test/helpers.test.ts
@@ -40,3 +40,75 @@ test('override setting defaults', async () => {
   // Existing property values should remain constant
   expect(settings.db.schema).toBe(defaults.db.schema)
 })
+
+describe('resolveFetch', () => {
+  const TEST_URL = 'https://example.com'
+  const TEST_OPTIONS = { method: 'GET' }
+
+  beforeEach(() => {
+    // Reset any mocks between tests
+    jest.resetModules()
+    jest.clearAllMocks()
+  })
+
+  test('should use custom fetch if provided', async () => {
+    const customFetch = jest.fn()
+    const resolvedFetch = helpers.resolveFetch(customFetch)
+
+    await resolvedFetch(TEST_URL, TEST_OPTIONS)
+
+    expect(customFetch).toHaveBeenCalledTimes(1)
+    expect(customFetch).toHaveBeenCalledWith(TEST_URL, TEST_OPTIONS)
+  })
+
+  test('should use global fetch if no custom fetch is provided', async () => {
+    const globalFetch = jest.fn()
+    global.fetch = globalFetch
+    const resolvedFetch = helpers.resolveFetch()
+
+    await resolvedFetch(TEST_URL, TEST_OPTIONS)
+
+    expect(globalFetch).toHaveBeenCalledTimes(1)
+    expect(globalFetch).toHaveBeenCalledWith(TEST_URL, TEST_OPTIONS)
+  })
+
+  test('should use node-fetch if global fetch is not available', async () => {
+    const nodeFetch = jest.fn()
+    jest.mock('@supabase/node-fetch', () => nodeFetch)
+
+    global.fetch = undefined as any
+    const resolvedFetch = helpers.resolveFetch()
+
+    await resolvedFetch(TEST_URL, TEST_OPTIONS)
+
+    expect(nodeFetch).toHaveBeenCalledTimes(1)
+    expect(nodeFetch).toHaveBeenCalledWith(TEST_URL, TEST_OPTIONS)
+  })
+})
+
+describe('resolveHeadersConstructor', () => {
+  beforeEach(() => {
+    // Reset any mocks between tests
+    jest.resetModules()
+    jest.clearAllMocks()
+  })
+
+  test('should use Headers if available', async () => {
+    const resolvedHeadersConstructor = await helpers.resolveHeadersConstructor()
+    expect(resolvedHeadersConstructor).toBe(Headers)
+  })
+
+  test('should use node-fetch Headers if global Headers is not available', async () => {
+    const MockHeaders = jest.fn()
+    jest.mock('@supabase/node-fetch', () => ({
+      Headers: MockHeaders,
+    }))
+
+    // Cannot assign read-only property, delete is available
+    // @ts-ignore
+    delete global.Headers
+
+    const resolvedHeadersConstructor = await helpers.resolveHeadersConstructor()
+    expect(resolvedHeadersConstructor).toBe(MockHeaders)
+  })
+})