diff --git a/src/components/Charts/BarChart/BarChartContent.tsx b/src/components/Charts/BarChart/BarChartContent.tsx
index ecfb90e8a1b6..6a038b1ccef7 100644
--- a/src/components/Charts/BarChart/BarChartContent.tsx
+++ b/src/components/Charts/BarChart/BarChartContent.tsx
@@ -11,6 +11,7 @@ import ChartXAxisLabels from '@components/Charts/components/ChartXAxisLabels';
 import ChartYAxisLabels from '@components/Charts/components/ChartYAxisLabels';
 import type {HitTestArgs} from '@components/Charts/hooks';
 import {
+    ChartFontsProvider,
     useChartFontManager,
     useChartInteractions,
     useChartLabelFormats,
@@ -44,7 +45,7 @@ type BarChartProps = CartesianChartProps & {
     useSingleColor?: boolean;
 };
 
-function BarChartContent({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left', useSingleColor = false, onBarPress}: BarChartProps) {
+function BarChartContentBody({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left', useSingleColor = false, onBarPress}: BarChartProps) {
     const theme = useTheme();
     const styles = useThemeStyles();
     const fontMgr = useChartFontManager();
@@ -301,6 +302,14 @@ function BarChartContent({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left'
     );
 }
 
+function BarChartContent(props: BarChartProps) {
+    return (
+        <ChartFontsProvider>
+            <BarChartContentBody {...props} />
+        </ChartFontsProvider>
+    );
+}
+
 export default BarChartContent;
 export type {BarChartProps};
 export {BAR_INNER_PADDING};
diff --git a/src/components/Charts/LineChart/LineChartContent.tsx b/src/components/Charts/LineChart/LineChartContent.tsx
index f0129ac2ae4d..93b9e9a80051 100644
--- a/src/components/Charts/LineChart/LineChartContent.tsx
+++ b/src/components/Charts/LineChart/LineChartContent.tsx
@@ -13,6 +13,7 @@ import LeftFrameLine from '@components/Charts/components/LeftFrameLine';
 import ScatterPoints from '@components/Charts/components/ScatterPoints';
 import type {HitTestArgs} from '@components/Charts/hooks';
 import {
+    ChartFontsProvider,
     useChartFontManager,
     useChartInteractions,
     useChartLabelFormats,
@@ -47,7 +48,7 @@ type LineChartProps = CartesianChartProps & {
     onPointPress?: (dataPoint: ChartDataPoint, index: number) => void;
 };
 
-function LineChartContent({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left', onPointPress}: LineChartProps) {
+function LineChartContentBody({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left', onPointPress}: LineChartProps) {
     const theme = useTheme();
     const styles = useThemeStyles();
     const fontMgr = useChartFontManager();
@@ -304,5 +305,13 @@ function LineChartContent({data, isLoading, yAxisUnit, yAxisUnitPosition = 'left
     );
 }
 
+function LineChartContent(props: LineChartProps) {
+    return (
+        <ChartFontsProvider>
+            <LineChartContentBody {...props} />
+        </ChartFontsProvider>
+    );
+}
+
 export default LineChartContent;
 export type {LineChartProps};
diff --git a/src/components/Charts/VictoryTheme.ts b/src/components/Charts/VictoryTheme.ts
index 78c83379b0d0..30b29a3ab9a6 100644
--- a/src/components/Charts/VictoryTheme.ts
+++ b/src/components/Charts/VictoryTheme.ts
@@ -2,9 +2,7 @@
  * Centralized styles and layout constants for the chart components.
  */
 import colors from '@styles/theme/colors';
-
-/** Font families used by all chart label components (Paragraph API multi-font fallback). */
-const CHART_FONT_FAMILIES = ['ExpensifyNeue', 'NotoSansSymbols', 'NotoSansSCMonths'];
+import {CHART_FONT_FAMILY_NAMES} from './utils/chartFontConstants';
 
 /**
  * Expensify Chart Color Palette.
@@ -54,7 +52,7 @@ const VictoryTheme = {
         default: getChartColor(DEFAULT_CHART_COLOR_INDEX),
         getColor: getChartColor,
     },
-    fontFamilies: CHART_FONT_FAMILIES,
+    fontFamilies: Array.from(CHART_FONT_FAMILY_NAMES),
     axis: {
         /** Number of Y-axis ticks (including zero) */
         tickCount: 5,
diff --git a/src/components/Charts/context/ChartFontsContext.tsx b/src/components/Charts/context/ChartFontsContext.tsx
new file mode 100644
index 000000000000..03ef4db13915
--- /dev/null
+++ b/src/components/Charts/context/ChartFontsContext.tsx
@@ -0,0 +1,26 @@
+import type {SkTypefaceFontProvider} from '@shopify/react-native-skia';
+import {createContext, useContext} from 'react';
+import type ChartFontsValue from '@components/Charts/types/chartFontsTypes';
+import type {ChartDefaultTypeface} from '@components/Charts/types/chartSkiaTypefaceTypes';
+
+const ChartFontsContext = createContext<ChartFontsValue | null>(null);
+
+function useChartFontsContext(): ChartFontsValue {
+    const context = useContext(ChartFontsContext);
+
+    if (!context) {
+        throw new Error('Chart fonts hooks must be used within ChartFontsProvider');
+    }
+
+    return context;
+}
+
+function useChartTypefaces(): ChartDefaultTypeface {
+    return useChartFontsContext().typefaces;
+}
+
+function useChartFontManager(): SkTypefaceFontProvider | null {
+    return useChartFontsContext().fontMgr;
+}
+
+export {ChartFontsContext, useChartFontManager, useChartTypefaces};
diff --git a/src/components/Charts/context/ChartFontsProvider.tsx b/src/components/Charts/context/ChartFontsProvider.tsx
new file mode 100644
index 000000000000..b90c811285ae
--- /dev/null
+++ b/src/components/Charts/context/ChartFontsProvider.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import useChartFonts from '@components/Charts/hooks/useChartFonts';
+import type ChartFontsValue from '@components/Charts/types/chartFontsTypes';
+import {ChartFontsContext} from './ChartFontsContext';
+
+type ChartFontsProviderProps = {
+    children: React.ReactNode;
+    value?: ChartFontsValue;
+};
+
+function ChartFontsLoaderProvider({children}: {children: React.ReactNode}) {
+    const fonts = useChartFonts();
+
+    return <ChartFontsContext.Provider value={fonts}>{children}</ChartFontsContext.Provider>;
+}
+
+function ChartFontsProvider({children, value}: ChartFontsProviderProps) {
+    if (value) {
+        return <ChartFontsContext.Provider value={value}>{children}</ChartFontsContext.Provider>;
+    }
+
+    return <ChartFontsLoaderProvider>{children}</ChartFontsLoaderProvider>;
+}
+
+export default ChartFontsProvider;
diff --git a/src/components/Charts/hooks/index.ts b/src/components/Charts/hooks/index.ts
index c18d0c9934d4..7ff2f5556252 100644
--- a/src/components/Charts/hooks/index.ts
+++ b/src/components/Charts/hooks/index.ts
@@ -2,7 +2,9 @@ export {default as useChartLabelLayout} from './useChartLabelLayout';
 export {default as useChartLabelMeasurements} from './useChartLabelMeasurements';
 export {default as useChartParagraphs} from './useChartParagraphs';
 export {default as useYAxisLabelWidth} from './useYAxisLabelWidth';
-export {default as useChartFontManager, useChartDefaultTypeface} from './useChartFontManager/useChartFontManager';
+export {useChartFontManager} from '@components/Charts/context/ChartFontsContext';
+export {default as ChartFontsProvider} from '@components/Charts/context/ChartFontsProvider';
+export {useChartTypefaces} from '@components/Charts/context/ChartFontsContext';
 export {useChartInteractions, TOOLTIP_BAR_GAP} from './useChartInteractions';
 export type {HitTestArgs} from './useChartInteractions';
 export {default as useChartLabelFormats} from './useChartLabelFormats';
diff --git a/src/components/Charts/hooks/useChartFontManager/useChartFontManager.native.ts b/src/components/Charts/hooks/useChartFontManager/useChartFontManager.native.ts
deleted file mode 100644
index 04cd0344d420..000000000000
--- a/src/components/Charts/hooks/useChartFontManager/useChartFontManager.native.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type {DataModule, SkTypefaceFontProvider} from '@shopify/react-native-skia';
-import {useFonts, useTypeface} from '@shopify/react-native-skia';
-
-function useChartFontManager(): SkTypefaceFontProvider | null {
-    return useFonts({
-        ExpensifyNeue: [
-            require('@assets/fonts/native/ExpensifyNeue-Regular.otf') as DataModule,
-            require('@assets/fonts/native/ExpensifyNeue-Bold.otf') as DataModule,
-            require('@assets/fonts/native/ExpensifyNeue-Italic.otf') as DataModule,
-            require('@assets/fonts/native/ExpensifyNeue-BoldItalic.otf') as DataModule,
-        ],
-        NotoSansSymbols: [require('@assets/fonts/NotoSans-Symbols.ttf') as DataModule],
-        NotoSansSCMonths: [require('@assets/fonts/NotoSansSC-Months.ttf') as DataModule],
-    });
-}
-
-function useChartDefaultTypeface() {
-    const regular = useTypeface(require('@assets/fonts/native/ExpensifyNeue-Regular.otf') as DataModule);
-    const bold = useTypeface(require('@assets/fonts/native/ExpensifyNeue-Bold.otf') as DataModule);
-    return {regular, bold};
-}
-
-export {useChartDefaultTypeface};
-export default useChartFontManager;
diff --git a/src/components/Charts/hooks/useChartFontManager/useChartFontManager.ts b/src/components/Charts/hooks/useChartFontManager/useChartFontManager.ts
deleted file mode 100644
index e0c8a8305fed..000000000000
--- a/src/components/Charts/hooks/useChartFontManager/useChartFontManager.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type {DataModule, SkTypefaceFontProvider} from '@shopify/react-native-skia';
-import {useFonts, useTypeface} from '@shopify/react-native-skia';
-
-function webFont(url: string): DataModule {
-    // We construct a fake ESModule-shaped object because react-native-skia's `useFonts` on web expects
-    // a DataModule (i.e. the result of a dynamic `require()` call), which always has the shape
-    // `{ __esModule: true, default: <url> }`. The `__esModule` property uses a double-underscore prefix
-    // that violates the naming-convention rule, but it is mandated by the library's internal contract.
-    return {__esModule: true, default: url} as unknown as DataModule;
-}
-
-function useChartFontManager(): SkTypefaceFontProvider | null {
-    return useFonts({
-        ExpensifyNeue: [
-            webFont(require('@assets/fonts/web/ExpensifyNeue-Regular.woff2') as string),
-            webFont(require('@assets/fonts/web/ExpensifyNeue-Bold.woff2') as string),
-            webFont(require('@assets/fonts/web/ExpensifyNeue-Italic.woff2') as string),
-            webFont(require('@assets/fonts/web/ExpensifyNeue-BoldItalic.woff2') as string),
-        ],
-        NotoSansSymbols: [webFont(require('@assets/fonts/NotoSans-Symbols.ttf') as string)],
-        NotoSansSCMonths: [webFont(require('@assets/fonts/NotoSansSC-Months.ttf') as string)],
-    });
-}
-
-function useChartDefaultTypeface() {
-    const regular = useTypeface(webFont(require('@assets/fonts/web/ExpensifyNeue-Regular.woff2') as string));
-    const bold = useTypeface(webFont(require('@assets/fonts/web/ExpensifyNeue-Bold.woff2') as string));
-    return {regular, bold};
-}
-
-export {useChartDefaultTypeface};
-export default useChartFontManager;
diff --git a/src/components/Charts/hooks/useChartFonts.ts b/src/components/Charts/hooks/useChartFonts.ts
new file mode 100644
index 000000000000..5b012437a9d1
--- /dev/null
+++ b/src/components/Charts/hooks/useChartFonts.ts
@@ -0,0 +1,15 @@
+import {useEffect, useSyncExternalStore} from 'react';
+import type ChartFontsValue from '@components/Charts/types/chartFontsTypes';
+import {getChartFontsSnapshot, loadChartFontsOnce, subscribeToChartFonts} from '@components/Charts/utils/chartFontsCache';
+
+function useChartFonts(): ChartFontsValue {
+    const fonts = useSyncExternalStore(subscribeToChartFonts, getChartFontsSnapshot, getChartFontsSnapshot);
+
+    useEffect(() => {
+        loadChartFontsOnce();
+    }, []);
+
+    return fonts;
+}
+
+export default useChartFonts;
diff --git a/src/components/Charts/types/chartFontsTypes.ts b/src/components/Charts/types/chartFontsTypes.ts
new file mode 100644
index 000000000000..deaecc415114
--- /dev/null
+++ b/src/components/Charts/types/chartFontsTypes.ts
@@ -0,0 +1,9 @@
+import type {SkTypefaceFontProvider} from '@shopify/react-native-skia';
+import type {ChartDefaultTypeface} from './chartSkiaTypefaceTypes';
+
+type ChartFontsValue = {
+    typefaces: ChartDefaultTypeface;
+    fontMgr: SkTypefaceFontProvider | null;
+};
+
+export default ChartFontsValue;
diff --git a/src/components/Charts/types/chartSkiaTypefaceTypes.ts b/src/components/Charts/types/chartSkiaTypefaceTypes.ts
new file mode 100644
index 000000000000..fa26dde27a2a
--- /dev/null
+++ b/src/components/Charts/types/chartSkiaTypefaceTypes.ts
@@ -0,0 +1,9 @@
+import type {SkTypeface} from '@shopify/react-native-skia';
+// eslint-disable-next-line no-restricted-imports
+import type FontFamilyStyles from '@styles/utils/FontUtils/fontFamily/types';
+
+type ChartSkiaTypefaceKey = Exclude<keyof FontFamilyStyles, 'SYSTEM'>;
+
+type ChartDefaultTypeface = Record<ChartSkiaTypefaceKey, SkTypeface | null>;
+
+export type {ChartDefaultTypeface, ChartSkiaTypefaceKey};
diff --git a/src/components/Charts/types.ts b/src/components/Charts/types/index.ts
similarity index 96%
rename from src/components/Charts/types.ts
rename to src/components/Charts/types/index.ts
index 2ed86d19ec06..b44954eb31e4 100644
--- a/src/components/Charts/types.ts
+++ b/src/components/Charts/types/index.ts
@@ -1,6 +1,6 @@
 import type {SkParagraph} from '@shopify/react-native-skia';
 import type {ValueOf} from 'type-fest';
-import type {LABEL_ROTATIONS} from './VictoryTheme';
+import type {LABEL_ROTATIONS} from '@components/Charts/VictoryTheme';
 
 type ChartDataPoint = {
     /** Label displayed under the data point (e.g., "Amazon", "Nov 2025") */
diff --git a/src/components/Charts/utils/chartFontAssets.native.ts b/src/components/Charts/utils/chartFontAssets.native.ts
new file mode 100644
index 000000000000..585fdee494e4
--- /dev/null
+++ b/src/components/Charts/utils/chartFontAssets.native.ts
@@ -0,0 +1,37 @@
+import type {DataModule} from '@shopify/react-native-skia';
+import type {ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+
+const EXPENSIFY_MONO_REGULAR = require('@assets/fonts/native/ExpensifyMono-Regular.otf') as DataModule;
+const EXPENSIFY_MONO_BOLD = require('@assets/fonts/native/ExpensifyMono-Bold.otf') as DataModule;
+const EXPENSIFY_MONO_ITALIC = require('@assets/fonts/native/ExpensifyMono-Italic.otf') as DataModule;
+const EXPENSIFY_MONO_BOLD_ITALIC = require('@assets/fonts/native/ExpensifyMono-BoldItalic.otf') as DataModule;
+const EXPENSIFY_NEUE_REGULAR = require('@assets/fonts/native/ExpensifyNeue-Regular.otf') as DataModule;
+const EXPENSIFY_NEUE_BOLD = require('@assets/fonts/native/ExpensifyNeue-Bold.otf') as DataModule;
+const EXPENSIFY_NEUE_ITALIC = require('@assets/fonts/native/ExpensifyNeue-Italic.otf') as DataModule;
+const EXPENSIFY_NEUE_BOLD_ITALIC = require('@assets/fonts/native/ExpensifyNeue-BoldItalic.otf') as DataModule;
+const EXPENSIFY_NEW_KANSAS_MEDIUM = require('@assets/fonts/native/ExpensifyNewKansas-Medium.otf') as DataModule;
+const EXPENSIFY_NEW_KANSAS_MEDIUM_ITALIC = require('@assets/fonts/native/ExpensifyNewKansas-MediumItalic.otf') as DataModule;
+const CUSTOM_EMOJI_FONT = require('@assets/fonts/native/CustomEmojiNativeFont.ttf') as DataModule;
+const SANS_SYMBOLS_FONT = require('@assets/fonts/NotoSans-Symbols.ttf') as DataModule;
+const SANS_SC_MONTHS_FONT = require('@assets/fonts/NotoSansSC-Months.ttf') as DataModule;
+
+const CHART_SKIA_TYPEFACE_ASSETS: Record<ChartSkiaTypefaceKey, DataModule> = {
+    MONOSPACE: EXPENSIFY_MONO_REGULAR,
+    MONOSPACE_BOLD: EXPENSIFY_MONO_BOLD,
+    MONOSPACE_ITALIC: EXPENSIFY_MONO_ITALIC,
+    MONOSPACE_BOLD_ITALIC: EXPENSIFY_MONO_BOLD_ITALIC,
+    EXP_NEUE: EXPENSIFY_NEUE_REGULAR,
+    EXP_NEUE_BOLD: EXPENSIFY_NEUE_BOLD,
+    EXP_NEUE_ITALIC: EXPENSIFY_NEUE_ITALIC,
+    EXP_NEUE_BOLD_ITALIC: EXPENSIFY_NEUE_BOLD_ITALIC,
+    EXP_NEW_KANSAS_MEDIUM: EXPENSIFY_NEW_KANSAS_MEDIUM,
+    EXP_NEW_KANSAS_MEDIUM_ITALIC: EXPENSIFY_NEW_KANSAS_MEDIUM_ITALIC,
+    CUSTOM_EMOJI_FONT,
+};
+
+const CHART_FONT_MGR_SUPPLEMENTAL_ASSETS = {
+    NotoSansSymbols: SANS_SYMBOLS_FONT,
+    NotoSansSCMonths: SANS_SC_MONTHS_FONT,
+} as const;
+
+export {CHART_FONT_MGR_SUPPLEMENTAL_ASSETS, CHART_SKIA_TYPEFACE_ASSETS};
diff --git a/src/components/Charts/utils/chartFontAssets.ts b/src/components/Charts/utils/chartFontAssets.ts
new file mode 100644
index 000000000000..a846320d3d7b
--- /dev/null
+++ b/src/components/Charts/utils/chartFontAssets.ts
@@ -0,0 +1,38 @@
+import type {DataModule} from '@shopify/react-native-skia';
+import type {ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+import chartWebFont from './chartWebFont';
+
+const EXPENSIFY_MONO_REGULAR = chartWebFont(require('@assets/fonts/web/ExpensifyMono-Regular.woff2') as string);
+const EXPENSIFY_MONO_BOLD = chartWebFont(require('@assets/fonts/web/ExpensifyMono-Bold.woff2') as string);
+const EXPENSIFY_MONO_ITALIC = chartWebFont(require('@assets/fonts/web/ExpensifyMono-Italic.woff2') as string);
+const EXPENSIFY_MONO_BOLD_ITALIC = chartWebFont(require('@assets/fonts/web/ExpensifyMono-BoldItalic.woff2') as string);
+const EXPENSIFY_NEUE_REGULAR = chartWebFont(require('@assets/fonts/web/ExpensifyNeue-Regular.woff2') as string);
+const EXPENSIFY_NEUE_BOLD = chartWebFont(require('@assets/fonts/web/ExpensifyNeue-Bold.woff2') as string);
+const EXPENSIFY_NEUE_ITALIC = chartWebFont(require('@assets/fonts/web/ExpensifyNeue-Italic.woff2') as string);
+const EXPENSIFY_NEUE_BOLD_ITALIC = chartWebFont(require('@assets/fonts/web/ExpensifyNeue-BoldItalic.woff2') as string);
+const EXPENSIFY_NEW_KANSAS_MEDIUM = chartWebFont(require('@assets/fonts/web/ExpensifyNewKansas-Medium.woff2') as string);
+const EXPENSIFY_NEW_KANSAS_MEDIUM_ITALIC = chartWebFont(require('@assets/fonts/web/ExpensifyNewKansas-MediumItalic.woff2') as string);
+const CUSTOM_EMOJI_FONT = chartWebFont(require('@assets/fonts/web/CustomEmojiWebFont.ttf') as string);
+const SANS_SYMBOLS_FONT = chartWebFont(require('@assets/fonts/NotoSans-Symbols.ttf') as string);
+const SANS_SC_MONTHS_FONT = chartWebFont(require('@assets/fonts/NotoSansSC-Months.ttf') as string);
+
+const CHART_SKIA_TYPEFACE_ASSETS: Record<ChartSkiaTypefaceKey, DataModule> = {
+    MONOSPACE: EXPENSIFY_MONO_REGULAR,
+    MONOSPACE_BOLD: EXPENSIFY_MONO_BOLD,
+    MONOSPACE_ITALIC: EXPENSIFY_MONO_ITALIC,
+    MONOSPACE_BOLD_ITALIC: EXPENSIFY_MONO_BOLD_ITALIC,
+    EXP_NEUE: EXPENSIFY_NEUE_REGULAR,
+    EXP_NEUE_BOLD: EXPENSIFY_NEUE_BOLD,
+    EXP_NEUE_ITALIC: EXPENSIFY_NEUE_ITALIC,
+    EXP_NEUE_BOLD_ITALIC: EXPENSIFY_NEUE_BOLD_ITALIC,
+    EXP_NEW_KANSAS_MEDIUM: EXPENSIFY_NEW_KANSAS_MEDIUM,
+    EXP_NEW_KANSAS_MEDIUM_ITALIC: EXPENSIFY_NEW_KANSAS_MEDIUM_ITALIC,
+    CUSTOM_EMOJI_FONT,
+};
+
+const CHART_FONT_MGR_SUPPLEMENTAL_ASSETS = {
+    NotoSansSymbols: SANS_SYMBOLS_FONT,
+    NotoSansSCMonths: SANS_SC_MONTHS_FONT,
+} as const;
+
+export {CHART_FONT_MGR_SUPPLEMENTAL_ASSETS, CHART_SKIA_TYPEFACE_ASSETS};
diff --git a/src/components/Charts/utils/chartFontConstants.ts b/src/components/Charts/utils/chartFontConstants.ts
new file mode 100644
index 000000000000..0ac924e91f90
--- /dev/null
+++ b/src/components/Charts/utils/chartFontConstants.ts
@@ -0,0 +1,16 @@
+import type {TupleToUnion} from 'type-fest';
+import type {ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+
+/** Font families registered on Skia fontMgr and used by Paragraph API multi-font fallback. */
+const CHART_FONT_FAMILY_NAMES = ['ExpensifyNeue', 'ExpensifyMono', 'ExpensifyNewKansas', 'NotoSansSymbols', 'NotoSansSCMonths'] as const;
+
+type ChartFontFamilyName = TupleToUnion<typeof CHART_FONT_FAMILY_NAMES>;
+
+/** Maps fontMgr family names to already-loaded chart typefaces (Noto families load separately). */
+const CHART_FONT_MGR_FROM_TYPEFACES: Record<Exclude<ChartFontFamilyName, 'NotoSansSymbols' | 'NotoSansSCMonths'>, ChartSkiaTypefaceKey[]> = {
+    ExpensifyNeue: ['EXP_NEUE', 'EXP_NEUE_BOLD', 'EXP_NEUE_ITALIC', 'EXP_NEUE_BOLD_ITALIC'],
+    ExpensifyMono: ['MONOSPACE', 'MONOSPACE_BOLD', 'MONOSPACE_ITALIC', 'MONOSPACE_BOLD_ITALIC'],
+    ExpensifyNewKansas: ['EXP_NEW_KANSAS_MEDIUM', 'EXP_NEW_KANSAS_MEDIUM_ITALIC'],
+};
+
+export {CHART_FONT_FAMILY_NAMES, CHART_FONT_MGR_FROM_TYPEFACES};
diff --git a/src/components/Charts/utils/chartFontsCache.ts b/src/components/Charts/utils/chartFontsCache.ts
new file mode 100644
index 000000000000..3945e4d57550
--- /dev/null
+++ b/src/components/Charts/utils/chartFontsCache.ts
@@ -0,0 +1,127 @@
+import type {DataModule, SkTypeface} from '@shopify/react-native-skia';
+import {Skia} from '@shopify/react-native-skia';
+import {Image} from 'react-native';
+import type ChartFontsValue from '@components/Charts/types/chartFontsTypes';
+import type {ChartDefaultTypeface, ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+import Log from '@libs/Log';
+import {CHART_FONT_MGR_SUPPLEMENTAL_ASSETS, CHART_SKIA_TYPEFACE_ASSETS} from './chartFontAssets';
+import {CHART_FONT_MGR_FROM_TYPEFACES} from './chartFontConstants';
+
+const EMPTY_CHART_FONTS: ChartFontsValue = {
+    typefaces: Object.fromEntries((Object.keys(CHART_SKIA_TYPEFACE_ASSETS) as ChartSkiaTypefaceKey[]).map((key) => [key, null])) as ChartDefaultTypeface,
+    fontMgr: null,
+};
+
+let cachedChartFonts: ChartFontsValue | null = null;
+let loadPromise: Promise<ChartFontsValue> | null = null;
+const chartFontLoadListeners = new Set<() => void>();
+
+function resolveChartFontAsset(source: DataModule | string): string {
+    if (typeof source === 'string') {
+        return source;
+    }
+
+    if (typeof source === 'number') {
+        return Image.resolveAssetSource(source).uri;
+    }
+
+    if ('default' in source && typeof source.default === 'string') {
+        return source.default;
+    }
+
+    if ('uri' in source && typeof source.uri === 'string') {
+        return source.uri;
+    }
+
+    throw new Error('Unsupported chart font asset source');
+}
+
+function loadTypefaceFromAsset(source: DataModule | string): Promise<SkTypeface | null> {
+    const uri = resolveChartFontAsset(source);
+
+    return Skia.Data.fromURI(uri).then((data) => Skia.Typeface.MakeFreeTypeFaceFromData(data));
+}
+
+function loadChartSkiaTypefaces(): Promise<ChartDefaultTypeface> {
+    const typefaceKeys = Object.keys(CHART_SKIA_TYPEFACE_ASSETS) as ChartSkiaTypefaceKey[];
+
+    return Promise.all(
+        typefaceKeys.map(async (typefaceKey) => {
+            const typeface = await loadTypefaceFromAsset(CHART_SKIA_TYPEFACE_ASSETS[typefaceKey]);
+            return [typefaceKey, typeface] as const;
+        }),
+    ).then((entries) => Object.fromEntries(entries) as ChartDefaultTypeface);
+}
+
+function buildChartFontsValue(typefaces: ChartDefaultTypeface): Promise<ChartFontsValue> {
+    const fontMgr = Skia.TypefaceFontProvider.Make();
+
+    for (const [familyName, typefaceKeys] of Object.entries(CHART_FONT_MGR_FROM_TYPEFACES)) {
+        for (const typefaceKey of typefaceKeys) {
+            const typeface = typefaces[typefaceKey];
+
+            if (typeface) {
+                fontMgr.registerFont(typeface, familyName);
+            }
+        }
+    }
+
+    return Promise.all(
+        Object.entries(CHART_FONT_MGR_SUPPLEMENTAL_ASSETS).map(async ([familyName, asset]) => {
+            const typeface = await loadTypefaceFromAsset(asset);
+
+            if (typeface) {
+                fontMgr.registerFont(typeface, familyName);
+            }
+        }),
+    ).then(() => ({typefaces, fontMgr}));
+}
+
+function loadChartFonts(): Promise<ChartFontsValue> {
+    return loadChartSkiaTypefaces().then(buildChartFontsValue);
+}
+
+function subscribeToChartFonts(listener: () => void): () => void {
+    chartFontLoadListeners.add(listener);
+
+    return () => {
+        chartFontLoadListeners.delete(listener);
+    };
+}
+
+function getChartFontsSnapshot(): ChartFontsValue {
+    return cachedChartFonts ?? EMPTY_CHART_FONTS;
+}
+
+function notifyChartFontLoadListeners(): void {
+    for (const listener of chartFontLoadListeners) {
+        listener();
+    }
+}
+
+function loadChartFontsOnce(): Promise<ChartFontsValue> {
+    if (cachedChartFonts) {
+        return Promise.resolve(cachedChartFonts);
+    }
+
+    if (!loadPromise) {
+        loadPromise = loadChartFonts()
+            .then((fonts) => {
+                cachedChartFonts = fonts;
+                notifyChartFontLoadListeners();
+                return fonts;
+            })
+            .catch((error: unknown) => {
+                Log.hmmm('Chart fonts failed to load', {
+                    error: error instanceof Error ? error.message : String(error),
+                });
+                loadPromise = null;
+                notifyChartFontLoadListeners();
+                return EMPTY_CHART_FONTS;
+            });
+    }
+
+    return loadPromise;
+}
+
+export {getChartFontsSnapshot, loadChartFontsOnce, subscribeToChartFonts};
diff --git a/src/components/Charts/utils/chartWebFont.ts b/src/components/Charts/utils/chartWebFont.ts
new file mode 100644
index 000000000000..a569e1424586
--- /dev/null
+++ b/src/components/Charts/utils/chartWebFont.ts
@@ -0,0 +1,11 @@
+import type {DataModule} from '@shopify/react-native-skia';
+
+function chartWebFont(url: string): DataModule {
+    // We construct a fake ESModule-shaped object because react-native-skia's `useFonts` on web expects
+    // a DataModule (i.e. the result of a dynamic `require()` call), which always has the shape
+    // `{ __esModule: true, default: <url> }`. The `__esModule` property uses a double-underscore prefix
+    // that violates the naming-convention rule, but it is mandated by the library's internal contract.
+    return {__esModule: true, default: url} as unknown as DataModule;
+}
+
+export default chartWebFont;
diff --git a/src/components/Charts/utils/getChartSkiaTypeface.ts b/src/components/Charts/utils/getChartSkiaTypeface.ts
new file mode 100644
index 000000000000..c1f0bd1521ee
--- /dev/null
+++ b/src/components/Charts/utils/getChartSkiaTypeface.ts
@@ -0,0 +1,59 @@
+import type {SkTypeface} from '@shopify/react-native-skia';
+import type {TextStyle} from 'react-native';
+import type {ChartDefaultTypeface, ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+// eslint-disable-next-line no-restricted-imports
+import singleFontFamily from '@styles/utils/FontUtils/fontFamily/singleFontFamily';
+import type {ChartLabelFontWeight} from './normalizeChartFontWeight';
+import normalizeChartFontWeight from './normalizeChartFontWeight';
+
+type ChartLabelFontStyle = 'normal' | 'italic';
+
+function normalizeFontStyle(fontStyle: string | undefined): ChartLabelFontStyle {
+    return fontStyle === 'italic' ? 'italic' : 'normal';
+}
+
+function fontWeightMatches(definitionWeight: TextStyle['fontWeight'], labelWeight: ChartLabelFontWeight): boolean {
+    const numericWeight = Number(definitionWeight);
+
+    if (labelWeight === 'bold') {
+        return numericWeight >= 600 || definitionWeight === 'bold';
+    }
+
+    return numericWeight < 600 && definitionWeight !== 'bold';
+}
+
+function getChartSkiaTypefaceKey(fontFamily: string | undefined, fontStyle: ChartLabelFontStyle, fontWeight: ChartLabelFontWeight): ChartSkiaTypefaceKey {
+    const resolvedFontFamily = fontFamily ?? singleFontFamily.EXP_NEUE.fontFamily;
+
+    // Kansas has no bold variant; weight is ignored and Medium is always used.
+    if (resolvedFontFamily === singleFontFamily.EXP_NEW_KANSAS_MEDIUM.fontFamily) {
+        return fontStyle === 'italic' ? 'EXP_NEW_KANSAS_MEDIUM_ITALIC' : 'EXP_NEW_KANSAS_MEDIUM';
+    }
+
+    const matchingKey = (Object.keys(singleFontFamily) as Array<keyof typeof singleFontFamily>)
+        .filter((key): key is ChartSkiaTypefaceKey => key !== 'SYSTEM')
+        .find((key) => {
+            const definition = singleFontFamily[key];
+            return definition.fontFamily === resolvedFontFamily && normalizeFontStyle(definition.fontStyle) === fontStyle && fontWeightMatches(definition.fontWeight, fontWeight);
+        });
+
+    return matchingKey ?? 'EXP_NEUE';
+}
+
+function getChartSkiaTypeface(
+    typefaces: ChartDefaultTypeface,
+    {
+        fontFamily,
+        fontStyle,
+        fontWeight,
+    }: {
+        fontFamily?: string;
+        fontStyle?: string;
+        fontWeight?: string | number;
+    },
+): SkTypeface | null {
+    const typefaceKey = getChartSkiaTypefaceKey(fontFamily, normalizeFontStyle(fontStyle), normalizeChartFontWeight(fontWeight));
+    return typefaces[typefaceKey];
+}
+
+export default getChartSkiaTypeface;
diff --git a/src/components/Charts/utils.ts b/src/components/Charts/utils/index.ts
similarity index 99%
rename from src/components/Charts/utils.ts
rename to src/components/Charts/utils/index.ts
index 6db9a4455453..9fa433e9e6c6 100644
--- a/src/components/Charts/utils.ts
+++ b/src/components/Charts/utils/index.ts
@@ -1,8 +1,8 @@
 import {FontStyle, FontWeight, Skia} from '@shopify/react-native-skia';
 import type {SkParagraph, SkParagraphBuilder, SkTypefaceFontProvider} from '@shopify/react-native-skia';
+import type {ChartDataPoint, LabelRotation, PieSlice} from '@components/Charts/types';
+import VictoryTheme, {DIAGONAL_ANGLE_RADIAN_THRESHOLD, ELLIPSIS, LABEL_PADDING, LABEL_ROTATIONS, MAX_X_AXIS_LABEL_WIDTH, SIN_45} from '@components/Charts/VictoryTheme';
 import variables from '@styles/variables';
-import type {ChartDataPoint, LabelRotation, PieSlice} from './types';
-import VictoryTheme, {DIAGONAL_ANGLE_RADIAN_THRESHOLD, ELLIPSIS, LABEL_PADDING, LABEL_ROTATIONS, MAX_X_AXIS_LABEL_WIDTH, SIN_45} from './VictoryTheme';
 
 /** One reusable ParagraphBuilder per fontMgr instance. Auto-GC'd when fontMgr is released. */
 const builderCache = new WeakMap<SkTypefaceFontProvider, SkParagraphBuilder>();
diff --git a/src/components/Charts/utils/normalizeChartFontWeight.ts b/src/components/Charts/utils/normalizeChartFontWeight.ts
new file mode 100644
index 000000000000..f2154fe10a66
--- /dev/null
+++ b/src/components/Charts/utils/normalizeChartFontWeight.ts
@@ -0,0 +1,18 @@
+type ChartLabelFontWeight = 'normal' | 'bold';
+
+function normalizeChartFontWeight(fontWeight: string | number | undefined): ChartLabelFontWeight {
+    if (fontWeight === 'bold') {
+        return 'bold';
+    }
+
+    const numericWeight = Number(fontWeight);
+
+    if (!Number.isNaN(numericWeight) && numericWeight >= 600) {
+        return 'bold';
+    }
+
+    return 'normal';
+}
+
+export default normalizeChartFontWeight;
+export type {ChartLabelFontWeight};
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/BaseVictoryChartRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/BaseVictoryChartRenderer.tsx
index da522351285b..2ceb4d4ac69f 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/BaseVictoryChartRenderer.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/BaseVictoryChartRenderer.tsx
@@ -1,4 +1,5 @@
 import React from 'react';
+import {ChartFontsProvider} from '@components/Charts/hooks';
 import VictoryChartContainer from './components/VictoryChartContainer';
 import VictoryChartContent from './components/VictoryChartContent';
 import {VictoryChartProvider} from './context/VictoryChartContext';
@@ -6,14 +7,14 @@ import type {VictoryChartRendererProps} from './types';
 
 function BaseVictoryChartRenderer({tnode}: VictoryChartRendererProps) {
     return (
-        <VictoryChartProvider tnode={tnode}>
-            <VictoryChartContainer>
-                <VictoryChartContent />
-            </VictoryChartContainer>
-        </VictoryChartProvider>
+        <ChartFontsProvider>
+            <VictoryChartProvider tnode={tnode}>
+                <VictoryChartContainer>
+                    <VictoryChartContent />
+                </VictoryChartContainer>
+            </VictoryChartProvider>
+        </ChartFontsProvider>
     );
 }
 
-BaseVictoryChartRenderer.displayName = 'BaseVictoryChartRenderer';
-
 export default BaseVictoryChartRenderer;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCartesian.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCartesian.tsx
index 10cef4f0875c..a50e79bf578f 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCartesian.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCartesian.tsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import {CartesianChart} from 'victory-native';
+import {ChartFontsProvider} from '@components/Charts/hooks';
 import {useVictoryChartContext} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext';
 import {VictoryChartRenderArgsProvider} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartRenderArgsContext';
 import getHierarchyID from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/getHierarchyID';
@@ -25,20 +26,23 @@ function VictoryChartCartesian() {
             domainPadding={domainPadding}
             padding={padding}
             renderOutside={(renderArgs) => (
-                <VictoryChartRenderArgsProvider value={renderArgs}>
-                    {labelItems.map((labelItem) => (
-                        <VictoryChartLabel
-                            key={`label-${labelItem.x}-${labelItem.y}`}
-                            {...labelItem}
-                        />
-                    ))}
-                    {legendItems.map((legendItem) => (
-                        <VictoryChartLegend
-                            key={`legend-${legendItem.x}-${legendItem.y}`}
-                            {...legendItem}
-                        />
-                    ))}
-                </VictoryChartRenderArgsProvider>
+                // Chart font context does not propagate across the Skia renderOutside boundary.
+                <ChartFontsProvider>
+                    <VictoryChartRenderArgsProvider value={renderArgs}>
+                        {labelItems.map((labelItem) => (
+                            <VictoryChartLabel
+                                key={`label-${labelItem.x}-${labelItem.y}`}
+                                {...labelItem}
+                            />
+                        ))}
+                        {legendItems.map((legendItem) => (
+                            <VictoryChartLegend
+                                key={`legend-${legendItem.x}-${legendItem.y}`}
+                                {...legendItem}
+                            />
+                        ))}
+                    </VictoryChartRenderArgsProvider>
+                </ChartFontsProvider>
             )}
         >
             {(renderArgs) => (
@@ -56,6 +60,4 @@ function VictoryChartCartesian() {
     );
 }
 
-VictoryChartCartesian.displayName = 'VictoryChartCartesian';
-
 export default VictoryChartCartesian;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCategories.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCategories.tsx
index 348230c9c9da..5fdc144c38a8 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCategories.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartCategories.tsx
@@ -24,6 +24,4 @@ function VictoryChartCategories({tnode}: VictoryChartCategoriesProps) {
     return <CategoriesRenderer tnode={tnode} />;
 }
 
-VictoryChartCategories.displayName = 'VictoryChartCategories';
-
 export default VictoryChartCategories;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLabel.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLabel.tsx
index 76e3f963bda1..bc3a2ca25cd6 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLabel.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLabel.tsx
@@ -1,7 +1,8 @@
 import {Skia, Text as SkText} from '@shopify/react-native-skia';
 import type {Color, SkFont} from '@shopify/react-native-skia';
 import React from 'react';
-import {useChartDefaultTypeface} from '@components/Charts/hooks';
+import {useChartTypefaces} from '@components/Charts/hooks';
+import getChartSkiaTypeface from '@components/Charts/utils/getChartSkiaTypeface';
 import type {LabelItem} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
 import computeTextAnchorPosition from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/computeTextAnchorPosition';
 
@@ -20,15 +21,21 @@ type ProcessedLine = {
  * Renders floating Skia text labels (from `<victorylabel>` nodes) over the chart canvas.
  * Intended for use inside CartesianChart's `renderOutside` callback.
  */
-function VictoryChartLabel({x, y, text, color, fontSize, fontWeight, lineHeight, textAnchor = 'start', verticalAnchor = 'start'}: VictoryChartLabelsProps) {
-    const {regular: regularTypeface, bold: boldTypeface} = useChartDefaultTypeface();
+function VictoryChartLabel({x, y, text, color, fontSize, fontWeight, fontFamily, fontStyle, lineHeight, textAnchor = 'start', verticalAnchor = 'start'}: VictoryChartLabelsProps) {
+    const typefaces = useChartTypefaces();
     const processedLines = text.split('\n').reduce(
         (acc, line, index) => {
             const lineColor = color?.[index];
             const lineFontSize = fontSize?.[index];
             const lineFontWeight = fontWeight?.[index];
+            const lineFontFamily = fontFamily?.[index];
+            const lineFontStyle = fontStyle?.[index];
             const lineLineHeight = lineHeight?.[index];
-            const typeface = lineFontWeight === 'bold' ? boldTypeface : regularTypeface;
+            const typeface = getChartSkiaTypeface(typefaces, {
+                fontFamily: lineFontFamily,
+                fontStyle: lineFontStyle,
+                fontWeight: lineFontWeight,
+            });
             const lineFont = typeface && lineFontSize ? Skia.Font(typeface, lineFontSize) : null;
             const fontMetrics = lineFont?.getMetrics();
             const lineWidth = lineFont?.getGlyphWidths(lineFont.getGlyphIDs(line)).reduce((totalWidth, width) => totalWidth + width, 0) ?? 0;
@@ -64,6 +71,4 @@ function VictoryChartLabel({x, y, text, color, fontSize, fontWeight, lineHeight,
     });
 }
 
-VictoryChartLabel.displayName = 'VictoryChartLabel';
-
 export default VictoryChartLabel;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLegend.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLegend.tsx
index b7de61bca20f..70d654878b68 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLegend.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartLegend.tsx
@@ -1,7 +1,8 @@
 import {Circle, Skia, Text as SkText} from '@shopify/react-native-skia';
 import type {Color, SkFont} from '@shopify/react-native-skia';
 import React, {Fragment} from 'react';
-import {useChartDefaultTypeface} from '@components/Charts/hooks';
+import {useChartTypefaces} from '@components/Charts/hooks';
+import getChartSkiaTypeface from '@components/Charts/utils/getChartSkiaTypeface';
 import type {LegendItem} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
 
 type VictoryChartLegendProps = LegendItem;
@@ -23,10 +24,10 @@ type ProcessedEntry = {
  * Intended for use inside CartesianChart's `renderOutside` callback.
  */
 function VictoryChartLegend({x, y, entries, gutter, symbolSpacer}: VictoryChartLegendProps) {
-    const {regular: regularTypeface, bold: boldTypeface} = useChartDefaultTypeface();
+    const typefaces = useChartTypefaces();
     const processedEntries = entries.reduce(
-        (acc, {text, color, fontSize, fontWeight, symbolColor, symbolSize}) => {
-            const typeface = fontWeight === 'bold' ? boldTypeface : regularTypeface;
+        (acc, {text, color, fontSize, fontWeight, fontFamily, fontStyle, symbolColor, symbolSize}) => {
+            const typeface = getChartSkiaTypeface(typefaces, {fontFamily, fontStyle, fontWeight});
             const font = typeface && fontSize ? Skia.Font(typeface, fontSize) : null;
             const fontMetrics = font?.getMetrics();
             const lineHeight = fontMetrics ? fontMetrics.ascent + fontMetrics.descent + fontMetrics.leading : 0;
@@ -75,6 +76,4 @@ function VictoryChartLegend({x, y, entries, gutter, symbolSpacer}: VictoryChartL
     });
 }
 
-VictoryChartLegend.displayName = 'VictoryChartLegend';
-
 export default VictoryChartLegend;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPie.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPie.tsx
index 0843a623ce02..8226c772ea6a 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPie.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPie.tsx
@@ -1,7 +1,10 @@
 import React from 'react';
+import {useAmbientTRenderEngine} from 'react-native-render-html';
 import type {TNode} from 'react-native-render-html';
 import {Pie} from 'victory-native';
+import parseVictoryLabelNode from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser';
 import parseAttribute from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseAttribute';
+import parseComponent from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseComponent';
 import VictoryChartPieLabel from './VictoryChartPieLabel';
 
 type VictoryChartPieProps = {tnode: TNode};
@@ -10,6 +13,10 @@ type VictoryChartPieProps = {tnode: TNode};
 const START_ANGLE = 270;
 
 function VictoryChartPie({tnode}: VictoryChartPieProps) {
+    const renderEngine = useAmbientTRenderEngine();
+    const labelComponentNode = parseComponent(tnode.attributes.labelcomponent, renderEngine, 'victorylabel');
+    const labelItemTemplate = labelComponentNode ? parseVictoryLabelNode(labelComponentNode).labelItems?.at(0) : undefined;
+
     const innerRadius = tnode.attributes.innerradius !== undefined ? Number(parseAttribute(tnode.attributes.innerradius)) : undefined;
     const radius = tnode.attributes.radius !== undefined ? Number(parseAttribute(tnode.attributes.radius)) : undefined;
     const size = radius ? radius * 2 : undefined;
@@ -25,6 +32,7 @@ function VictoryChartPie({tnode}: VictoryChartPieProps) {
                     <VictoryChartPieLabel
                         tnode={tnode}
                         slice={slice}
+                        labelItemTemplate={labelItemTemplate}
                     />
                 </Pie.Slice>
             )}
@@ -32,6 +40,4 @@ function VictoryChartPie({tnode}: VictoryChartPieProps) {
     );
 }
 
-VictoryChartPie.displayName = 'VictoryChartPie';
-
 export default VictoryChartPie;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPieLabel.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPieLabel.tsx
index a9ff0dd3ee67..6b99a8361a74 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPieLabel.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPieLabel.tsx
@@ -1,28 +1,23 @@
 import React from 'react';
-import {useAmbientTRenderEngine} from 'react-native-render-html';
 import type {TNode} from 'react-native-render-html';
 import type {PieSliceData} from 'victory-native';
 import {useVictoryChartContext} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext';
-import parseVictoryLabelNode from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser';
-import type {PolarChartData} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
+import type {LabelItem, PolarChartData} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
 import parseAttribute from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseAttribute';
-import parseComponent from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseComponent';
 import VictoryChartLabel from './VictoryChartLabel';
 
 type VictoryChartPieLabelProps = {
     tnode: TNode;
     slice: PieSliceData;
+    labelItemTemplate?: LabelItem;
 };
 
 const RADIAN = Math.PI / 180;
 
-function VictoryChartPieLabel({tnode, slice}: VictoryChartPieLabelProps) {
+function VictoryChartPieLabel({tnode, slice, labelItemTemplate}: VictoryChartPieLabelProps) {
     const {data} = useVictoryChartContext();
-    const renderEngine = useAmbientTRenderEngine();
-    const labelComponentNode = parseComponent(tnode.attributes.labelcomponent, renderEngine, 'victorylabel');
-    const labelItem = labelComponentNode ? parseVictoryLabelNode(labelComponentNode).labelItems?.at(0) : undefined;
 
-    if (!labelItem) {
+    if (!labelItemTemplate) {
         return null;
     }
 
@@ -35,14 +30,15 @@ function VictoryChartPieLabel({tnode, slice}: VictoryChartPieLabelProps) {
     const x = slice.center.x + labelRadius * Math.cos(-midAngle * RADIAN);
     const y = slice.center.y + labelRadius * Math.sin(midAngle * RADIAN);
 
-    labelItem.text = text;
-    labelItem.x = x;
-    labelItem.y = y;
-    labelItem.textAnchor = 'middle';
+    const labelItem: LabelItem = {
+        ...labelItemTemplate,
+        text,
+        x,
+        y,
+        textAnchor: 'middle',
+    };
 
     return <VictoryChartLabel {...labelItem} />;
 }
 
-VictoryChartPieLabel.displayName = 'VictoryChartPieLabel';
-
 export default VictoryChartPieLabel;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPolar.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPolar.tsx
index ebaa6856e2f9..65c7e0233380 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPolar.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/components/VictoryChartPolar.tsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import {PolarChart} from 'victory-native';
+import {ChartFontsProvider} from '@components/Charts/hooks';
 import {COLOR_KEY, LABEL_KEY, VALUE_KEY} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/constants';
 import {useVictoryChartContext} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext';
 import getHierarchyID from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/getHierarchyID';
@@ -20,28 +21,29 @@ function VictoryChartPolar() {
             valueKey={VALUE_KEY}
             colorKey={COLOR_KEY}
         >
-            {tnode.children.map((child) => (
-                <VictoryChartCategories
-                    key={`${child.tagName ?? 'node'}-${getHierarchyID(child)}`}
-                    tnode={child}
-                />
-            ))}
-            {labelItems.map((labelItem) => (
-                <VictoryChartLabel
-                    key={`label-${labelItem.x}-${labelItem.y}`}
-                    {...labelItem}
-                />
-            ))}
-            {legendItems.map((legendItem) => (
-                <VictoryChartLegend
-                    key={`legend-${legendItem.x}-${legendItem.y}`}
-                    {...legendItem}
-                />
-            ))}
+            {/* Chart font context does not propagate into polar Skia children. */}
+            <ChartFontsProvider>
+                {tnode.children.map((child) => (
+                    <VictoryChartCategories
+                        key={`${child.tagName ?? 'node'}-${getHierarchyID(child)}`}
+                        tnode={child}
+                    />
+                ))}
+                {labelItems.map((labelItem) => (
+                    <VictoryChartLabel
+                        key={`label-${labelItem.x}-${labelItem.y}`}
+                        {...labelItem}
+                    />
+                ))}
+                {legendItems.map((legendItem) => (
+                    <VictoryChartLegend
+                        key={`legend-${legendItem.x}-${legendItem.y}`}
+                        {...legendItem}
+                    />
+                ))}
+            </ChartFontsProvider>
         </PolarChart>
     );
 }
 
-VictoryChartPolar.displayName = 'VictoryChartPolar';
-
 export default VictoryChartPolar;
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext.tsx
index a6ee93bc96a9..332d34825f69 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext.tsx
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/context/VictoryChartContext.tsx
@@ -1,6 +1,6 @@
 import React, {createContext, useContext} from 'react';
 import type {TNode} from 'react-native-render-html';
-import {useChartDefaultTypeface} from '@components/Charts/hooks';
+import {useChartTypefaces} from '@components/Charts/hooks';
 import {CHART_TYPE, LABEL_KEY, X_KEY} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/constants';
 import processVictoryChartTree from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/processVictoryChartTree';
 import type {ChartType, ProcessNodeResult} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
@@ -32,8 +32,8 @@ const VictoryChartContext = createContext<VictoryChartContextValue | null>(null)
  * Returns null when the chart data is invalid (no data points, or mixed cartesian/polar content).
  */
 function VictoryChartProvider({tnode, children}: {tnode: TNode; children: React.ReactNode}) {
-    const {regular: regularTypeface} = useChartDefaultTypeface();
-    const {data, xKey, yKeys, xAxis, yAxis, domain, domainPadding, padding, isHorizontal, categories, labelItems, legendItems} = processVictoryChartTree(tnode, regularTypeface, null);
+    const typefaces = useChartTypefaces();
+    const {data, xKey, yKeys, xAxis, yAxis, domain, domainPadding, padding, isHorizontal, categories, labelItems, legendItems} = processVictoryChartTree(tnode, typefaces.EXP_NEUE, null);
     const {nodeStyles: chartContentStyles, parentNodeStyles: chartContainerStyles} = parseStyles(tnode);
 
     const hasCartesianData = Object.values(data).some((entry) => X_KEY in entry);
@@ -75,8 +75,6 @@ function VictoryChartProvider({tnode, children}: {tnode: TNode; children: React.
     return <VictoryChartContext.Provider value={contextValue}>{children}</VictoryChartContext.Provider>;
 }
 
-VictoryChartProvider.displayName = 'VictoryChartProvider';
-
 function useVictoryChartContext(): VictoryChartContextValue {
     const context = useContext(VictoryChartContext);
     if (!context) {
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser.ts b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser.ts
index a244f0b8c32e..78c4b7c61845 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser.ts
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLabelParser.ts
@@ -1,4 +1,5 @@
 import type {TNode} from 'react-native-render-html';
+import normalizeChartFontWeight from '@components/Charts/utils/normalizeChartFontWeight';
 import type {LabelItem, PartialProcessNodeResult, RawLabelStyle, TextAnchor} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
 import parseAttribute from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseAttribute';
 
@@ -13,6 +14,8 @@ function parseVictoryLabelNode(tnode: TNode): PartialProcessNodeResult {
         color: {},
         fontSize: {},
         fontWeight: {},
+        fontFamily: {},
+        fontStyle: {},
         lineHeight: parseAttribute<number[]>(tnode.attributes.lineheight),
         textAnchor: parseAttribute<TextAnchor>(tnode.attributes.textanchor),
         verticalAnchor: parseAttribute<TextAnchor>(tnode.attributes.verticalanchor),
@@ -37,7 +40,19 @@ function parseVictoryLabelNode(tnode: TNode): PartialProcessNodeResult {
             if (textStyle.fontWeight) {
                 labelItem.fontWeight = {
                     ...labelItem.fontWeight,
-                    [index]: Number(textStyle.fontWeight) === 700 ? 'bold' : 'normal',
+                    [index]: normalizeChartFontWeight(textStyle.fontWeight),
+                };
+            }
+            if (textStyle.fontFamily) {
+                labelItem.fontFamily = {
+                    ...labelItem.fontFamily,
+                    [index]: textStyle.fontFamily,
+                };
+            }
+            if (textStyle.fontStyle) {
+                labelItem.fontStyle = {
+                    ...labelItem.fontStyle,
+                    [index]: textStyle.fontStyle,
                 };
             }
         }
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLegendParser.ts b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLegendParser.ts
index ebc83a9ac9fe..6b848196008c 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLegendParser.ts
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/parsers/victoryLegendParser.ts
@@ -1,4 +1,5 @@
 import type {TNode} from 'react-native-render-html';
+import normalizeChartFontWeight from '@components/Charts/utils/normalizeChartFontWeight';
 import type {LegendItem, LegendItemEntry, PartialProcessNodeResult, RawLegendData, RawLegendStyle} from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types';
 import parseAttribute from '@components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/utils/parseAttribute';
 
@@ -13,12 +14,14 @@ function parseVictoryLegendNode(tnode: TNode): PartialProcessNodeResult {
     const style = parseAttribute<RawLegendStyle>(tnode.attributes.style);
     const color = style?.labels?.fill;
     const fontSize = style?.labels?.fontSize !== undefined ? Number(style.labels.fontSize) : undefined;
-    const fontWeight = Number(style?.labels?.fontWeight) === 700 ? 'bold' : undefined;
+    const fontWeight = style?.labels?.fontWeight !== undefined ? normalizeChartFontWeight(style.labels.fontWeight) : undefined;
+    const fontFamily = style?.labels?.fontFamily;
+    const fontStyle = style?.labels?.fontStyle;
     const entries: LegendItemEntry[] = (parseAttribute<RawLegendData[]>(tnode.attributes.data) ?? []).map((entry) => {
         const text = entry.name;
         const symbolColor = entry.symbol?.fill;
         const symbolSize = entry.symbol?.size !== undefined ? Number(entry.symbol.size) : undefined;
-        return {text, color, fontSize, fontWeight, symbolColor, symbolSize};
+        return {text, color, fontSize, fontWeight, fontFamily, fontStyle, symbolColor, symbolSize};
     });
     const legendItem: LegendItem = {x, y, entries, gutter, symbolSpacer};
     return {legendItems: [legendItem]};
diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types.ts b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types.ts
index 51f52d6656c3..4797b16ceb7b 100644
--- a/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types.ts
+++ b/src/components/HTMLEngineProvider/HTMLRenderers/VictoryChartRenderer/types.ts
@@ -36,6 +36,8 @@ type RawLabelStyle = {
     fill?: Color;
     fontSize?: string | number;
     fontWeight?: string | number;
+    fontFamily?: string;
+    fontStyle?: string;
 };
 
 type RawLegendStyle = {
@@ -43,6 +45,8 @@ type RawLegendStyle = {
         fill?: Color;
         fontSize?: string | number;
         fontWeight?: string | number;
+        fontFamily?: string;
+        fontStyle?: string;
     };
 };
 
@@ -81,6 +85,12 @@ type LabelItem = {
     /** Font weight (per line) */
     fontWeight?: Record<number, 'normal' | 'bold'>;
 
+    /** Font family (per line) */
+    fontFamily?: Record<number, string>;
+
+    /** Font style (per line) */
+    fontStyle?: Record<number, string>;
+
     /** Line height (per line) */
     lineHeight?: Record<number, number>;
 
@@ -104,6 +114,12 @@ type LegendItemEntry = {
     /** Font weight */
     fontWeight?: 'normal' | 'bold';
 
+    /** Font family */
+    fontFamily?: string;
+
+    /** Font style */
+    fontStyle?: string;
+
     /** The color of the symbol */
     symbolColor?: Color;
 
diff --git a/tests/unit/components/Charts/VictoryTheme.test.ts b/tests/unit/components/Charts/VictoryTheme.test.ts
index 44f821ce0a26..78525af7b963 100644
--- a/tests/unit/components/Charts/VictoryTheme.test.ts
+++ b/tests/unit/components/Charts/VictoryTheme.test.ts
@@ -1,3 +1,4 @@
+import {CHART_FONT_FAMILY_NAMES} from '@components/Charts/utils/chartFontConstants';
 import type VictoryThemeType from '@components/Charts/VictoryTheme';
 import colors from '@styles/theme/colors';
 
@@ -108,7 +109,7 @@ describe('VictoryTheme', () => {
     describe('static configuration values', () => {
         it('exposes the expected font families in order', () => {
             const VictoryTheme = loadVictoryTheme();
-            expect(VictoryTheme.fontFamilies).toEqual(['ExpensifyNeue', 'NotoSansSymbols', 'NotoSansSCMonths']);
+            expect(VictoryTheme.fontFamilies).toEqual([...CHART_FONT_FAMILY_NAMES]);
         });
 
         it('exposes axis values', () => {
diff --git a/tests/unit/getChartSkiaTypefaceTest.ts b/tests/unit/getChartSkiaTypefaceTest.ts
new file mode 100644
index 000000000000..c627d98a480f
--- /dev/null
+++ b/tests/unit/getChartSkiaTypefaceTest.ts
@@ -0,0 +1,53 @@
+import type {SkTypeface} from '@shopify/react-native-skia';
+import type {ChartDefaultTypeface, ChartSkiaTypefaceKey} from '@components/Charts/types/chartSkiaTypefaceTypes';
+import {CHART_SKIA_TYPEFACE_ASSETS} from '@components/Charts/utils/chartFontAssets';
+import getChartSkiaTypeface from '@components/Charts/utils/getChartSkiaTypeface';
+
+const CHART_SKIA_TYPEFACE_KEYS = Object.keys(CHART_SKIA_TYPEFACE_ASSETS) as ChartSkiaTypefaceKey[];
+
+function makeTypefaces(): ChartDefaultTypeface {
+    return Object.fromEntries(CHART_SKIA_TYPEFACE_KEYS.map((key) => [key, {id: key} as unknown as SkTypeface])) as ChartDefaultTypeface;
+}
+
+describe('getChartSkiaTypeface', () => {
+    const typefaces = makeTypefaces();
+
+    it('should resolve numeric bold weight to the bold typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontWeight: 700});
+        expect(typeface).toBe(typefaces.EXP_NEUE_BOLD);
+    });
+
+    it('should resolve string bold weight to the bold typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontWeight: 'bold'});
+        expect(typeface).toBe(typefaces.EXP_NEUE_BOLD);
+    });
+
+    it('should resolve normal weight to the regular typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontWeight: 400});
+        expect(typeface).toBe(typefaces.EXP_NEUE);
+    });
+
+    it('should resolve semibold numeric weight to the bold typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontWeight: 600});
+        expect(typeface).toBe(typefaces.EXP_NEUE_BOLD);
+    });
+
+    it('should resolve medium numeric weight to the regular typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontWeight: 500});
+        expect(typeface).toBe(typefaces.EXP_NEUE);
+    });
+
+    it('should resolve Expensify New Kansas by font family', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {fontFamily: 'Expensify New Kansas'});
+        expect(typeface).toBe(typefaces.EXP_NEW_KANSAS_MEDIUM);
+    });
+
+    it('should resolve italic Expensify Neue bold to the bold italic typeface', () => {
+        const typeface = getChartSkiaTypeface(typefaces, {
+            fontFamily: 'Expensify Neue',
+            fontStyle: 'italic',
+            fontWeight: 'bold',
+        });
+        expect(typeface).toBe(typefaces.EXP_NEUE_BOLD_ITALIC);
+    });
+});
