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

@tgimg/react

v0.1.3

Published

Ultra-fast image component for Telegram Mini Apps — instant thumbhash placeholders, adaptive format/size selection, zero layout shift

Downloads

282

Readme

@tgimg/react

Ultra-fast image component for Telegram Mini Apps and webviews. Renders thumbhash placeholders instantly, then swaps to the optimal format and size (AVIF → WebP → JPEG) with zero layout shift.

Part of the tgimg pipeline: use the CLI to build assets and a manifest, then feed the manifest to this runtime.

Install

npm install @tgimg/react
# or
pnpm add @tgimg/react
yarn add @tgimg/react

Peer dependencies: React 18+, React DOM 18+.

Quick start

  1. Build images with the tgimg CLI (outputs a manifest + optimized files):

    tgimg build ./images --out ./public/tgimg --profile telegram-webview
  2. Provide the manifest to your app and use <TgImg />:

    import { TgImgProvider, TgImg } from '@tgimg/react';
    import manifest from './public/tgimg/tgimg.manifest.json'; // or virtual:tgimg-manifest with vite-plugin-tgimg
    
    function App() {
      return (
        <TgImgProvider manifest={manifest}>
          <TgImg src="hero/banner" alt="Hero" width={640} />
          <TgImg src="cards/item" alt="Item" width={320} fit="cover" radius={8} />
        </TgImgProvider>
      );
    }

src is the asset key from the manifest (e.g. the path without extension you used when building). The component picks the best variant (format + size), shows a thumbhash placeholder immediately, then swaps to the real image with no layout shift.

API

<TgImgProvider manifest>

Wraps the tree and provides the tgimg manifest so every <TgImg /> can resolve src to variants.

| Prop | Type | Description | |-----------|------------------|--------------------------------| | manifest| TgImgManifest | Manifest from tgimg build. | | children| ReactNode | Your app (e.g. <TgImg />). |

<TgImg />

Renders an image for a manifest asset: placeholder first, then the selected variant.

| Prop | Type | Default | Description | |-------------------|-------------------------|------------|-------------| | src | string | required | Asset key in the manifest (e.g. "promo/banner"). | | alt | string | required | Alt text for accessibility. | | width | number | — | Width in CSS pixels. Omit to fill container. | | height | number | — | Height in CSS pixels. Omit to use aspect ratio from manifest. | | ratio | number | from manifest | Aspect ratio override (width/height). | | fit | 'cover' \| 'contain' \| 'fill' \| 'none' | 'cover' | Object-fit. | | radius | number \| string | — | Border radius (px or CSS value). | | priority | boolean | false | If true, load eagerly (no lazy). | | transition | 'auto' \| 'instant' \| 'reveal' \| 'off' | 'auto' | How to swap placeholder → image. | | placeholderChroma | number | auto | Thumbhash color (0 = gray, 1 = full). | | baseUrl | string | manifest base_path | URL prefix for asset paths. | | className | string | — | Extra class on the wrapper. | | style | React.CSSProperties | — | Inline styles on the wrapper. | | onLoad | () => void | — | Called when the image has loaded and decoded. | | onError | (error: Error) => void| — | Called on load error. |

You can also pass manifest directly to <TgImg manifest={...} /> instead of using TgImgProvider.

Hooks

  • useManifest() — Returns the manifest from the nearest TgImgProvider. Throws if missing.
  • useAsset(src: string) — Returns the asset entry for src from the manifest, or null.
  • useTgImg(props) — Low-level hook that returns resolved URLs and state; used internally by <TgImg />.

Utilities

  • selectVariant(asset, width, dpr, formats) — Picks the best variant for given width, DPR, and format support.
  • buildSrcSet(asset, width, formats) — Builds a srcset string for the asset.
  • detectFormats() / getFormatsSync() — Detect supported formats (AVIF, WebP, etc.) in the environment.
  • thumbHashToDataURL(base64) — Decode thumbhash base64 to a data URL for the placeholder image.

See the package exports for full types (TgImgManifest, TgImgAsset, TgImgProps, etc.).

Examples

Priority image (above the fold):

<TgImg src="hero/banner" alt="Hero" width={1280} priority />

Lazy card with cover fit and radius:

<TgImg src="cards/product" alt="Product" width={320} height={240} fit="cover" radius={12} />

With Vite and virtual manifest (vite-plugin-tgimg):

// vite.config.ts
import tgimg from 'vite-plugin-tgimg';
// ...
plugins: [tgimg({ dir: 'public/tgimg' })],
import manifest from 'virtual:tgimg-manifest';
import { TgImgProvider, TgImg } from '@tgimg/react';

<TgImgProvider manifest={manifest}>
  <TgImg src="promo/banner" alt="Promo" width={640} />
</TgImgProvider>

Use cases

  • Telegram Mini Apps — Small placeholders, format fallbacks for iOS/Android webviews, no blink.
  • SPAs and static sites — One tgimg build, serve from CDN; content-addressed filenames for caching.
  • Zero CLS — Aspect ratio and size come from the manifest; no layout jump when the image loads.

Requirements

  • Assets and manifest must be produced by tgimg CLI (tgimg build).
  • Manifest version must be supported by this package (see MANIFEST_VERSION_MIN / MANIFEST_VERSION_MAX).

License

MIT · tgimg-core