Skip to main content
Image filters modify the appearance of rendered content. They can be applied to individual shapes or groups of elements.

Blur

Applies a Gaussian blur effect.
import { Canvas, Circle, Blur } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={100} color="blue">
    <Blur blur={10} />
  </Circle>
</Canvas>

Props

blur
number | { x: number, y: number }
required
Blur radius in pixels. Can be a single number for both directions or an object with x and y values for directional blur.
mode
TileMode
default:"'decal'"
How the filter extends beyond bounds:
  • clamp: Extends edge pixels
  • repeat: Repeats the image
  • mirror: Mirrors the image
  • decal: Transparent outside (default)

Offset

Shifts the image by a specified distance.
import { Canvas, Circle, Offset } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={50} color="red">
    <Offset x={20} y={20} />
  </Circle>
</Canvas>

Props

x
number
required
Horizontal offset in pixels
y
number
required
Vertical offset in pixels

Shadow

Creates drop shadow or inner shadow effects.
import { Canvas, RoundedRect, Shadow } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <RoundedRect x={50} y={50} width={200} height={200} r={20} color="white">
    <Shadow dx={5} dy={5} blur={10} color="rgba(0,0,0,0.5)" />
  </RoundedRect>
</Canvas>

Props

dx
number
default:"0"
Horizontal shadow offset
dy
number
default:"0"
Vertical shadow offset
blur
number
required
Shadow blur radius
color
Color
default:"'black'"
Shadow color
inner
boolean
default:"false"
If true, creates an inner shadow instead of drop shadow
shadowOnly
boolean
default:"false"
If true, only renders the shadow without the source content

Morphology

Erodes or dilates the image.
import { Canvas, Circle, Morphology } from "@shopify/react-native-skia";

// Dilate (expand)
<Circle cx={150} cy={150} r={50} color="blue">
  <Morphology operator="dilate" radius={5} />
</Circle>

// Erode (shrink)
<Circle cx={150} cy={150} r={50} color="red">
  <Morphology operator="erode" radius={3} />
</Circle>

Props

operator
'erode' | 'dilate'
required
  • erode: Shrinks bright areas
  • dilate: Expands bright areas
radius
number | { x: number, y: number }
required
Morphology radius. Can be uniform or directional.

Displacement Map

Distorts an image based on color channels from another image.
import { Canvas, Image, DisplacementMap, useImage } from "@shopify/react-native-skia";

export default function DisplacementExample() {
  const source = useImage(require("./source.png"));
  const displacement = useImage(require("./displacement.png"));
  
  if (!source || !displacement) return null;
  
  return (
    <Canvas style={{ flex: 1 }}>
      <Image image={source} x={0} y={0} width={300} height={300}>
        <DisplacementMap
          channelX="r"
          channelY="g"
          scale={20}
        >
          <Image image={displacement} x={0} y={0} width={300} height={300} />
        </DisplacementMap>
      </Image>
    </Canvas>
  );
}

Props

channelX
ColorChannel
required
Color channel for X displacement: 'r', 'g', 'b', or 'a'
channelY
ColorChannel
required
Color channel for Y displacement: 'r', 'g', 'b', or 'a'
scale
number
required
Displacement scale factor
children
ReactNode
The displacement map source (usually an Image)

Runtime Shader

Apply custom shader effects as image filters.
import { Canvas, Circle, RuntimeShader, Skia } from "@shopify/react-native-skia";

const source = Skia.RuntimeEffect.Make(`
  uniform shader image;
  uniform float intensity;
  
  half4 main(vec2 coord) {
    half4 color = image.eval(coord);
    float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
    return mix(color, vec4(gray, gray, gray, color.a), intensity);
  }
`);

export default function GrayscaleFilter() {
  return (
    <Canvas style={{ flex: 1 }}>
      <Circle cx={150} cy={150} r={100} color="rainbow">
        <RuntimeShader source={source} uniforms={{ intensity: 0.8 }} />
      </Circle>
    </Canvas>
  );
}

