https://github.com/user-attachments/assets/734e3a02-e9ff-4f24-9c51-27585d53a806

built directly on winit and wgpu. inspired by nsxiv.
still work in progress.
mostly vibe coded with AI tbh.
to build and install the program, use one of the following methods.
On macOS, HEIF/HEIC decoding uses the system ImageIO framework, so no separate HEIF library is required.
On Linux, HEIF/HEIC support requires the libheif development package, for example:
sudo apt install libheif-dev
cargo build --release
sudo install -Dm755 target/release/sriv /usr/local/bin/sriv
if you have a CUDA-capable GPU, you can use
cargo build --release --features=cuda
alternatively, install directly with Cargo:
sudo cargo install --path . --force --root /usr/local
to clear and regenerate the thumbnail cache for all specified images, use the --clear-cache flag before the file or directory arguments:
sriv --clear-cache <image files or directories>
sriv can index your images with OpenAI CLIP (ViT-B/32) via the Hugging Face Candle runtime.
The first launch downloads model weights and tokenizer from the Hugging Face Hub, after which embeddings are cached alongside your thumbnails in ${XDG_CACHE_HOME}/sriv/.
/ to focus the search bar and type a natural-language prompt. The bar glows purple when focused.Enter to run the search; results are ranked by cosine similarity and highlighted at the top.n/Shift+n (or p/Shift+p) step through the match list, keeping
search results intact./ again to refocus and refine the query, or Esc/Backspace on an empty field to clear the search.If built with CUDA support, embedding generation automatically uses CUDA when available; otherwise sriv fans out across your CPU cores. The status area shows how many embeddings are still pending and whether the GPU or CPU is in use.
you can put custom keybindings in ~/.config/sriv/bindings.toml to execute custom commands.
Just put whatever modifiers (ctrl, shift, alt) if you want and + and then the letter or number of the key.
# open the current image in the default viewer
"ctrl+o" = "xdg-open {file}"
# copy the current image to the clipboard
"ctrl+c" = "xclip -selection clipboard -target image/png -i {file}"
# print out the EXIF metadata of the current image
"ctrl+e" = "exiv2 {file}"
if you want a binding to launch a graphical app and not attach it to sriv's terminal panel, use the table form and set terminal = false.
["ctrl+d"]
command = "~/proj/pupphoto/open_darktable.sh {file}"
terminal = false
you can also put general UI settings in ~/.config/sriv/config.toml.
# optional: path to a .ttf or .otf font to use for all UI text
ui_font_path = "/usr/share/fonts/noto/NotoSansMono-Regular.ttf"
if ui_font_path is unset or fails to load, sriv falls back to the system sans-serif font.
The goal is to have a super fast, responsive image viewer that can handle tens of thousands of 100 megapixel photos and generate thumbnails/CLIP embeddings in parallel.
All thumbnails are loaded into memory. This is different from sxiv/nsxiv, which conserve computational resources by only generating thumbnails for images visible in the viewport, but lead to a laggy user experience when viewing lots of high resolution images, where you have to wait for thumbnails to be generated, one per second, whenever you scroll.
However, only the thumbnails visible in the viewport are loaded into textures on the GPU. This is to conserve VRAM, and uploading a small handful of visible textures onto the GPU is very fast.
Also, a tiled texture strategy is used for displaying the full size image, to prevent crashes on certain GPUs or difficulty with allocating a contiguous giant texture. Full size images can be quite large and use a lot of memory, so an LRU cache keeps memory usage bounded.
why does it use so much cpu?
it is designed to aggressively generate thumbnails with many threads
why does it use so much ram?
in addition to generating thumbnails in parallel, it also stores a local cache of full size images
why does it use so much gpu?
it puts the textures on the gpu for a smoother viewing experience, and it may use a CUDA-capable GPU for CLIP embedding generation
59 commits
Rust
100.0%
https://github.com/user-attachments/assets/734e3a02-e9ff-4f24-9c51-27585d53a806

built directly on winit and wgpu. inspired by nsxiv.
still work in progress.
mostly vibe coded with AI tbh.
to build and install the program, use one of the following methods.
On macOS, HEIF/HEIC decoding uses the system ImageIO framework, so no separate HEIF library is required.
On Linux, HEIF/HEIC support requires the libheif development package, for example:
sudo apt install libheif-dev
cargo build --release
sudo install -Dm755 target/release/sriv /usr/local/bin/sriv
if you have a CUDA-capable GPU, you can use
cargo build --release --features=cuda
alternatively, install directly with Cargo:
sudo cargo install --path . --force --root /usr/local
to clear and regenerate the thumbnail cache for all specified images, use the --clear-cache flag before the file or directory arguments:
sriv --clear-cache <image files or directories>
sriv can index your images with OpenAI CLIP (ViT-B/32) via the Hugging Face Candle runtime.
The first launch downloads model weights and tokenizer from the Hugging Face Hub, after which embeddings are cached alongside your thumbnails in ${XDG_CACHE_HOME}/sriv/.
/ to focus the search bar and type a natural-language prompt. The bar glows purple when focused.Enter to run the search; results are ranked by cosine similarity and highlighted at the top.n/Shift+n (or p/Shift+p) step through the match list, keeping
search results intact./ again to refocus and refine the query, or Esc/Backspace on an empty field to clear the search.If built with CUDA support, embedding generation automatically uses CUDA when available; otherwise sriv fans out across your CPU cores. The status area shows how many embeddings are still pending and whether the GPU or CPU is in use.
you can put custom keybindings in ~/.config/sriv/bindings.toml to execute custom commands.
Just put whatever modifiers (ctrl, shift, alt) if you want and + and then the letter or number of the key.
# open the current image in the default viewer
"ctrl+o" = "xdg-open {file}"
# copy the current image to the clipboard
"ctrl+c" = "xclip -selection clipboard -target image/png -i {file}"
# print out the EXIF metadata of the current image
"ctrl+e" = "exiv2 {file}"
if you want a binding to launch a graphical app and not attach it to sriv's terminal panel, use the table form and set terminal = false.
["ctrl+d"]
command = "~/proj/pupphoto/open_darktable.sh {file}"
terminal = false
you can also put general UI settings in ~/.config/sriv/config.toml.
# optional: path to a .ttf or .otf font to use for all UI text
ui_font_path = "/usr/share/fonts/noto/NotoSansMono-Regular.ttf"
if ui_font_path is unset or fails to load, sriv falls back to the system sans-serif font.
The goal is to have a super fast, responsive image viewer that can handle tens of thousands of 100 megapixel photos and generate thumbnails/CLIP embeddings in parallel.
All thumbnails are loaded into memory. This is different from sxiv/nsxiv, which conserve computational resources by only generating thumbnails for images visible in the viewport, but lead to a laggy user experience when viewing lots of high resolution images, where you have to wait for thumbnails to be generated, one per second, whenever you scroll.
However, only the thumbnails visible in the viewport are loaded into textures on the GPU. This is to conserve VRAM, and uploading a small handful of visible textures onto the GPU is very fast.
Also, a tiled texture strategy is used for displaying the full size image, to prevent crashes on certain GPUs or difficulty with allocating a contiguous giant texture. Full size images can be quite large and use a lot of memory, so an LRU cache keeps memory usage bounded.
why does it use so much cpu?
it is designed to aggressively generate thumbnails with many threads
why does it use so much ram?
in addition to generating thumbnails in parallel, it also stores a local cache of full size images
why does it use so much gpu?
it puts the textures on the gpu for a smoother viewing experience, and it may use a CUDA-capable GPU for CLIP embedding generation
59 commits
Rust
100.0%