# VidStr
> VidStr is a Nostr video client (YouTube-like UX) built on NIP-71 video events. Version 2026.09.15.2. It reads and publishes regular (kind 21/22), addressable (kind 34235/34236), and legacy no-imeta video events; surfaces kind 1 notes linking video files; archives plebs.app uploads (#pv69420); uploads media to Blossom servers; and streams feeds from Nostr relays in realtime. The app sends no Referer header (``), so media on referer-checking hosts (e.g. x.com) plays.
VidStr is a client-side single-page React app and an installable PWA: a
service worker precaches the app shell and runtime-caches same-origin
assets, so it works fully offline after the first load. All content comes
from public Nostr relays; all media comes from Blossom servers. There is no
backend.
Key features:
- Feeds: Global and Subscribed (kind 3 follow list) feeds, separated into
horizontal "Videos" (kind 21/34235) and vertical "Shorts" (kind 22/34236)
so vertical floods can't displace horizontal content, plus a "Notes" feed
of kind 1 notes that link video files (detected client-side via imeta tags
or video file URLs in the content), plus "Plebs" tabs (main page and
profile pages) archiving plebs.app uploads (#pv69420) with the
triple-published events (regular, addressable, kind 1) deduped by video
URL — surviving single events are shown too.
Feeds stream from every read relay simultaneously and paint incrementally;
subscriptions stay open after EOSE for realtime updates. Each kind is
queried with its own filter object in the same REQ so every kind gets its
own relay-side limit budget (per NIP-01). Infinite scroll via `until`
cursors.
- Filters on every listing: NIP-05-only mode (on by default — only videos
whose author's kind 0 metadata declares a valid NIP-05 identifier, verified
via cached batched kind 0 fetches), hide/show videos with kind 1984 reports
(hidden by default), YouTube-link videos, videos without determinable
duration, note videos, and a dual-handle min/max duration range slider
(applies to videos with a known duration; persisted across sessions).
- Thumbnails & previews: videos without a thumbnail get a frame extracted
client-side from the video file (hidden