diff --git a/packages/react/src/provider/context.ts b/packages/react/src/common/context.ts
similarity index 90%
rename from packages/react/src/provider/context.ts
rename to packages/react/src/common/context.ts
index ce95f5a24..9e44801e7 100644
--- a/packages/react/src/provider/context.ts
+++ b/packages/react/src/common/context.ts
@@ -1,7 +1,7 @@
import type { Client } from '@openfeature/web-sdk';
import React from 'react';
-import type { NormalizedOptions, ReactFlagEvaluationOptions} from '../common/options';
-import { normalizeOptions } from '../common/options';
+import type { NormalizedOptions, ReactFlagEvaluationOptions} from '../common';
+import { normalizeOptions } from '../common';
/**
* The underlying React context.
diff --git a/packages/react/src/common/index.ts b/packages/react/src/common/index.ts
new file mode 100644
index 000000000..a5b372459
--- /dev/null
+++ b/packages/react/src/common/index.ts
@@ -0,0 +1,4 @@
+export * from './context';
+export * from './is-equal';
+export * from './options';
+export * from './suspense';
diff --git a/packages/react/src/context/index.ts b/packages/react/src/context/index.ts
new file mode 100644
index 000000000..6377bcc69
--- /dev/null
+++ b/packages/react/src/context/index.ts
@@ -0,0 +1 @@
+export * from './use-context-mutator';
diff --git a/packages/react/src/context/use-context-mutator.ts b/packages/react/src/context/use-context-mutator.ts
new file mode 100644
index 000000000..420e923c6
--- /dev/null
+++ b/packages/react/src/context/use-context-mutator.ts
@@ -0,0 +1,51 @@
+import { useCallback, useContext, useRef } from 'react';
+import type { EvaluationContext } from '@openfeature/web-sdk';
+import { OpenFeature } from '@openfeature/web-sdk';
+import { Context } from '../common';
+
+export type ContextMutationOptions = {
+ /**
+ * Mutate the default context instead of the domain scoped context applied at the ``.
+ * Note, if the `` has no domain specified, the default is used.
+ * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.
+ * @default false
+ */
+ defaultContext?: boolean;
+};
+
+export type ContextMutation = {
+ /**
+ * A function to set the desired context (see: {@link ContextMutationOptions} for details).
+ * There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.
+ * This promise never rejects.
+ * @param updatedContext
+ * @returns Promise for awaiting the context update
+ */
+ setContext: (updatedContext: EvaluationContext) => Promise;
+};
+
+/**
+ * Get function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.
+ * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.
+ * @param {ContextMutationOptions} options options for the generated function
+ * @returns {ContextMutation} function(s) to mutate context
+ */
+export function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {
+ const { domain } = useContext(Context) || {};
+ const previousContext = useRef(null);
+
+ const setContext = useCallback(async (updatedContext: EvaluationContext) => {
+ if (previousContext.current !== updatedContext) {
+ if (!domain || options?.defaultContext) {
+ OpenFeature.setContext(updatedContext);
+ } else {
+ OpenFeature.setContext(domain, updatedContext);
+ }
+ previousContext.current = updatedContext;
+ }
+ }, [domain]);
+
+ return {
+ setContext,
+ };
+}
diff --git a/packages/react/src/evaluation/use-feature-flag.ts b/packages/react/src/evaluation/use-feature-flag.ts
index cbcaea92a..05d6d8841 100644
--- a/packages/react/src/evaluation/use-feature-flag.ts
+++ b/packages/react/src/evaluation/use-feature-flag.ts
@@ -11,15 +11,12 @@ import {
ProviderStatus,
} from '@openfeature/web-sdk';
import { useEffect, useRef, useState } from 'react';
-import type { ReactFlagEvaluationOptions} from '../common/options';
-import { DEFAULT_OPTIONS, normalizeOptions } from '../common/options';
-import { suspendUntilReady } from '../common/suspense';
-import { useProviderOptions } from '../provider/context';
+import type { ReactFlagEvaluationOptions} from '../common';
+import { DEFAULT_OPTIONS, isEqual, normalizeOptions, suspendUntilReady, useProviderOptions } from '../common';
import { useOpenFeatureClient } from '../provider/use-open-feature-client';
import { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';
import type { FlagQuery } from '../query';
import { HookFlagQuery } from './hook-flag-query';
-import { isEqual } from '../common/is-equal';
// This type is a bit wild-looking, but I think we need it.
// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index 34b1d7d1a..6690ab35a 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -1,5 +1,6 @@
export * from './evaluation';
export * from './query';
export * from './provider';
+export * from './context';
// re-export the web-sdk so consumers can access that API from the react-sdk
export * from '@openfeature/web-sdk';
diff --git a/packages/react/src/provider/index.ts b/packages/react/src/provider/index.ts
index a4ee0392b..5d29f9cd3 100644
--- a/packages/react/src/provider/index.ts
+++ b/packages/react/src/provider/index.ts
@@ -2,4 +2,3 @@ export * from './provider';
export * from './use-open-feature-client';
export * from './use-when-provider-ready';
export * from './test-provider';
-export * from './use-context-mutator';
\ No newline at end of file
diff --git a/packages/react/src/provider/provider.tsx b/packages/react/src/provider/provider.tsx
index 64f641649..02ebc13ad 100644
--- a/packages/react/src/provider/provider.tsx
+++ b/packages/react/src/provider/provider.tsx
@@ -1,8 +1,8 @@
import type { Client} from '@openfeature/web-sdk';
import { OpenFeature } from '@openfeature/web-sdk';
import * as React from 'react';
-import type { ReactFlagEvaluationOptions } from '../common/options';
-import { Context } from './context';
+import type { ReactFlagEvaluationOptions } from '../common';
+import { Context } from '../common';
type ClientOrDomain =
| {
diff --git a/packages/react/src/provider/test-provider.tsx b/packages/react/src/provider/test-provider.tsx
index 38becaf2f..72746c764 100644
--- a/packages/react/src/provider/test-provider.tsx
+++ b/packages/react/src/provider/test-provider.tsx
@@ -7,7 +7,7 @@ import {
OpenFeature
} from '@openfeature/web-sdk';
import React from 'react';
-import type { NormalizedOptions } from '../common/options';
+import type { NormalizedOptions } from '../common';
import { OpenFeatureProvider } from './provider';
type FlagValueMap = { [flagKey: string]: JsonValue };
@@ -119,4 +119,4 @@ function mixInNoop(provider: Partial = {}) {
(provider.metadata as unknown) = { name: TEST_PROVIDER };
}
return provider;
-}
\ No newline at end of file
+}
diff --git a/packages/react/src/provider/use-context-mutator.ts b/packages/react/src/provider/use-context-mutator.ts
deleted file mode 100644
index 86dd242d3..000000000
--- a/packages/react/src/provider/use-context-mutator.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { useCallback, useContext, useRef } from 'react';
-import type { EvaluationContext } from '@openfeature/web-sdk';
-import { OpenFeature } from '@openfeature/web-sdk';
-import { Context } from './context';
-
-/**
- *
- * A hook for accessing context mutating functions.
- *
- */
-export function useContextMutator({
- setGlobal
-}: {
- /**
- * Apply changes to the global context instead of the domain scoped context applied at the React Provider
- */
- setGlobal?: boolean;
-} = {}) {
- const { domain } = useContext(Context) || {};
- const previousContext = useRef(null);
-
- const setContext = useCallback(async (updatedContext: EvaluationContext) => {
- if (previousContext.current !== updatedContext) {
- if (!domain || setGlobal) {
- OpenFeature.setContext(updatedContext);
- } else {
- OpenFeature.setContext(domain, updatedContext);
- }
- previousContext.current = updatedContext;
- }
- }, [domain]);
-
- return {
- setContext,
- };
-}
diff --git a/packages/react/src/provider/use-open-feature-client.ts b/packages/react/src/provider/use-open-feature-client.ts
index 9b395fedb..5fe3f7604 100644
--- a/packages/react/src/provider/use-open-feature-client.ts
+++ b/packages/react/src/provider/use-open-feature-client.ts
@@ -1,5 +1,5 @@
import React from 'react';
-import { Context } from './context';
+import { Context } from '../common';
import type { Client } from '@openfeature/web-sdk';
/**
diff --git a/packages/react/src/provider/use-when-provider-ready.ts b/packages/react/src/provider/use-when-provider-ready.ts
index 885b24a62..0c2f37daf 100644
--- a/packages/react/src/provider/use-when-provider-ready.ts
+++ b/packages/react/src/provider/use-when-provider-ready.ts
@@ -1,10 +1,8 @@
import { ProviderStatus } from '@openfeature/web-sdk';
-import type { ReactFlagEvaluationOptions} from '../common/options';
-import { DEFAULT_OPTIONS, normalizeOptions } from '../common/options';
-import { useProviderOptions } from './context';
import { useOpenFeatureClient } from './use-open-feature-client';
import { useOpenFeatureClientStatus } from './use-open-feature-client-status';
-import { suspendUntilReady } from '../common/suspense';
+import type { ReactFlagEvaluationOptions} from '../common';
+import { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilReady } from '../common';
type Options = Pick;
diff --git a/packages/react/test/provider.spec.tsx b/packages/react/test/provider.spec.tsx
index 0c8bd3581..8e8c84a7e 100644
--- a/packages/react/test/provider.spec.tsx
+++ b/packages/react/test/provider.spec.tsx
@@ -252,7 +252,7 @@ describe('OpenFeatureProvider', () => {
}));
const GlobalComponent = ({ name }: { name: string }) => {
const flagValue = useStringFlagValue<'b' | 'a'>('globalFlagsHere', 'a');
-
+
return (