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

@facilitronworks/react-native-windows-image-picker

v0.1.0-pre.0

Published

A native image and document picker TurboModule for React Native Windows (new architecture), backed by Windows.Storage.Pickers.FileOpenPicker.

Downloads

124

Readme

@facilitronworks/react-native-windows-image-picker

A native image and document picker TurboModule for React Native Windows on the new architecture (Fabric / Composition), backed by Windows.Storage.Pickers.FileOpenPicker.

Status: pre-release (0.1.0-pre.0), not yet published to npm. The C++ implementation is extracted from a shipping production Windows app (RNW 0.83.2, Windows-on-ARM and x64) where it backs real image and file-attachment upload flows.

Build-verified. The packaged form compiles: autolinked into a consuming RNW 0.83.2 new-arch app and built clean for ARM64 Debug, producing RNWImagePicker.dll, .winmd, .lib and .pri. autolink-windows correctly emits both #include <winrt/RNWImagePicker.h> and packageProviders.Append(winrt::RNWImagePicker::ReactPackageProvider()).

Not yet verified: runtime behaviour of this project's DLL on-device (the source is production-proven, but the binary built from this project has not been exercised), x64 and Release configurations, and there is no example app or CI build yet. Wait for 0.1.0 before depending on it in production.

Building it yourself: run a NuGet restore first (msbuild -restore). Without it the CppWinRT targets never load, .idl files fall through to classic midl.exe instead of midlrt, and every namespace declaration fails with MIDL2025.

Why this exists

There is no maintained file/image picker for React Native Windows. This isn't an oversight — every upstream door has been tried and closed:

  • @react-native-documents/picker dropped Windows, and the maintainer declined to take it back: "No one has stepped up to maintain it in years. I don't think it's a good idea to add it into this repo (because it will, again, be unmaintained)."
  • React Native Windows core has no plan to ship one: "AFAIK there's no plan to expose a built-in way to access windows file pickers for RNW... you'd probably need to expose the APIs yourself, like you said, with your own Turbo Module."
  • expo-image-picker has no Windows implementation, and Expo's additional platform support covers only macOS and tvOS.
  • react-native-image-picker has had open Windows requests since 2021 and 2023, both unanswered.

