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

@vasakgroup/plugin-vicons

v2.1.2

Published

Icon API for Tauri plugins (Created for VasakOS)

Readme

Tauri Plugin vicons

Obtiene íconos nativos del sistema Linux (GTK) como base64, listos para usar en cualquier elemento <img>. Soporta temas de iconos del sistema, cacheo automático, y detección de cambios de tema en vivo.

Requisitos

  • Rust 1.80.0+
  • Tauri v2
  • Linux con GTK 3 (entornos GNOME, KDE, Xfce, etc.)

Instalación

1. Agregar el crate Rust

[dependencies]
tauri-plugin-vicons = { git = "https://github.com/Vasak-OS/tauri-plugin-vicons", branch = "v2" }

2. Registrar el plugin en lib.rs

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_vicons::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

3. Agregar el paquete JS (opcional)

bun add @vasakgroup/plugin-vicons

4. Configurar permisos

En src-tauri/capabilities/default.json:

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

API

Comandos Rust

| Comando | Descripción | Retorno | |-------------|------------------------------------------------|--------------------------| | get_icon | Obtiene un icono regular por nombre o ruta | String (base64) | | get_symbol| Obtiene un icono simbólico por nombre o ruta | String (base64) |

Ambos aceptan un solo argumento name: &str. Si es una ruta de archivo válida, leen el archivo directamente. Si es un nombre de icono GTK, lo buscan en el tema de iconos del sistema.

Eventos emitidos

| Evento | Cuándo se emite | Payload | |---------------------------|------------------------------------------|---------| | vicons:theme-changed | El tema de iconos del sistema cambió | null |

Escucharlo desde el frontend:

import { listen } from "@tauri-apps/api/event";

await listen("vicons:theme-changed", () => {
  // recargar íconos, refrescar UI, etc.
});

Funciones JS (guest-js)

| Función | Descripción | Retorno | |-------------------|-----------------------------------------------------------------|------------------------| | getIconSource | Obtiene un data URI completo listo para <img src> | string | | getSymbolSource | Igual que getIconSource pero con iconos simbólicos | string | | getIcon | Obtiene solo el base64 de un icono regular (sin data URI) | Promise<string> | | getSymbol | Obtiene solo el base64 de un icono simbólico (sin data URI) | Promise<string> |

getIconSource y getSymbolSource detectan automáticamente el tipo MIME del icono (PNG, JPEG, GIF, WebP, BMP, SVG) mediante magic bytes.

Uso

Básico

import { getIconSource } from '@vasakgroup/plugin-vicons';

const icon = await getIconSource('folder');
// → "data:image/svg+xml;base64,PHN2ZyB4bWxucz0..."

Con Vue

<script setup lang="ts">
import { getIconSource } from '@vasakgroup/plugin-vicons';
import { ref, onMounted } from 'vue';

const icon = ref('');
onMounted(async () => {
  icon.value = await getIconSource('folder');
});
</script>

<template>
  <img :src="icon" alt="folder" />
</template>

Con React

import { getIconSource } from '@vasakgroup/plugin-vicons';
import { useEffect, useState } from 'react';

function FolderIcon() {
  const [src, setSrc] = useState('');
  useEffect(() => {
    getIconSource('folder').then(setSrc);
  }, []);
  return <img src={src} alt="folder" />;
}

Ruta de archivo directa

Si pasás una ruta de archivo existente, se lee directamente sin pasar por el tema GTK:

const icon = await getIconSource('/usr/share/icons/hicolor/48x48/apps/firefox.png');

Escuchar cambios de tema

El plugin detecta automáticamente cambios en el tema de iconos del sistema (a través de la señal changed de GTK) y emite un evento:

import { listen } from "@tauri-apps/api/event";
import { getIconSource } from '@vasakgroup/plugin-vicons';

listen("vicons:theme-changed", async () => {
  console.log("Theme changed, refreshing icons...");
  const icon = await getIconSource('folder');
  // actualizar UI con el nuevo icono
});

Arquitectura

flowchart TB
    subgraph Frontend
        A[getIconSource / getSymbolSource] --> B[getIconType<br/>magic bytes PNG/JPEG/GIF/WebP/BMP/SVG]
        C[listen 'vicons:theme-changed']
    end

    subgraph Backend
        D[get_icon_impl / get_symbol_impl] --> E{¿ruta válida?}
        E -->|sí| F[leer archivo]
        E -->|no| G[buscar en GTK IconTheme]
        G --> H{¿cache hit?}
        H -->|sí + vigente| I[devolver cache]
        H -->|no o expirado| J[GTK lookup → base64 → guardar cache]
    end

    subgraph ThemeMonitor
        K[init_theme_monitor] --> L[connect_changed GTK signal]
        L --> M[clear_cache_internal]
        M --> N[emit 'vicons:theme-changed']
    end

    A --> D
    N -.->|Tauri event| C

Cache

  • Dos cachés separadas: ICON_CACHE y SYMBOL_CACHE (HashMap<String, CacheEntry>).
  • Cada entrada expira después de 30 minutos.
  • Al cambiar el tema de iconos del sistema, ambos cachés se limpian por completo.
  • La caché usa std::sync::LazyLock y std::sync::Mutex (sin dependencias externas).

Detección de cambios de tema

GTK monitorea internamente los cambios de tema mediante:

  • GSettings (org.gnome.desktop.interface icon-theme)
  • inotify sobre ~/.config/gtk-3.0/settings.ini
  • XDG Desktop Portal

Cuando detecta un cambio, dispara la señal changed del IconTheme. El plugin la captura, limpia la caché, y emite vicons:theme-changed al frontend.

Logging

El plugin escribe logs en {app_data_dir}/logs/icons.log con niveles INFO, WARN y ERROR. Sin dependencias externas de logging — usa std::io::LineWriter directo a archivo.

Errores

| Error | Causa | |---------------------|---------------------------------------------| | IconNotFound | El nombre solicitado no existe en el tema | | ThemeMonitorError | No se pudo inicializar el monitor de tema | | Io | Error de lectura de archivo |

Dependencias

Solo 5 crates además de Tauri:

| Crate | Propósito | |------------|-------------------------------| | serde | Serialización | | thiserror| Errores tipados | | gtk | Acceso al theme de iconos GTK | | glib | Bindings de GLib (con GTK) | | base64 | Codificación base64 |

Licencia

GPLv3 — Vasak Group