RivePeek is a native Windows Shell preview handler that renders animated
Rive .riv files live in the File Explorer preview pane —
the same mechanism Windows uses to preview PDFs, Office documents and images.
Select a .riv file with the preview pane open (Alt + P) and the default
artboard plays, fit and centered, isolated inside Windows' prevhost.exe
surrogate process so a malformed file can never destabilize Explorer.
It also registers an IThumbnailProvider, so .riv files show a static
first-frame thumbnail as their icon in the Explorer file grid.
RivePeek in File Explorer — static .riv thumbnails in the grid and a live, animated preview pane.
Headless render (rivshot) |
Live preview pane (captured from the real COM handler) |
|---|---|
![]() |
![]() |
Validated against 887 marketplace
.rivfiles: 886 render successfully (99.9%). The single outlier is rejected asmalformedby the Rive runtime itself during import.
- 🎬 Animated preview pane — the default artboard's state machine (or first animation) plays live while the file is selected.
- 🖼️ Static thumbnails — first-frame
.rivthumbnails as grid icons viaIThumbnailProvider. - 🔤 Text rendering —
WITH_RIVE_TEXTenabled, shaping via HarfBuzz + SheenBidi (statically linked); text runs draw with the Direct2D backend. - 📐 Flexbox layout —
WITH_RIVE_LAYOUTenabled, backed by Yoga, so layout-driven artboards and responsive components position correctly. - 🛡️ Process-isolated + fault-guarded — runs in Windows'
prevhost.exesurrogate, and load/advance/draw/teardown are wrapped in SEH so even a pathological file degrades to a blank preview instead of crashing the host. - 💤 Idles when backgrounded — animation pauses when the host/preview isn't in the foreground, and resizes never steal focus from Explorer's file list.
- 🪶 Self-contained — the core Rive runtime plus HarfBuzz/SheenBidi are
compiled in; rendering is pure Direct2D + WIC.
RivePeek.dlllinks the static CRT and needs no redistributables. - 🔒 Per-user install — registers under
HKCU; no administrator rights. - 🧪 Headless tooling —
rivshotrenders any.rivto PNG and validates a whole corpus.
Windows previews files through COM components hosted out-of-process. When you
select a .riv file:
- Explorer reads
HKCR\.riv\ShellEx\{8895b1c6-…}to find the preview handler's CLSID. - The handler's
AppIDpoints at theprevhost.exesurrogate, so Windows loadsRivePeek.dllinto that isolated host — not intoexplorer.exe. - Explorer hands the file to the handler as a read-only
IStream(IInitializeWithStream), then gives it anHWND+ bounding rectangle (IPreviewHandler::SetWindow) and callsDoPreview(). - RivePeek parses the file with the Rive C++ runtime, then draws every frame with a Direct2D renderer into a child window, advancing the default state machine (or first animation) on a ~30 fps timer.
Rather than compiling Rive's heavyweight GPU "Rive Renderer" (and its shader dependency chain), RivePeek implements Rive's two abstract embedding interfaces directly on top of Direct2D + WIC:
rive::Factory→D2DFactory: builds paths (ID2D1PathGeometry), solid/linear/radial brushes, and decodes images via WIC.rive::Renderer→D2DRenderer: mapssave/restore,transform,clipPath(geometry-mask layers),drawPath(fill/stroke),drawImage, anddrawImageMesh(per-triangle affine-textured fills) onto anID2D1RenderTarget. Non-srcOverblend modes are composited with the Direct2DBlendeffect (viaID2D1DeviceContext).
The same backend powers a WIC bitmap render target for headless thumbnail generation (no GPU or window required), which doubles as the test harness.
The core Rive runtime is compiled with text (WITH_RIVE_TEXT, linking
HarfBuzz + SheenBidi) and layout (WITH_RIVE_LAYOUT, linking Yoga) enabled;
audio and scripting stay #ifdef-guarded off (see Limitations).
src/
guids.hpp CLSID + registration constants
rive_d2d.hpp/.cpp Direct2D implementation of rive::Factory + rive::Renderer
rive_scene.hpp/.cpp loads a .riv, instantiates artboard + state machine, draws
preview_handler.* the COM handler (IPreviewHandler, IInitializeWithStream,
IOleWindow, IObjectWithSite, IPreviewHandlerVisuals,
IThumbnailProvider)
dllmain.cpp COM class factory, DLL exports, (un)registration
rivepeek.def exported entry points
tools/
rivshot.cpp headless .riv → .png renderer / validation harness
preview_test.cpp in-process integration test of the full COM pipeline
surrogate_test.cpp out-of-process (prevhost.exe) activation test
thumb_test.cpp IThumbnailProvider test (.riv → thumbnail .png)
build/ MSVC build scripts (no CMake required)
install/ register.ps1 / unregister.ps1 / RivePeek.reg
rive-runtime/ Rive C++ runtime (git submodule)
third_party/ HarfBuzz + SheenBidi (text) and Yoga (layout), gitignored
(see get_text_deps.bat / get_yoga.bat)
- Download
RivePeek.dll(and theinstallscripts) from the latest release. - Put
RivePeek.dllsomewhere stable, e.g.%LOCALAPPDATA%\RivePeek\. - Register it (per-user, no admin):
.\install\register.ps1 -Dll "$env:LOCALAPPDATA\RivePeek\RivePeek.dll"
- In Explorer, press Alt + P for the preview pane and select a
.rivfile.
Prefer to build from source? See below.
Requirements: Visual Studio 2022 Build Tools (MSVC v143) and the Windows 10/11 SDK. No CMake needed — the build scripts configure the toolchain themselves.
git clone --recurse-submodules https://github.com/ajsb85/rive-peek.git
cd rive-peek
build\build_all.batbuild_all.bat first runs get_text_deps.bat and get_yoga.bat, which clone
the dependencies into third_party/ (~160 MB) — needs git and network access
on the first build. They are pinned to the revisions Rive uses
(rive-app/harfbuzz @ rive_13.1.1, Tehreer/SheenBidi @ v2.6,
rive-app/yoga @ rive_changes_v2_0_1_2) and are compiled into text_deps.lib
and yoga.lib. Yoga must be Rive's fork, not upstream — the runtime stores
YGNode by value, which upstream made opaque.
This produces, in build\bin\:
| Artifact | Purpose |
|---|---|
RivePeek.dll |
the preview + thumbnail handler (register to install) |
rivshot.exe |
rivshot in.riv out.png [size] [seconds] — headless render |
preview_test.exe |
drives the COM pipeline in-process and screenshots it |
surrogate_test.exe |
activates the handler in prevhost.exe (like Explorer) |
thumb_test.exe |
renders the IThumbnailProvider thumbnail to a PNG |
Individual steps: get_text_deps.bat / get_yoga.bat (clone deps),
build_text_deps.bat (text_deps.lib), build_yoga.bat (yoga.lib),
build_rive_core.bat (the rive_core.lib static lib), build_dll.bat,
build_rivshot.bat, build_test.bat, build_surrogate_test.bat,
build_thumb_test.bat.
The build environment is configured by
build\env.bat, which auto-detects the newest MSVC toolset and Windows SDK viavswhere. It deliberately avoidsvcvars64.batbecause that script aborts when the optionalcmakedeveloper extension is absent.
Registration writes the COM class, the .riv association, and the
approved-preview-handlers entry under HKEY_CURRENT_USER\Software\Classes —
per-user, so no administrator rights are required (the same scheme
Microsoft's own preview-handler sample uses).
# install
install\register.ps1
# uninstall
install\unregister.ps1Equivalent manual routes: regsvr32 build\bin\RivePeek.dll, or edit + merge
install\RivePeek.reg.
After installing, open Explorer, enable the preview pane (Alt + P) and click
a .riv file. The handler is loaded by the native 64-bit
prevhost.exe surrogate (AppID {6d2b5079-2f0b-48dd-ab7f-97cec514d30b}).
# Render one file headlessly
build\bin\rivshot.exe sample.riv sample.png 512
# Exercise the entire COM handler in-process and capture the preview window
build\bin\preview_test.exe sample.riv capture.png
# Render every .riv in a folder and tally pass/fail
build\validate.ps1 -Dir "path\to\riv\files"
# Replicate Explorer's out-of-process activation (loads the handler in prevhost.exe)
build\bin\surrogate_test.exe sample.riv
# Produce the static thumbnail the file grid would show
build\bin\thumb_test.exe sample.riv thumb.png 256Diagnostics: set the environment variable RIVEPEEK_LOG=1 to make the
handler append a trace of each COM call (Initialize, DoPreview,
GetThumbnail, errors) to %TEMP%\RivePeek.log. It is silent otherwise.
preview_test.exe performs the exact sequence the Shell does
(DllGetClassObject → IClassFactory::CreateInstance → QueryInterface for
every required interface → IInitializeWithStream::Initialize → SetWindow →
DoPreview) and verifies it without needing the DLL registered.
- Text (
WITH_RIVE_TEXT, HarfBuzz + SheenBidi) and flexbox layout (WITH_RIVE_LAYOUT, Yoga) are both supported. Vector art, shapes, gradients, clipping, raster images, image meshes, bones, constraints, state machines, text and layout all render. Audio and scripting remain unsupported. - Scripting (Rive's experimental scripted objects) is not supported; such objects are skipped on import. One corpus file exercises a destruction-order bug in those objects — the SEH teardown guard contains it (blank preview) rather than crashing.
- Blend modes are fully supported (all 15 Rive modes via the Direct2D
Blendeffect). One caveat: a blended shape inside a clip composites against the pre-clip backdrop, since the clip is realized with a D2D layer whose contents aren't yet flattened when the backdrop is sampled. - Files using a different Rive major version than the bundled runtime (currently 7) are reported as unsupported.
- Adding text/layout is a forward path: build the relevant runtime
dependencies, define
WITH_RIVE_TEXT/WITH_RIVE_LAYOUT, and implementFactory::decodeFont.
| Symptom | Fix |
|---|---|
| Preview pane is blank / shows nothing | Make sure it's the Preview pane (Alt + P), not the Details pane. Re-run install\register.ps1 (it restarts Explorer). |
.riv shows a generic picture/file icon |
Old thumbnail cache. Restart Explorer, or clear it: taskkill /f /im explorer.exe & del /q "%LOCALAPPDATA%\Microsoft\Windows\Explorer\thumbcache_*.db" & start explorer. |
| Nothing happens at all | Confirm Folder Options ▸ View ▸ "Show preview handlers in preview pane" is enabled. |
| Want to see what the handler is doing | Set RIVEPEEK_LOG=1 and read %TEMP%\RivePeek.log — it traces every COM call. |
Build can't overwrite RivePeek.dll |
The DLL is loaded by a running prevhost.exe/Explorer. Close previews (or taskkill /f /im prevhost.exe) and rebuild. |
- WiX MSI installer (
installer/— dual-scope per-user / per-machine,WixUI_Advanced); attached to each release - Code-sign the DLL and MSI (Authenticode) — the current installer is unsigned
- Full blend-mode support — all 15 Rive blend modes via the Direct2D
Blendeffect (ID2D1DeviceContext), with a clean srcOver fallback - Text rendering (
WITH_RIVE_TEXT— HarfBuzz + SheenBidi, statically linked); shaping + variable/embedded fonts - Yoga-based layout (
WITH_RIVE_LAYOUT— rive-app/yoga, statically linked); flexbox positioning for responsive artboards - Idle pause — the animation timer stops advancing when the host/preview
isn't in the foreground, and resize/reparent use
SWP_NOACTIVATEso the pane never steals keyboard focus from Explorer's file list
Contributions are welcome — see CONTRIBUTING.md for how to
build, the project layout, coding conventions, and good first issues (the
roadmap items above are all self-contained starting points).
- Built on the Rive C++ runtime (MIT), included as a submodule.
- COM preview-handler structure (interface set,
QISearchdispatch, per-userHKCUregistration, prevhost surrogate AppID) follows Microsoft's canonicalRecipePreviewHandlersample. - RivePeek itself is MIT licensed — see
LICENSE.


