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

@feedclip/sdk

v0.1.34

Published

Video feedback SDK for React, Vue, and Angular

Downloads

896

Readme

FeedClip SDK

Video feedback for React, Vue, and Angular.

Website · GitHub · Live examples · Changelog

FeedClip records a selected tab, window, or screen in the browser, with an optional microphone or explicit camera mode. Users can review the clip, capture the current frame, annotate it, and send video, screenshots, written feedback, and product context to a destination you control.

  • React 19, Vue 3, and Angular 19–21
  • TypeScript, ESM, CommonJS, and CSS builds
  • Local preview before anything is submitted
  • Custom HTTP, IndexedDB, Supabase, and S3 transports
  • Optional FeedClip Pro and FeedClip Cloud

Installation

React:

npm install @feedclip/sdk react react-dom

Vue:

npm install @feedclip/sdk vue react react-dom

Angular:

npm install @feedclip/sdk @angular/core react react-dom

The Vue and Angular entrypoints are lifecycle adapters over the same React capture engine, so they also require React 19 and React DOM 19.

React quick start

import FeedClip, {
  createIndexedDbFeedbackStore,
} from "@feedclip/sdk";
import "@feedclip/sdk/style.css";

const saveFeedback = createIndexedDbFeedbackStore({
  databaseName: "my-product-feedback",
});

export function Feedback() {
  return (
    <FeedClip
      config={{
        locale: "en-US",
        maxDurationMilliSeconds: 60_000,
        maxFileSize: 25 * 1024 * 1024,
        defaultVideoFileExtension: "webm",
        defaultVideoFileNameStyle: "ISO 8601",
        onSubmit: saveFeedback,
        // Replace these sample values with your own non-sensitive metadata.
        getContext: () => ({
          accountId: "account-123",
          appVersion: "1.0.0",
        }),
        diagnostics: {
          enabled: true,
        },
      }}
    />
  );
}

IndexedDB keeps submissions in the browser and is useful for local development and the Free examples. For production, provide an authenticated backend or use FeedClip Cloud.

Floating launcher

Use FeedClipLauncher when feedback should open from a chat-style button above your product instead of occupying space in the page layout:

import { FeedClipLauncher } from "@feedclip/sdk";
import "@feedclip/sdk/style.css";

export function AppFeedback() {
  return (
    <FeedClipLauncher
      label="Report a problem"
      position="bottom-right"
      config={{
        locale: "en-US",
        maxDurationMilliSeconds: 60_000,
        maxFileSize: 25 * 1024 * 1024,
        defaultVideoFileExtension: "webm",
        defaultVideoFileNameStyle: "ISO 8601",
        onSubmit: submitFeedback,
      }}
    />
  );
}

The launcher is portaled into document.body, uses a fixed high stacking layer, respects mobile safe areas, and defaults to the bottom-right corner. Opening it never starts a recording or asks for media permission; the customer still explicitly chooses Record screen or Use camera. Escape and the close controls dismiss it and restore focus to the launcher.

Available positions are bottom-right, bottom-left, top-right, and top-left. Use controlled open and onOpenChange props when your own Help menu, support chat, or application state should control the panel. The default English and Russian launcher labels follow config.locale; override label and closeLabel for product-specific wording.

Vue exports FeedClipLauncherVue from @feedclip/sdk/vue. Angular exports FeedClipAngularLauncherComponent from @feedclip/sdk/angular with the <feedclip-launcher> selector.

Vue

<script setup lang="ts">
import FeedClipVue from "@feedclip/sdk/vue";
import { createIndexedDbFeedbackStore } from "@feedclip/sdk";
import "@feedclip/sdk/style.css";

const config = {
  locale: "en-US" as const,
  maxDurationMilliSeconds: 60_000,
  maxFileSize: 25 * 1024 * 1024,
  defaultVideoFileExtension: "webm" as const,
  defaultVideoFileNameStyle: "ISO 8601" as const,
  onSubmit: createIndexedDbFeedbackStore({ databaseName: "feedback" }),
};
</script>

<template>
  <FeedClipVue :config="config" />
</template>

Angular

import { Component } from "@angular/core";
import { FeedClipAngularComponent } from "@feedclip/sdk/angular";
import { createIndexedDbFeedbackStore } from "@feedclip/sdk";
import "@feedclip/sdk/style.css";

