Skip to main content
Image filters apply effects to rendered content, including blur, shadows, displacement, and more. They operate on the entire rendered output.

Blur

Apply a Gaussian blur effect.
NameTypeDescription
blurnumber or VectorBlur radius (x and y)
modeTileModeEdge handling mode (default: “decal”)
childrenReactNodeContent to apply filter to
import { Canvas, Circle, Blur } from "@shopify/react-native-skia";

const BlurDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <Circle cx={128} cy={128} r={64} color="blue">
        <Blur blur={10} />
      </Circle>
    </Canvas>
  );
};

Blur with Vector Radius

Apply different blur amounts horizontally and vertically:
<Blur blur={{ x: 20, y: 5 }} />

Tile Modes

  • "clamp" - Clamp to edge colors
  • "repeat" - Repeat the image
  • "mirror" - Mirror the image
  • "decal" - Transparent outside (default)
<Blur blur={10} mode="clamp" />

Shadow

Add drop shadow or inner shadow effects.
NameTypeDescription
dxnumberHorizontal shadow offset
dynumberVertical shadow offset
blurnumberShadow blur radius
colorColorShadow color
innerbooleanInner shadow (default: false)
shadowOnlybooleanOnly show shadow (default: false)
childrenReactNodeContent to apply filter to
import { Canvas, RoundedRect, Shadow } from "@shopify/react-native-skia";

const ShadowDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <RoundedRect x={50} y={50} width={156} height={156} r={20} color="white">
        <Shadow dx={4} dy={4} blur={8} color="rgba(0, 0, 0, 0.3)" />
      </RoundedRect>
    </Canvas>
  );
};

Inner Shadow

<Shadow dx={2} dy={2} blur={4} color="black" inner />

Shadow Only

Render only the shadow without the original content:
<Shadow dx={4} dy={4} blur={8} color="black" shadowOnly />

Offset

Offset the rendered content.
NameTypeDescription
xnumberHorizontal offset
ynumberVertical offset
childrenReactNodeContent to apply filter to
import { Canvas, Circle, Offset } from "@shopify/react-native-skia";

const OffsetDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <Circle cx={128} cy={128} r={64} color="blue">
        <Offset x={10} y={10} />
      </Circle>
    </Canvas>
  );
};

Morphology

Apply erosion or dilation effects.
NameTypeDescription
operator"erode" or "dilate"Morphology operation
radiusnumber or VectorEffect radius
childrenReactNodeContent to apply filter to
import { Canvas, Text, Morphology, useFont } from "@shopify/react-native-skia";

const MorphologyDemo = () => {
  const font = useFont(require("./font.ttf"), 32);

  if (!font) return null;

  return (
    <Canvas style={{ flex: 1 }}>
      <Text text="Dilated" x={32} y={64} font={font} color="black">
        <Morphology operator="dilate" radius={2} />
      </Text>
      <Text text="Eroded" x={32} y={128} font={font} color="black">
        <Morphology operator="erode" radius={1} />
      </Text>
    </Canvas>
  );
};

DisplacementMap

Displace pixels using a displacement map.
NameTypeDescription
channelXColorChannelChannel for X displacement
channelYColorChannelChannel for Y displacement
scalenumberDisplacement scale
childrenReactNodeContent and displacement map
import { Canvas, Image, DisplacementMap } from "@shopify/react-native-skia";

const DisplacementDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <Image image={sourceImage} x={0} y={0} width={256} height={256}>
        <DisplacementMap channelX="r" channelY="g" scale={20}>
          <Image image={displacementMap} x={0} y={0} width={256} height={256} />
        </DisplacementMap>
      </Image>
    </Canvas>
  );
};

Color Channels

  • "r" - Red channel
  • "g" - Green channel
  • "b" - Blue channel
  • "a" - Alpha channel

RuntimeShader

Apply a custom shader as an image filter.
NameTypeDescription
sourceSkRuntimeEffectRuntime shader effect
uniformsUniformsShader uniform values
childrenReactNodeContent to apply filter to
import { Canvas, Circle, RuntimeShader, Skia } from "@shopify/react-native-skia";

const RuntimeShaderDemo = () => {
  const source = Skia.RuntimeEffect.Make(`
    uniform shader image;
    uniform float brightness;

    half4 main(float2 xy) {
      half4 color = image.eval(xy);
      return color * brightness;
    }
  `);

  if (!source) return null;

  return (
    <Canvas style={{ flex: 1 }}>
      <Circle cx={128} cy={128} r={64} color="blue">
        <RuntimeShader source={source} uniforms={{ brightness: 1.5 }} />
      </Circle>
    </Canvas>
  );
};

Combining Image Filters

Image filters can be composed to create complex effects:
import { Canvas, RoundedRect, Blur, Shadow, Morphology } from "@shopify/react-native-skia";

const CombinedFiltersDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <RoundedRect x={50} y={50} width={156} height={156} r={20} color="white">
        <Shadow dx={4} dy={4} blur={8} color="rgba(0, 0, 0, 0.2)" />
        <Blur blur={2} />
        <Morphology operator="dilate" radius={1} />
      </RoundedRect>
    </Canvas>
  );
};

Blur with Image

Common pattern for blurred images:
import { Canvas, Image, Blur, useImage } from "@shopify/react-native-skia";

const BlurredImageDemo = () => {
  const image = useImage(require("./photo.jpg"));

  if (!image) return null;

  return (
    <Canvas style={{ flex: 1 }}>
      <Image image={image} x={0} y={0} width={256} height={256} fit="cover">
        <Blur blur={15} mode="clamp" />
      </Image>
    </Canvas>
  );
};

Performance Considerations

  • Image filters can be computationally expensive
  • Large blur radii significantly impact performance
  • Consider using smaller blur radii or downsampling for better performance
  • Combine filters judiciously to maintain 60 FPS

Imperative API

Create image filters imperatively:
import { Skia, TileMode } from "@shopify/react-native-skia";

const blurFilter = Skia.ImageFilter.MakeBlur(10, 10, TileMode.Decal, null);
const shadowFilter = Skia.ImageFilter.MakeDropShadow(
  4, 4, 8, 8,
  Skia.Color("rgba(0, 0, 0, 0.3)"),
  null
);

const paint = Skia.Paint();
paint.setImageFilter(blurFilter);

Build docs developers (and LLMs) love