Install
$ agentstack add skill-madebyecho-agent-skills-react-native-skia-shaders Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Dangerous shell/eval execution.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
React Native Skia Shaders
A unified skill covering 25+ SKSL shader techniques adapted for @shopify/react-native-skia. SKSL is Skia's portable shading language — a GLSL-like dialect that compiles to Metal (iOS), Vulkan/OpenGL (Android), and WebGPU/WebGL (web). Most ShaderToy / GLSL recipes translate, but the type system, entry point, coordinate system, uniform declaration, and child-shader / image sampling are different. Don't copy-paste GLSL — port it.
When to Apply
Reach for this skill when:
- Writing or porting any SKSL shader for
@shopify/react-native-skia - Building animated backgrounds, mesh gradients, ink/water/glass effects, particle fields
- Distorting, blurring, or color-grading images with `
+or` filters - Composing
BackdropFilterfor live-blur / glassmorphism over scrolling content - Driving shader uniforms from gestures, Reanimated
useSharedValue, oruseClock - Debugging "compilation failed" / black-screen issues in
Skia.RuntimeEffect.Make - Picking a performance budget that won't melt mid-tier Android phones
- Translating a ShaderToy / GLSL snippet to SKSL
Skip this skill for: legacy react-native-svg masks, animated GIF playback, native iOS Metal / Android Vulkan shaders written outside Skia, Three.js/expo-three (those use raw GLSL with a different runtime).
Skill Structure
react-native-skia-shaders/
├── SKILL.md # This file — entry point & routing
├── techniques/ # Implementation guides (read per routing table)
│ ├── rn-skia-integration.md # Canvas, Fill, Shader, RuntimeEffect wiring
│ ├── sksl-vs-glsl.md # Conversion cheatsheet (THE most-used file)
│ ├── uniforms-animation.md # Reanimated, useClock, gesture-driven uniforms
│ ├── child-shaders.md # uniform shader, ImageShader, BackdropFilter
│ ├── image-effects.md # Blur, ColorMatrix, Displacement, RuntimeShader filter
│ ├── mobile-performance.md # GPU budgets, profiling, fallbacks
│ ├── sksl-pitfalls.md # Common SKSL compile errors & fixes
│ ├── sdf-2d.md # 2D signed distance functions
│ ├── sdf-3d.md # 3D signed distance functions
│ ├── ray-marching.md # Sphere tracing with SDF
│ ├── csg-boolean-operations.md # Smooth blends, intersections
│ ├── domain-warping.md # Distort space with noise
│ ├── domain-repetition.md # Infinite repetition, folding
│ ├── lighting-model.md # Phong, Blinn-Phong, PBR-lite
│ ├── shadow-techniques.md # Hard & soft shadows
│ ├── normal-estimation.md # Tetrahedron technique
│ ├── ambient-occlusion.md # SDF AO
│ ├── procedural-noise.md # Value, Perlin, Simplex, FBM
│ ├── voronoi-cellular-noise.md # Worley, F1/F2 distances
│ ├── color-palette.md # Cosine palettes, Oklab, HSL
│ ├── procedural-2d-pattern.md # Bricks, hex, truchet
│ ├── polar-uv-manipulation.md # Polar, kaleidoscope
│ ├── fractal-rendering.md # Mandelbrot, Julia
│ ├── sdf-tricks.md # Hollowing, outlines, debug viz
│ ├── post-processing.md # Bloom, tone mapping, vignette
│ ├── anti-aliasing.md # SDF AA, smoothstep AA
│ ├── matrix-transform.md # Camera look-at, FOV
│ ├── texture-sampling.md # ImageShader sampling patterns
│ ├── atmospheric-scattering.md # Sky, fog, sunset
│ └── particle-system.md # Stateless particles
└── reference/ # Deep-dive math, advanced patterns
├── sksl-vs-glsl.md # Full SKSL spec quick-ref
├── uniforms-animation.md # Reanimated worklet patterns
├── ray-marching.md # Sphere tracing math
├── lighting-model.md # PBR derivations
├── procedural-noise.md # Noise function theory
└── ...
How to Use
- Identify the technique(s) from the Routing Table below.
- Always read
techniques/rn-skia-integration.mdbefore generating any shader code — it shows the exact React component wiring (`→→→RuntimeEffect.Make`) and how to feed uniforms. - Always read
techniques/sksl-vs-glsl.mdbefore porting a GLSL/ShaderToy snippet — the translation is not free. - Read the matched
techniques/*.md— each contains core principles, SKSL-correct code templates, and a worked example. - Follow the reference link at the bottom of each technique file if you need math derivations.
- Apply the Performance Budget (below) — react-native-skia runs on phones, not desktop GPUs.
Technique Routing Table
| User wants to create... | Primary technique | Combine with | |---|---|---| | First-time SKSL shader, "just show me how" | [rn-skia-integration](techniques/rn-skia-integration.md) | sksl-vs-glsl | | Port a ShaderToy / GLSL effect | [sksl-vs-glsl](techniques/sksl-vs-glsl.md) | rn-skia-integration | | Animated background driven by time | [uniforms-animation](techniques/uniforms-animation.md) | procedural-noise, color-palette | | Gesture-controlled distortion | [uniforms-animation](techniques/uniforms-animation.md) | domain-warping, child-shaders | | Distorted / wavy image | [child-shaders](techniques/child-shaders.md) | domain-warping, image-effects | | Glass / frosted / glassmorphism | [child-shaders](techniques/child-shaders.md) + [image-effects](techniques/image-effects.md) | post-processing | | Live blur over scrolling content (BackdropFilter) | [image-effects](techniques/image-effects.md) | child-shaders | | Color grading an image | [image-effects](techniques/image-effects.md) | color-palette | | Displacement map / liquid effect | [image-effects](techniques/image-effects.md) + [domain-warping](techniques/domain-warping.md) | procedural-noise | | Mesh gradient / fluid color blob | [procedural-noise](techniques/procedural-noise.md) | color-palette, domain-warping | | 3D objects / scenes from math | [ray-marching](techniques/ray-marching.md) + [sdf-3d](techniques/sdf-3d.md) | lighting-model, shadow-techniques | | Smooth-blended 3D shapes | [csg-boolean-operations](techniques/csg-boolean-operations.md) | sdf-3d, ray-marching | | Infinite repeating patterns | [domain-repetition](techniques/domain-repetition.md) | sdf-3d, ray-marching | | Organic / warped shapes | [domain-warping](techniques/domain-warping.md) | procedural-noise | | Realistic lighting (Phong, PBR-lite) | [lighting-model](techniques/lighting-model.md) | shadow-techniques, ambient-occlusion | | Soft shadows | [shadow-techniques](techniques/shadow-techniques.md) | lighting-model | | Surface normals from SDF | [normal-estimation](techniques/normal-estimation.md) | sdf-3d | | Ambient occlusion | [ambient-occlusion](techniques/ambient-occlusion.md) | lighting-model, normal-estimation | | Noise / FBM textures | [procedural-noise](techniques/procedural-noise.md) | domain-warping | | Tiled 2D patterns | [procedural-2d-pattern](techniques/procedural-2d-pattern.md) | polar-uv-manipulation | | Voronoi / cell patterns | [voronoi-cellular-noise](techniques/voronoi-cellular-noise.md) | color-palette | | Fractals (Mandelbrot, Julia) | [fractal-rendering](techniques/fractal-rendering.md) | color-palette, polar-uv-manipulation | | Color grading / palettes | [color-palette](techniques/color-palette.md) | — | | Bloom / tone mapping / glitch | [post-processing](techniques/post-processing.md) | child-shaders | | 2D shapes / UI from SDF | [sdf-2d](techniques/sdf-2d.md) | color-palette, anti-aliasing | | Sky / fog / atmospheric | [atmospheric-scattering](techniques/atmospheric-scattering.md) | — | | Stateless particles (sparks, stars) | [particle-system](techniques/particle-system.md) | procedural-noise | | Polar / kaleidoscope | [polar-uv-manipulation](techniques/polar-uv-manipulation.md) | procedural-2d-pattern | | Anti-aliased SDF rendering | [anti-aliasing](techniques/anti-aliasing.md) | sdf-2d | | Camera transforms / look-at | [matrix-transform](techniques/matrix-transform.md) | ray-marching | | Image sampling tricks | [texture-sampling](techniques/texture-sampling.md) | child-shaders | | SDF tricks / optimization | [sdf-tricks](techniques/sdf-tricks.md) | sdf-3d, ray-marching | | "It compiles but is black" / crashes | [sksl-pitfalls](techniques/sksl-pitfalls.md) + [mobile-performance](techniques/mobile-performance.md) | — |
SKSL Quick Reference (most-used translations)
When the user shows you GLSL / ShaderToy code, apply these mechanical rewrites before anything else (full table in [techniques/sksl-vs-glsl.md](techniques/sksl-vs-glsl.md)):
| GLSL / ShaderToy | SKSL (react-native-skia) | |---|---| | void mainImage(out vec4 c, in vec2 fc) | vec4 main(vec2 pos) (or half4 main(float2 pos)) | | Implicit fragColor write | return vec4(...); | | fragCoord / gl_FragCoord.xy | pos (the parameter — already pixel-space, top-left origin) | | iResolution.xy | A uniform float2 resolution; you must pass yourself | | iTime | A uniform float time; driven by useClock() or Reanimated | | iMouse | A uniform float2 touch; driven by Gesture.Pan() | | texture(iChannel0, uv) | image.eval(uv * resolution) with uniform shader image; | | #version 300 es / precision highp float; | Remove — SKSL has no #version | | vec2, vec3, vec4 | Same — or float2/3/4 (interchangeable); prefer half2/3/4 for color math | | mat2, mat3 | float2x2, float3x3 (or keep mat2/mat3 — both work) | | out vec4 fragColor; | Delete — main returns a vec4 instead | | gl_FragCoord.xy / iResolution.xy | pos / resolution |
Critical entry point
Every SKSL shader for react-native-skia returns a color:
uniform float2 resolution;
uniform float time;
vec4 main(vec2 pos) {
vec2 uv = pos / resolution; // 0..1
vec3 col = 0.5 + 0.5 * cos(time + uv.xyx + vec3(0, 2, 4));
return vec4(col, 1.0);
}
pos is pixel-space, top-left origin — same as gl_FragCoord.xy. Aspect-correct UVs:
vec2 uv = (2.0 * pos - resolution) / resolution.y; // -aspect..aspect on x, -1..1 on y
Wiring it into a React component
import { Canvas, Fill, Shader, Skia, useClock } from "@shopify/react-native-skia";
import { useDerivedValue, useWindowDimensions } from "react-native";
const source = Skia.RuntimeEffect.Make(`
uniform float2 resolution;
uniform float time;
vec4 main(vec2 pos) {
vec2 uv = pos / resolution;
return vec4(0.5 + 0.5 * cos(time + uv.xyx + vec3(0,2,4)), 1.0);
}
`)!;
export const Cosmic = () => {
const { width, height } = useWindowDimensions();
const clock = useClock(); // ms shared value
const uniforms = useDerivedValue(() => ({
resolution: [width, height],
time: clock.value / 1000, // seconds
}));
return (
);
};
uniforms accepts a plain object or a Reanimated derived value. The object keys must exactly match the uniform names in the SKSL source. The values must be numbers or arrays of numbers — vectors are arrays (float2 → [x, y]), matrices are flat row-major arrays.
Performance Budget (mobile)
Skia on a phone is not WebGL on a desktop. Be aggressive about cost:
| Limit | iOS (Metal) | Android (mid-tier) | Notes | |---|---|---|---| | Ray-march steps (per pixel) | ≤ 80 | ≤ 48 | Far below the 128 ShaderToy budget | | Volume / shadow inner loops | ≤ 16 | ≤ 8 | Each costs ~1 SDF evaluation | | FBM octaves | ≤ 5 | ≤ 4 | Mid-tier Snapdragons stutter past 4 | | Total inner-loop iterations / pixel | ≤ 500 | ≤ 300 | Beyond this the GPU thread budget breaks 60fps | | Canvas size | Match pixelRatio carefully | Downscale to ~0.75x | A retina-sized full-screen shader is 3x more work than it looks | | pow(), exp(), log(), sin(), cos() | Cheap — use freely | Cheap | Avoid pow(x, 100.0) for sharp specular — use repeated * |
Always test on the lowest-end target device. A shader that hits 60fps on iPhone 15 Pro will often drop to 20fps on a 2022 Pixel 6a. See [techniques/mobile-performance.md](techniques/mobile-performance.md) for profiling.
Common SKSL Pitfalls
(Full list in [techniques/sksl-pitfalls.md](techniques/sksl-pitfalls.md).)
Skia.RuntimeEffect.Make() returns null
The compile failed. Make returns null on error and does not throw. Always:
const source = Skia.RuntimeEffect.Make(sksl);
if (!source) throw new Error("SKSL compile failed");
The current public signature is Skia.RuntimeEffect.Make(sksl: string) — no error callback. If Make returns null, errors are logged to console.log by Skia itself. To diagnose, run the same SKSL in a CanvasKit playground or temporarily wrap with a smaller test shader and bisect the body.
Wrong uniform sizes → silent black
If you declare uniform float3 color; but pass color: [1, 0], the shader silently produces wrong output (sometimes black). Vector arity must match exactly: float2=2, float3=3, float4=4, float3x3=9 floats row-major.
Unused uniforms get pruned
If a uniform is never referenced in the shader body, the compiler removes it. Passing it later throws Uniform not found. Either reference the uniform (= uniform * 0.0 + …) or drop it from the JS side.
texture() doesn't exist in SKSL
Use image.eval(pixelCoords) on a uniform shader image; parameter. Coordinates are in pixels, not UVs — multiply your normalized UV by the image's natural size or by resolution before passing.
Reserved words
SKSL inherits GLSL's reserved-word list and adds a few. Don't name a variable sample, filter, input, output, texture, partition, active, common, cast, patch. Especially sample — it collides with a built-in.
Reanimated values from JS thread
Passing a Reanimated SharedValue directly to uniforms works (Skia integrates with Reanimated). Passing sharedValue.value from JS does not animate — it's captured once. Either use useDerivedValue(() => ({...})) or pass the SharedValue itself (when supported by your version).
Quick Recipes
End-to-end shader recipes assembled from technique modules.
Animated mesh gradient background
- Color: [color-palette](techniques/color-palette.md) cosine palette
- Movement: [domain-warping](techniques/domain-warping.md) low-freq FBM
- Time: [uniforms-animation](techniques/uniforms-animation.md)
useClock - Output: [rn-skia-integration](techniques/rn-skia-integration.md)
//
Glassmorphism card
- Backdrop:
BackdropFilterwrapping aBlur(20)([image-effects](techniques/image-effects.md)) - Refraction: light displacement via a [child-shader](techniques/child-shaders.md) with a normal-map sample
- Edge highlight: [sdf-2d](techniques/sdf-2d.md) rounded rect AA outline
- Composite: stacked `` + glass shader + content
Liquid / ripple distortion over an image
- Source: [`
](techniques/child-shaders.md) as auniform shader` - Distortion: [domain-warping](techniques/domain-warping.md) sin/FBM displacement
- Driver: [uniforms-animation](techniques/uniforms-animation.md)
useClock+ tap position - Polish: [anti-aliasing](techniques/anti-aliasing.md) bilinear sample
Stylized 2D scene
- Shapes: [sdf-2d](techniques/sdf-2d.md) + [sdf-tricks](techniques/sdf-tricks.md) (layered edges)
- Color: [color-palette](techniques/color-palette.md) + [polar-uv-manipulation](techniques/polar-uv-manipulation.md)
- Polish: [anti-aliasing](techniques/anti-aliasing.md) analytic AA + [post-processing](techniques/post-processing.md) vignette
Photoreal ray-marched scene (use sparingly on mobile)
- Geometry: [sdf-3d](techniques/sdf-3d.md) + [csg-boolean-operations](techniques/csg-boolean-
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: madebyecho
- Source: madebyecho/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.