@Component({
  selector: "app-feedback",
  standalone: true,
  imports: [FeedClipAngularComponent],
  template: `<feedclip-widget [config]="config" />`,
})
export class FeedbackComponent {
  readonly config = {
    locale: "en-US" as const,
    maxDurationMilliSeconds: 60_000,
    maxFileSize: 25 * 1024 * 1024,
    defaultVideoFileExtension: "webm" as const,
    defaultVideoFileNameStyle: "ISO 8601" as const,
    onSubmit: createIndexedDbFeedbackStore({ databaseName: "feedback" }),
  };
}

Submit to your backend

createFeedbackEndpointTransport sends multipart/form-data containing a JSON payload, the recorded video, an optional screenshot, optional screenshot visualNotes, and an optional Pro-generated thumbnail image file.

import { createFeedbackEndpointTransport } from "@feedclip/sdk";

const onSubmit = createFeedbackEndpointTransport({
  endpoint: "/api/feedback",
  credentials: "include",
});

The endpoint returns a receipt:

interface FeedbackReceipt {
  feedbackId: string;
  status: "received" | "processing" | "completed" | "failed";
  analysis?: FeedbackAnalysis;
  attachments?: Array<{
    kind: "video" | "screenshot" | "thumbnail";
    fileName: string;
    mediaType: string;
    size: number;
    url: string;
  }>;
  issue?: GeneratedIssue;
  error?: "processing_failed";
}

Cloud analysis can include analysis.issueMarkdown: a preformatted Markdown issue body with summary, priority, reproduction steps, context, transcript, and safe opt-in diagnostics. When users click the attached screenshot, FeedClip adds lightweight visual notes with marker coordinates and optional labels, so the generated issue can point engineers to the exact part of the UI. Every additional click creates another marker (up to five), and markers are included automatically when the user uploads the feedback; there is no separate save step. Use it to create GitHub, Linear, Jira, or internal tracker tickets without asking engineers to rewrite the report by hand. It can also include analysis.environment: a compact QA snapshot with the page, browser, operating system, viewport, language, and timezone. FeedClip derives it from the safe browser context already attached to the submission, so engineers do not have to ask “what browser were you using?” after every report. Cloud analysis also includes analysis.triage with impact, reproducibility, and an optional suggested owner to help route feedback to the right team faster. Use analysis.nextActions for a short checklist of engineering or QA follow-ups that can go straight into your tracker or support workflow. Cloud receipts also include private attachment links for the recorded video, screenshot, and thumbnail when present. Those links use the Cloud API and still require project authorization.

The built-in result UI renders safe http and https attachment URLs as compact private links and groups them with the issue-ready report. When Cloud returns analysis, the result UI exposes copy actions for the full Markdown report, a compact bug report, and a QA checklist, so support or QA can paste the right level of detail into GitHub, Linear, Jira, or an internal tracker. Copied reports carry the FeedClip submission ID and processing status, labels, environment, transcript, and safe private evidence links when those fields are available. The QA format turns reproduction steps, expected/actual behavior, next actions, environment, and evidence review into explicit checklist items. If you build your own receipt UI, treat attachments[].url as a private API link, not as a public CDN URL: fetch it through your authenticated backend flow or with a short-lived scoped token. Do not paste permanent project keys into browser code or public issue trackers.

The built-in result UI appears as soon as onSubmit returns a receipt. For asynchronous backends it shows the submission ID and received or processing status while analysis is not yet part of the receipt; completed analysis and issue-export actions are rendered when your onSubmit returns them.

Keep permanent project keys, storage credentials, AI credentials, and service account tokens on the server. Browser integrations should use an authenticated proxy or short-lived scoped tokens.

Configuration

| Property | Required | Description | |---|:---:|---| | locale | Yes | Widget language | | maxDurationMilliSeconds | Yes | Recording duration limit | | maxFileSize | Yes | Maximum submitted video size in bytes | | defaultVideoFileExtension | Yes | webm, mp4, avi, mov, or mkv | | defaultVideoFileNameStyle | Yes | UnixTimestamp, ISO 8601, or Custom | | onSubmit | One handler | Receives the complete feedback submission | | onUpload | One handler | Legacy file-only upload handler | | getContext | No | Adds application-specific metadata | | browserContext | No | Opts into query-string or referrer capture | | diagnostics | No | Configures the default safe capture profile and optional console, failed-network, click, and navigation events | | privacyNotice | No | Adds a privacy-notice link to the widget | | license | No | Enables licensed Pro features | | onLicenseError | No | Advanced troubleshooting callback for license verification errors |

