Skip to main content
React Native Skia uses its own React renderer. It’s currently impossible to automatically share a React context between two renderers. This means that a React Native context won’t be available from your drawing directly. We recommend preparing the data needed for your drawing outside the <Canvas> element. However, if you need to use a React context within your drawing, you must re-inject it. We found its-fine, also used by react-three-fiber, to provide an elegant solution to this problem.

Using its-fine

import React from "react";
import { Canvas, Fill } from "@shopify/react-native-skia";
import { useTheme, ThemeProvider } from "./ThemeContext";
import { useContextBridge, FiberProvider } from "its-fine";

const MyDrawing = () => {
  const { primary } = useTheme();
  return <Fill color={primary} />;
};

export const Layer = () => {
  const ContextBridge = useContextBridge();
  return (
    <Canvas style={{ flex: 1 }}>
      <ContextBridge>
        <Fill color="black" />
        <MyDrawing />
      </ContextBridge>
    </Canvas>
  );
};

export const App = () => {
  return (
    <FiberProvider>
      <ThemeProvider primary="red">
        <Layer />
      </ThemeProvider>
    </FiberProvider>
  );
};

Example Context Definition

Below is a simple theme context used in the example above:
import type { ReactNode } from "react";
import React, { useContext, createContext } from "react";

interface Theme {
  primary: string;
}

export const ThemeContext = createContext<Theme | null>(null);

export const ThemeProvider = ({
  primary,
  children,
}: {
  primary: string;
  children: ReactNode;
}) => (
  <ThemeContext.Provider value={{ primary }}>
    {children}
  </ThemeContext.Provider>
);

export const useTheme = () => {
  const theme = useContext(ThemeContext);
  if (theme === null) {
    throw new Error("Theme provider not found");
  }
  return theme;
};

Best Practices

Whenever possible, prepare your data outside the Canvas component to avoid the need for context bridging.
  • Keep drawing logic simple and data-driven
  • Pass props directly to canvas children when possible
  • Use context bridging only when necessary
  • Consider using Reanimated shared values for dynamic data

Build docs developers (and LLMs) love