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

@sosweetham/tauri-plugin-sharehub-api

v0.1.3

Published

Share content to and from Tauri 2 apps through the native OS share UI: share out (text/files) and receive shares in (text, links, images, files) as a share target. iOS, Android, macOS, Windows.

Readme

Crates.io Version NPM Version License: MIT

tauri-plugin-sharehub

Bidirectional native sharing for Tauri 2 apps: share text and files out to other apps, and receive text, links, images, and files shared in from other apps as a share target.

Bidirectional

Most share plugins only push content out. sharehub does both:

  • Share OUT. Open the system share sheet to hand text or a file to another app. Backed by UIActivityViewController (iOS), ACTION_SEND (Android), NSSharingServicePicker (macOS), and DataTransferManager (Windows).
  • Share IN. Register your app as a share target so other apps can send it text, links, images, and files. On iOS a copyable Share Extension writes the shared blobs plus a manifest.json into a shared App Group container and opens your app via a deep link. On Android the plugin copies the ACTION_SEND / ACTION_SEND_MULTIPLE streams into the app's files directory. Either way your app reads the queue with getPendingShares() and pulls bytes lazily with readSharedItem(id).

Platform support

| Capability | iOS | Android | macOS | Windows | Linux | | ----------------- | --- | ------- | ----- | ------- | ----- | | Share text (OUT) | yes | yes | yes | yes | no | | Share file (OUT) | yes | yes | yes | yes | no | | Receive shares (IN) | yes | yes | no | no | no |

Desktop receive is a graceful no-op: getPendingShares() resolves to an empty list rather than throwing, so the same code runs everywhere. On Linux the share-out calls are no-ops.

Install

Add the Rust crate to your Tauri app:

cargo add tauri-plugin-sharehub

Add the JavaScript guest bindings with your package manager of choice:

pnpm add @sosweetham/tauri-plugin-sharehub-api
# or: npm add @sosweetham/tauri-plugin-sharehub-api
# or: yarn add @sosweetham/tauri-plugin-sharehub-api

Register the plugin in src-tauri/src/lib.rs:

// src-tauri/src/lib.rs
tauri::Builder::default()
    .plugin(tauri_plugin_sharehub::init())
    // ...

Grant the default permission set in your capability file, e.g. src-tauri/capabilities/default.json:

{
  "permissions": ["sharehub:default"]
}

sharehub:default allows every command: share_text, share_file, get_pending_shares, read_shared_item, and clear_pending_shares.

Usage: share OUT

import { shareText, shareFile } from "@sosweetham/tauri-plugin-sharehub-api";

// Share plain text.
await shareText("Pendi is great!");

// Share a file by file:// URL.
await shareFile("file:///path/to/document.pdf", {
  mimeType: "application/pdf",
  title: "My Document",
});

// Anchor the share sheet (iPad / macOS, in webview coordinates).
await shareText("Hello!", {
  position: { x: 100, y: 200, preferredEdge: "bottom" },
});

Usage: share IN

Your app receives shares by reading a queue. The reliable mechanism is to call getPendingShares() on launch and from your deep-link handler, then read bytes for the items you care about and clear the queue once handled.

import {
  getPendingShares,
  readSharedItem,
  clearPendingShares,
  onShare,
} from "@sosweetham/tauri-plugin-sharehub-api";

async function consumeShares() {
  const { items } = await getPendingShares();
  if (items.length === 0) return;

  for (const item of items) {
    if (item.kind === "text" || item.kind === "url") {
      console.log("shared text/link:", item.text ?? item.url);
    } else {
      // image / file: pull the bytes lazily and wrap them in a File.
      const buf = await readSharedItem(item.id);
      const file = new File([buf], item.name ?? "shared", {
        type: item.mimeType,
      });
      // ...upload or process `file`
    }
  }

  // Only clear once everything has been handled successfully. A mid-flow
  // crash leaves the share for the next launch.
  await clearPendingShares();
}

// Best-effort: fires when a share arrives while the app is already running.
// Silently no-ops where the platform has no live channel, so treat it as a
// nudge on top of the launch-time `getPendingShares()` path, not a replacement.
const unsubscribe = await onShare(() => {
  void consumeShares();
});

Deep-link + App Group model

iOS only lets a separate Share Extension target receive system shares, so it cannot ship inside the plugin: it must be a target in your app. The extension copies the shared blobs plus a manifest.json into a shared App Group container and opens your app at <yourScheme>://share. Your app handles that deep link, navigates to a share screen, and calls getPendingShares().

A copyable extension template (ShareViewController.swift, Info.plist, ShareExt.entitlements) and full setup steps live in extensions/ios/README.md. The key gotchas: the same App Group must be on both the host app and the extension entitlements and registered on your Apple Developer account, and the extension's appScheme must match your tauri-plugin-deep-link scheme.

On Android, add an ACTION_SEND / ACTION_SEND_MULTIPLE intent filter to your main activity in src-tauri/gen/android/app/src/main/AndroidManifest.xml so the system lists your app as a share target, for example:

<intent-filter>
  <action android:name="android.intent.action.SEND" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.SEND_MULTIPLE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="*/*" />
</intent-filter>

The plugin copies the incoming streams into the app's files directory and exposes them through the same getPendingShares() / readSharedItem() API.

Type generation

Every shape that crosses the JS bridge is defined once in Rust, in src/models.rs, and generated outward:

src/models.rs  ->  schemars JSON Schema  ->  Zod (guest-js/schemas.ts)

Run pnpm generate-types after editing src/models.rs to regenerate guest-js/schemas.ts (driven by the dev-only gen Cargo feature). Never edit guest-js/schemas.ts by hand. Inbound payloads cross from arbitrary external apps through messy native parsing, so getPendingShares() validates its result at runtime against the generated Zod schema before returning it. Outbound option types are hand-written in guest-js/index.ts because they are JS-constructed arguments and need no runtime parse.

Credits

The share-OUT path is derived from Choochmeque's tauri-plugin-sharekit (MIT).

License

MIT