RNW's own native module docs point at exactly this outcome: publish your own library when "an existing library doesn't already exist (or you don't have permission to modify it)."

Related prior art

If you only need document/folder picking, look at @hbannro/rn-documents-picker-windows first — it's MIT, new-arch, mirrors the @react-native-documents/picker API, and solves the HWND problem correctly. It targets RNW 0.77 and has no image-specific surface (no dimensions, base64, or image-restricted filtering), which is why this package exists separately rather than as a PR to it.

The hard part: IInitializeWithWindow

This is the trap that catches everyone, and the main reason this code is worth sharing.

On a WinAppSDK / Win32 desktop app there is no CoreWindow. A FileOpenPicker tries to parent itself to one, doesn't find it, and throws — usually surfacing as an opaque E_FAIL or a hang, with nothing pointing at the real cause. The picker must be explicitly associated with the app's top-level HWND through the classic COM interface IInitializeWithWindow:

#include <shobjidl_core.h>

auto initWithWindow = picker.as<::IInitializeWithWindow>();
initWithWindow->Initialize(ResolveHostWindow());

Two further constraints that are easy to get wrong:

  1. The pick must run on the UI thread. The dialog is modal and owned by the app window. This module hops onto the RNW dispatcher with a small ResumeOnDispatcher coroutine awaiter before creating or showing the picker.
  2. The HWND must be a real top-level window. This module prefers a handle registered once from WinMain, then falls back to GetActiveWindow() and GetForegroundWindow() — both valid fallbacks precisely because the pick already runs on the thread that owns the app window.

Installation

npm install @facilitronworks/react-native-windows-image-picker
# or: yarn add @facilitronworks/react-native-windows-image-picker

Then autolink and rebuild:

npx react-native autolink-windows
npx react-native run-windows

That is all the build wiring there is. The package ships a real windows/RNWImagePicker/RNWImagePicker.vcxproj plus a react-native.config.js declaring it as a direct Windows dependency, so autolink-windows adds the ProjectReference to your app project and emits the provider registration into your generated AutolinkedNativeModules.g.cpp. There is nothing to copy, and nothing to add to your own .vcxproj.

Requires the new architecture<RnwNewArch>true</RnwNewArch> in your app's windows/ExperimentalFeatures.props. Developed against RNW 0.83.x.

Integration

Autolinking registers the module — the attributed REACT_MODULE is picked up by this library's own ReactPackageProvider, which calls AddAttributedModules(packageBuilder, true) on your behalf. It is then reachable from JS as NativeModules.RNWImagePicker, or through the typed wrappers in src/index.ts (see Usage).

One manual step remains: the host window. Autolinking cannot register your HWND, so this hook stays yours. Call it once from WinMain, after the app window is created:

// <winrt/RNWImagePicker.h> is already pulled in for you by AutolinkedNativeModules.g.h
winrt::RNWImagePicker::ImagePicker::SetHostWindow(reinterpret_cast<uint64_t>(hwnd));

SetHostWindow is projected as a static on an ImagePicker runtimeclass rather than exposed as a plain C++ function, because autolinking hands your app this library's WinMD projection (<winrt/RNWImagePicker.h>) but not its raw headers — and the library links as its own DLL, whose exports are just the WinRT activation entry points. The internal free function RNWImagePicker::SetHostWindow(void*) still exists for anyone vendoring the sources directly.

Why it matters: this is the one fully reliable source for the window the picker must parent to — it is captured directly from the AppWindow the RNW host created, rather than inferred. If you skip it the GetActiveWindow / GetForegroundWindow fallbacks usually work, but "usually" is not what you want behind a modal dialog.

A future version will prefer ReactCoreInjection::GetTopLevelWindowId(context.Properties().Handle()) so the WinMain hook becomes optional. The current fallback chain is the version that has actually shipped, so it is what is published here.

Usage

import {
  launchImageLibraryAsync,
  launchDocumentPickerAsync,
  isAvailable,
} from '@facilitronworks/react-native-windows-image-picker';

// Pick a single image
const result = await launchImageLibraryAsync({ base64: false });
if (!result.canceled) {
  const [asset] = result.assets!;
  console.log(asset.uri, asset.width, asset.height, asset.mimeType);
}

// Pick one or more arbitrary documents
const docs = await launchDocumentPickerAsync();
if (!docs.canceled) {
  for (const doc of docs.assets!) {
    console.log(doc.fileName, doc.fileSize, doc.mimeType);
  }
}

Result shape

{
  canceled: false,
  assets: [
    {
      uri: 'file:///.../LocalState/PickedFiles/<name>',
      fileName: 'photo.jpg',
      mimeType: 'image/jpeg',
      fileSize: 1048576,
      type: 'image',   // 'file' for documents
      width: 4032,     // images only
      height: 3024,
      base64: undefined,  // only when requested
      exif: null
    }
  ]
}

Cancelling resolves { canceled: true, assets: null } — it does not reject. Rejection is reserved for genuine failures.

Why files are copied

Every picked file is copied into LocalFolder\PickedFiles and the returned uri points at that copy. A StorageFile handed back by the picker carries broker-mediated access that does not reliably survive being passed to other subsystems as a plain path; copying gives you a stable location you can read, upload, and retry against. The module sweeps stale copies once per process on init, since nothing else ever deletes them.

API

| Function | Description | | --- | --- | | launchImageLibraryAsync(options?) | Pick a single image (image file types only). | | launchDocumentPickerAsync(options?) | Pick one or more files of any type. | | requestMediaLibraryPermissionsAsync(writeOnly?) | Always granted on desktop; for API symmetry. | | getMediaLibraryPermissionsAsync(writeOnly?) | As above. | | isAvailable() | true when running on Windows with the native module registered. |

options.base64 is the only option honoured today. quality and selectionLimit are accepted and ignored by launchImageLibraryAsync (single-select).

Roadmap

  • [x] Standalone .vcxproj + ReactPackageProvider + react-native.config.js so this installs and autolinks as a normal package
  • [ ] Verify the project actually compiles, and autolinks cleanly into a real app
  • [ ] ReactCoreInjection::GetTopLevelWindowId to make the WinMain hook optional
  • [ ] Example app + CI build
  • [ ] Camera capture (currently a separate module)
  • [ ] Folder picking / save picker
  • [ ] Publish to npm and register in react-native-community/directory

Contributing

Issues and PRs welcome — particularly build-wiring and RNW version-compat reports. This is maintained as a byproduct of a production app, so the honest maintenance promise is: it will keep working on the RNW versions that app ships on.

License

MIT — see LICENSE.