Supported locales: en-US, ru-RU, es-ES, fr-FR, de-DE, it-IT, pt-PT, zh-CN, ja-JP, and ko-KR.

Free, Pro, and Cloud

| Plan | Best for | Included | |---|---|---| | Free | Custom and self-hosted integrations | Screen recording, optional microphone or camera mode, preview frame capture, feedback metadata, screenshot visual notes, IndexedDB, and custom HTTP submissions | | Pro | Self-hosted products that need the complete client SDK | Interactive trim preview with apply/save/cancel controls, thumbnail file export, upload progress, storage helpers, and branding removal | | Cloud | Managed feedback processing | Hosted ingestion, private storage, transcription, structured AI analysis, and Pro SDK features while subscribed |

The Free SDK is MIT-licensed, including commercial use. Pro is a separate project-bound license for client-side features. Cloud is an optional hosted service and does not require exposing permanent API or AI keys in the browser.

See current product details and pricing at feedclip.dev.

Pro license setup

FeedClip Pro is unlocked by a signed project license. After purchasing Pro on feedclip.dev, the success page shows an SDK configuration block containing:

  • token — the signed license token for your project;
  • publicKey — the public verification key used by the browser SDK;
  • issuer, audience, and projectId — values the SDK checks before enabling Pro features.

Pass that object as config.license:

import FeedClip from "@feedclip/sdk";
import "@feedclip/sdk/style.css";

const proLicense = {
  token: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkZDTCJ9...",
  publicKey: {
    kty: "EC",
    crv: "P-256",
    x: "...",
    y: "...",
  },
  issuer: "https://feedclip.dev",
  audience: "@feedclip/sdk",
  projectId: "your-project-id",
};

export function Feedback() {
  return (
    <FeedClip
      config={{
        locale: "en-US",
        maxDurationMilliSeconds: 60_000,
        maxFileSize: 100_000_000,
        defaultVideoFileExtension: "webm",
        defaultVideoFileNameStyle: "ISO 8601",
        license: proLicense,
        onSubmit: async (submission, onProgress) => {
          // Upload to your backend or storage.
        },
      }}
    />
  );
}

The Pro license is safe to verify in the browser: it contains a signed grant and a public key, not a private signing key. Still keep the purchase success page private, bind each license to the intended project, and do not confuse a Pro SDK license with server-side storage credentials.

FeedClip Cloud includes Pro SDK features while the Cloud subscription is active. For Cloud, keep the permanent X-Project-Key on your server, exchange it for a short-lived SDK entitlement through /api/cloud/license, and send only that temporary entitlement to the browser.

Examples

For the most reliable screen-capture experience, open the hosted demos in a top-level browser tab:

Each hosted demo includes a visible integration sample. The StackBlitz links below are useful for exploring source code, but embedded previews may block screen sharing.

Privacy and security

Recordings remain in the browser until the user submits them. By default, FeedClip removes URL credentials, fragments, query strings, and referrers from captured browser context.

Data collection contract

Nothing leaves the browser until the user submits. A normal submission contains:

| Data | Default | Notes | | --- | --- | --- | | Recording file | Yes | Screen or camera stream explicitly selected by the user | | Feedback kind, description, ID, timestamp | Yes | User-entered report and SDK-generated metadata | | Screenshot, thumbnail, visual markers | When created | Only files/markers visible in the review UI | | Page URL and title | Yes | Credentials, fragments, and query string are removed by default | | User agent, language, timezone | Yes | Used to reproduce the browser environment | | Viewport width/height and device pixel ratio | Yes | CSS viewport, not physical display inventory | | Safe diagnostic profile | Yes | Capture outcome/surface, dimensions/FPS, MIME support, permission state, runtime/API availability, recent capture outcomes | | Referrer and URL query string | No | Separate explicit browserContext options | | Product/app metadata | No | Explicit allowlist supplied by your getContext callback | | Console/network/click/navigation events | No | Explicit diagnostics.enabled: true opt-in |