Props

source
SkRuntimeEffect
required
Compiled runtime shader effect
uniforms
Uniforms
Uniform values to pass to the shader

Combining Filters

Chain multiple filters together:
import { Canvas, Rect, Blur, Shadow, Morphology } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Rect x={50} y={50} width={200} height={200} color="purple">
    <Shadow dx={3} dy={3} blur={5} color="rgba(0,0,0,0.3)" />
    <Blur blur={2} />
    <Morphology operator="dilate" radius={1} />
  </Rect>
</Canvas>

Backdrop Filter

Applies filters to content behind an element.
import { Canvas, Circle, Rect, BackdropFilter, Blur } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  {/* Background content */}
  <Circle cx={150} cy={150} r={100} color="red" />
  
  {/* Blurred overlay */}
  <BackdropFilter filter={<Blur blur={10} />}>
    <Rect x={100} y={100} width={100} height={100} color="rgba(255,255,255,0.3)" />
  </BackdropFilter>
</Canvas>

BackdropBlur Component

Convenience component for backdrop blur:
import { Canvas, Circle, Rect, BackdropBlur } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={100} color="blue" />
  
  <BackdropBlur blur={15}>
    <Rect x={100} y={100} width={100} height={100} color="rgba(255,255,255,0.5)" />
  </BackdropBlur>
</Canvas>

Examples

Card with Shadow

import { Canvas, RoundedRect, Shadow } from "@shopify/react-native-skia";

<Canvas style={{ width: 300, height: 200 }}>
  <RoundedRect x={20} y={20} width={260} height={160} r={12} color="white">
    <Shadow
      dx={0}
      dy={4}
      blur={12}
      color="rgba(0, 0, 0, 0.15)"
    />
  </RoundedRect>
</Canvas>

Glow Effect

import { Canvas, Circle, Shadow } from "@shopify/react-native-skia";

<Canvas style={{ flex: 1 }}>
  <Circle cx={150} cy={150} r={50} color="cyan">
    <Shadow dx={0} dy={0} blur={20} color="cyan" shadowOnly />
  </Circle>
  <Circle cx={150} cy={150} r={50} color="cyan" />
</Canvas>

Frosted Glass

import { Canvas, Image, Rect, BackdropBlur, useImage } from "@shopify/react-native-skia";

export default function FrostedGlass() {
  const image = useImage(require("./background.jpg"));
  
  if (!image) return null;
  
  return (
    <Canvas style={{ flex: 1 }}>
      <Image image={image} fit="cover" x={0} y={0} width={300} height={400} />
      
      <BackdropBlur blur={20}>
        <Rect
          x={50}
          y={150}
          width={200}
          height={100}
          color="rgba(255, 255, 255, 0.3)"
        />
      </BackdropBlur>
    </Canvas>
  );
}

Neon Text Effect

import { Canvas, Text, Shadow, matchFont } from "@shopify/react-native-skia";

const font = matchFont({ fontSize: 72, fontWeight: "bold" });

<Canvas style={{ flex: 1 }}>
  <Text x={50} y={150} text="NEON" font={font} color="#00FFFF">
    <Shadow dx={0} dy={0} blur={10} color="#00FFFF" shadowOnly />
    <Shadow dx={0} dy={0} blur={20} color="#00FFFF" shadowOnly />
    <Shadow dx={0} dy={0} blur={30} color="#00FFFF" shadowOnly />
  </Text>
  <Text x={50} y={150} text="NEON" font={font} color="white" />
</Canvas>

Performance Considerations

  • Image filters create offscreen buffers and can be expensive
  • Blur is one of the most expensive filters - use smaller radius values when possible
  • Combining multiple filters compounds the performance cost
  • Use backdrop filters sparingly as they process all content behind the element
  • Consider using simpler effects for animations

Build docs developers (and LLMs) love