npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dahab-tech/react-native-media-editor

v0.3.2

Published

Customizable photo & video editor for Expo / React Native with RTL support

Readme

@dahab-tech/react-native-media-editor

The React Native photo & video editor SDK for Expo — customizable, RTL-first, free and MIT-licensed.

→ Full docs & demo at dahab-tech.com/apps/react-native-media-editor

  • Photo: crop with straighten dial + aspect presets, 15 adjustments, 64 built-in filters, overlays, selective focus (radial + linear tilt-shift), draw (4 brushes), text with per-line pill backgrounds, stickers/emoji, multi-photo batch, full-resolution export.
  • Video: trim (lossless passthrough), crop, cover selection, filters + adjustments with live preview, playback speed (audio retimed), text/sticker/draw layers burned into export, opt-in compression — powered by AVFoundation (iOS) and Media3 Transformer (Android). No FFmpeg.
  • RTL & i18n: English and Arabic built in, custom strings supported, per-editor direction control (no global I18nManager reliance).
  • Theming: light + dark themes, fully overridable colors/spacing/radius.

Installation

npx expo install @dahab-tech/react-native-media-editor

Autolinking picks up the native module, and expo install auto-adds the SDK's config plugin to your app.json (only matters for VideoEditor on Android — see below).

Requires a development build (Expo Go is not supported because the package contains native code):

npx expo run:ios   # or run:android

Optional peer dependencies

Only install what you use:

| Feature | Extra dependencies | | --- | --- | | PhotoEditor component | npx expo install @shopify/react-native-skia react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context @expo/vector-icons expo-font | | VideoEditor component | npx expo install @shopify/react-native-skia expo-video react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context @expo/vector-icons expo-font | | Functional video API (trimVideo, getVideoThumbnail, getVideoInfo) | none |

Both editors need @shopify/react-native-skia (the video editor renders its effects preview and overlays with Skia too) and react-native-reanimated v4+ with react-native-worklets. On Android, VideoEditor requires minSdkVersion 26+ — Skia's video decoder throws below 26 on every device. The SDK's config plugin raises it for you; npx expo install adds it automatically, or add it yourself:

{
  "expo": {
    "plugins": ["@dahab-tech/react-native-media-editor"]
  }
}

The plugin is raise-only — it never lowers a minSdkVersion you've set higher — and photo-only apps can skip it. Bare React Native projects set android.minSdkVersion=26 in android/gradle.properties manually. The default Expo template already ships most peers, so usually only @shopify/react-native-skia and/or expo-video are new. A Metro Unable to resolve module <package> error means that peer is missing: install it and rebuild your development build.

Usage

Video editor (trim, crop, cover, filters, adjustments, speed, text/sticker/draw layers)

import { VideoEditor } from '@dahab-tech/react-native-media-editor/videoEditor';

<VideoEditor
  source={videoUri}
  onCancel={() => {}}
  onExport={(result) => console.log(result.uri, result.durationMs)}
  // Fires when the user picks a cover; defaults to the exported video's first frame otherwise.
  onCoverSelected={(cover) => console.log(cover.uri)}
  onError={(error) => console.warn(error)}
/>

Functional video API (no UI, no extra dependencies)

import {
  getVideoInfo,
  getVideoThumbnail,
  trimVideo,
} from '@dahab-tech/react-native-media-editor';

const info = await getVideoInfo(videoUri);
// { durationMs, width, height, rotation, fps } — display dimensions, rotation applied

const trimmed = await trimVideo(videoUri, { startMs: 1000, endMs: 6000 });
// { uri, durationMs } — lossless passthrough when the source allows it

const cropped = await trimVideo(videoUri, {
  startMs: 1000,
  endMs: 6000,
  crop: { x: 100, y: 50, width: 640, height: 360 }, // display-space pixels; forces re-encode
});

const compressed = await trimVideo(videoUri, {
  startMs: 0,
  endMs: 30_000,
  compression: { preset: 'medium', maxDimension: 1080 }, // presence forces re-encode
});
// `compression.preset` = 'high' | 'medium' | 'low' (bpp/frame heuristic on OUTPUT dims)
// `compression.maxDimension` caps the long edge post-crop; never upscales
// `compression.bitrateMbps` overrides `preset` when you need an exact target

const cover = await getVideoThumbnail(videoUri, {
  timeMs: 2500,
  quality: 0.9,
  maxWidth: 720,
});
// { uri, width, height }

Photo editor

import { PhotoEditor } from '@dahab-tech/react-native-media-editor/photoEditor';

<PhotoEditor
  source={photoUri}
  onCancel={() => {}}
  onExport={(result) => console.log(result.width, result.height)} // result.base64 = JPEG
  exportQuality={90}
/>

Built-in tools: Crop (free/1:1/4:3/16:9/9:16 aspect presets, straighten dial, 90° rotate, flip), Adjust (15 parameters including brightness, contrast, saturation, exposure, highlights/shadows, temperature/tint, sharpen, structure, vignette), Filters (64 built-in presets with live previews), Overlays (Light + Mood packs), Focus (radial + linear tilt-shift), Draw (4 brushes), Text (draggable overlays with color, font, alignment, and per-line pill backgrounds), and Stickers/emoji. Multi-photo batch mode is supported. Export renders at the image's intrinsic resolution, not the screen size.

RTL & localization

English and Arabic ship built in. Pass locale to switch, or provide your own strings:

<VideoEditor source={uri} locale="ar" />

<VideoEditor
  source={uri}
  locale="fr"
  strings={{ cancel: 'Annuler', export: 'Exporter' /* ... */ }}
  direction="auto" // 'ltr' | 'rtl' | 'auto' (default: from locale, then I18nManager)
/>

Layout direction is resolved per editor: explicit direction prop → locale script → I18nManager. The trim timeline intentionally stays LTR in RTL locales, matching platform media conventions.

Theming

<VideoEditor
  source={uri}
  theme={{ colors: { accent: '#FF375F', background: '#000000' } }}
/>

Any subset of colors, spacing, and radius can be overridden; the rest falls back to the default dark theme.

Output files

Trimmed videos and thumbnails are written to the app's cache directory (caches/MediaEditor/). Move them somewhere permanent (e.g. with expo-file-system) if you need them to survive cache eviction.

Example app

See example/ for a working demo with a video picker, photo picker, and an English/Arabic RTL toggle.

License

MIT © DahabTech LLC