Built-in collection never calls enumerateDevices and does not place device IDs or labels, IP addresses, cookies, local/session storage, credentials, authorization headers, form/input values, clipboard contents, request/response bodies or headers, arbitrary environment variables, a dependency inventory, or other-tab content in the submission payload. Network infrastructure can process connection metadata independently of the SDK payload.

Do not place passwords, access tokens, payment data, or other secrets in getContext. Enable query-string or referrer capture only after reviewing the data your application places there. Link the widget to your privacy notice when required by your use case.

FeedClip attaches a privacy-safe diagnostic profile to each submission by default. It contains an allowlisted capture outcome, capture surface and dimensions, recorder MIME support, camera/microphone permission states, and whether the app is running in a secure top-level or embedded context. It never contains device IDs or labels, IP addresses, cookies, storage, tokens, request bodies, or URL query strings. Disable it only when required:

diagnostics: { safeProfile: false }

Event diagnostics remain opt-in. When diagnostics.enabled is true, the same customContext.feedclipDiagnostics snapshot can also include console errors, failed HTTP requests, clicks, and navigation events. It does not capture request/response bodies, headers, input values, URL query strings, URL fragments, or credentials.

diagnostics: {
  enabled: true,
  maxEvents: 40,
}

The browser cannot safely infer your application stack. Add only the fields your team needs through getContext; they are exported as Product context:

getContext: () => ({
  appVersion: APP_VERSION,
  buildSha: BUILD_SHA,
  environment: 'production',
  framework: 'react',
  frameworkVersion: React.version,
  releaseChannel: 'stable',
})

Do not pass access tokens, user/session objects, cookies, emails, or arbitrary environment variables. Keys that look like credentials are redacted again by Cloud exports, but they should never enter the submission in the first place.

Screen sharing, camera, and microphone capture require HTTPS or localhost, user permission, getDisplayMedia, MediaRecorder, and a media format supported by the browser.

Browsers can block screen capture inside embedded previews even when camera and microphone access is allowed. Open StackBlitz or another embedded preview in a top-level browser tab before starting screen recording. FeedClip detects this case after a failed request and shows a specific new-tab instruction instead of the generic permissions error.

Browser capture compatibility and troubleshooting

FeedClip uses the stream returned by the browser. The browser and operating system own the tab/window/screen picker and the pixels supplied by that stream; the SDK cannot recover pixels when the browser returns an empty or black video track.

The recording lifecycle is exercised in Playwright on Chromium, Firefox, and WebKit for both monitor and window display surfaces. Those tests cover start, pause, resume, first-click stop, browser-controlled sharing termination, full frame preview, and review. Automated CI uses deterministic media streams because headless runners cannot operate the macOS system picker or inspect a physical monitor. Before shipping a browser-specific integration, also run a manual smoke test with the actual operating-system picker.

If screen capture fails or the preview is black:

  1. Open the app in a top-level HTTPS tab, not an embedded preview.
  2. Confirm that the browser has macOS Screen & System Audio Recording permission, then fully restart the browser after changing it.
  3. Update the browser. On macOS 15, Firefox requires Firefox 132 or newer for Mozilla's newer screen-sharing API.
  4. If Firefox returns a black whole-display stream, leave Firefox full-screen mode and retry. If it persists, select a single application window or use current Safari/Chromium for whole-display capture.
  5. If a selected window disappears or the browser's sharing toolbar stops the stream, FeedClip finalizes the available recording and moves to review.

References: Mozilla's macOS 15 guidance, Mozilla's macOS full-screen capture issue, and MediaTrackSettings.displaySurface.

Package entrypoints

import FeedClip from "@feedclip/sdk";
import FeedClipVue from "@feedclip/sdk/vue";
import { FeedClipAngularComponent } from "@feedclip/sdk/angular";
import "@feedclip/sdk/style.css";

The main entrypoint also exports typed feedback contracts, browser-context helpers, HTTP and IndexedDB transports, licensed upload helpers, and license verification utilities.

License

The Free SDK is distributed under the MIT License. Paid FeedClip features and services are covered by the accompanying commercial terms.