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

avatar64

v1.1.0

Published

Bulletproof browser-only utilities to convert profile pictures to WebP base64 text and render base64 back into images.

Readme

avatar64

npm version npm downloads license bundle size TypeScript

A bulletproof, tiny, browser-only utility for profile pictures:

  • Convert an image File into WebP and return plain Base64 text
  • Convert Base64 text (or a full data URL) back into a safe <img src> value
  • Convert Base64 text back into a PNG File object for uploads or downloads

No UI. No storage. No backend. Just conversion and display.


✨ Features

  • 🛡️ Bulletproof - Comprehensive error handling and input validation
  • 🪶 Lightweight - Zero dependencies, minimal bundle size
  • 🔒 Safe - Built-in safety limits prevent browser freezing
  • 📦 TypeScript - Full type definitions included
  • 🎯 Focused - Does one thing exceptionally well
  • Fast - Optimized WebP conversion with high-quality output
  • 🔄 Reversible - Convert base64 back to PNG files for uploads

📦 Install

npm install avatar64
yarn add avatar64
pnpm add avatar64

⚠️ Browser-only

This package uses Canvas API for image processing.
It must run in the browser.

Importing or executing conversion functions on the server (Node.js / SSR) will throw an error with a clear message.


🚀 Quick Start

Convert: File → WebP Base64 (plain text)

import { fileToWebpBase64 } from "avatar64";

const input = document.querySelector<HTMLInputElement>("#file")!;
const output = document.querySelector<HTMLTextAreaElement>("#out")!;

input.addEventListener("change", async () => {
  const file = input.files?.[0];
  if (!file) return;

  try {
    const { base64, width, height, decodedBytes } = await fileToWebpBase64(file, {
      maxSize: 256,
      quality: 0.8,
    });

    // Plain base64 text (NO data: prefix)
    output.value = base64;
    console.log(`Converted to ${width}x${height}, ${decodedBytes} bytes`);
  } catch (error) {
    console.error("Conversion failed:", error.message);
  }
});

Convert Options

type ConvertOptions = {
  maxSize?: number;        // default: 256px, set 0 to keep original size
  quality?: number;        // default: 0.8 (range: 0.1 to 1.0)
  allowedMime?: string[];  // default: ["image/png", "image/jpeg", "image/webp", "image/gif"]
  maxInputBytes?: number;  // default: 6MB (6 * 1024 * 1024)
};

Convert Result

type ConvertResult = {
  base64: string;        // Plain base64 text (NO data: prefix)
  dataUrl: string;       // Full data URL for immediate preview
  width: number;         // Output dimensions
  height: number;
  decodedBytes: number;  // Exact size of WebP payload
};

🖼️ Show: Base64 → Image

Get an <img src> value

import { base64ToImgSrc } from "avatar64";

try {
  img.src = base64ToImgSrc(base64Text);
  // → data:image/webp;base64,...
} catch (error) {
  console.error("Invalid base64:", error.message);
}

One-liner helper

import { showBase64InImage } from "avatar64";

try {
  showBase64InImage(img, base64Text);
} catch (error) {
  console.error("Failed to display image:", error.message);
}

Display Options

type ShowOptions = {
  mimeFallback?: string;     // default: "image/webp"
  stripWhitespace?: boolean; // default: true
  maxBase64Chars?: number;   // default: 3,000,000
  maxDecodedBytes?: number;  // default: 2MB (2 * 1024 * 1024)
};

🔄 Convert: Base64 → PNG File

Create a PNG File object from base64

import { base64ToPngFile } from "avatar64";

try {
  // Convert base64 back to a PNG File object
  const pngFile = await base64ToPngFile(base64Text, "avatar.png");
  
  // Now you can upload it to your server
  const formData = new FormData();
  formData.append("avatar", pngFile);
  
  await fetch("/api/upload", {
    method: "POST",
    body: formData,
  });
  
  console.log(`✓ Created PNG file: ${pngFile.name}, ${pngFile.size} bytes`);
} catch (error) {
  console.error("Conversion failed:", error.message);
}

Download base64 as PNG

import { downloadBase64AsPng } from "avatar64";

try {
  // Trigger immediate browser download
  await downloadBase64AsPng(base64Text, "my-avatar.png");
  console.log("✓ Download started");
} catch (error) {
  console.error("Download failed:", error.message);
}

🔧 API Reference

fileToWebpBase64(file, options?)

Converts an image File to WebP format and returns base64 text.

Parameters:

  • file: File - Image file to convert
  • options?: ConvertOptions - Optional conversion settings

Returns: Promise<ConvertResult>

Throws: Detailed error if file is invalid, too large, unsupported type, or conversion fails


base64ToImgSrc(base64OrDataUrl, options?)

Converts base64 text or data URL to a safe <img src> value.

Parameters:

  • base64OrDataUrl: string - Plain base64 or full data URL
  • options?: ShowOptions - Optional display settings

Returns: string - Safe data URL for image src

Throws: Detailed error if input is invalid, corrupted, or exceeds safety limits


showBase64InImage(img, base64OrDataUrl, options?)

Convenience function to directly set an image element's src.

Parameters:

  • img: HTMLImageElement - Target image element
  • base64OrDataUrl: string - Plain base64 or full data URL
  • options?: ShowOptions - Optional display settings

Returns: void

Throws: Detailed error if element is invalid or base64 is corrupted


base64ToPngFile(base64OrDataUrl, filename?, options?) 🆕

Converts base64 text or data URL to a PNG File object.

Parameters:

  • base64OrDataUrl: string - Plain base64 or full data URL
  • filename?: string - Output filename (default: "image.png")
  • options?: ShowOptions - Optional display settings

Returns: Promise<File> - PNG File object ready for upload

Throws: Detailed error if input is invalid or conversion fails

Use cases:

  • Upload base64 images to servers that require File objects
  • Convert stored base64 back to files for FormData
  • Programmatic file handling in web apps

downloadBase64AsPng(base64OrDataUrl, filename?, options?) 🆕

Converts base64 to PNG and triggers browser download.

Parameters:

  • base64OrDataUrl: string - Plain base64 or full data URL
  • filename?: string - Download filename (default: "image.png")
  • options?: ShowOptions - Optional display settings

Returns: Promise<void>

Throws: Detailed error if input is invalid or download fails

Use cases:

  • "Save As" / "Download" buttons for profile pictures
  • Export user-generated images
  • Backup/download functionality

base64DecodedByteLength(base64)

Calculate the exact decoded byte size of a base64 string.

Parameters:

  • base64: string - Base64 string to measure

Returns: number - Exact decoded bytes (0 if invalid)


🛡️ Safety Features

  • ✅ Validates all inputs (File type, MIME, size, dimensions)
  • ✅ Protects against corrupted or malicious files
  • ✅ Prevents browser freezing with size limits
  • ✅ Timeout protection for slow image loading
  • ✅ Proper resource cleanup (blob URLs, canvas)
  • ✅ Descriptive error messages for debugging
  • ✅ Handles edge cases (empty files, invalid dimensions)

Default Safety Limits

| Limit | Default | Purpose | |-------|---------|---------| | maxInputBytes | 6 MB | Reject oversized input files | | maxSize | 256px | Resize large images | | maxBase64Chars | 3,000,000 | Prevent massive base64 strings | | maxDecodedBytes | 2 MB | Limit decoded image size | | Image dimensions | 16384×16384 | Prevent canvas errors | | Load timeout | 30 seconds | Prevent hanging |


📝 Notes & Limitations

  • Base64 inflates size by ~33% compared to binary
  • Output format for conversion is always WebP for optimal size/quality
  • PNG conversion uses lossless encoding with full alpha channel support
  • Browser support requires Canvas API (all modern browsers)
  • Designed for avatars - profile pictures, not large photos
  • No server-side support - browser environment required
  • WebP encoding must be supported by browser (widely supported)

💡 Use Cases

  • User profile picture uploads
  • Avatar selection interfaces
  • Image preview before upload
  • Client-side image optimization
  • Progressive web apps with offline image handling
  • Chat applications with avatar display
  • Account settings pages
  • Download/export functionality for user images
  • Converting stored base64 back to files for re-upload

🔄 Example: Complete Upload Flow

import { fileToWebpBase64, base64ToImgSrc } from "avatar64";

async function handleAvatarUpload(file: File) {
  try {
    // Convert to WebP base64
    const result = await fileToWebpBase64(file, {
      maxSize: 256,
      quality: 0.85,
    });

    // Preview locally
    const preview = document.querySelector<HTMLImageElement>("#preview")!;
    preview.src = result.dataUrl;

    // Send plain base64 to your API
    await fetch("/api/profile/avatar", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ avatar: result.base64 }),
    });

    console.log(`✓ Uploaded ${result.width}×${result.height} avatar`);
  } catch (error) {
    console.error("Upload failed:", error.message);
    alert(`Failed to upload avatar: ${error.message}`);
  }
}

// Later, display stored avatar
function displayAvatar(base64: string) {
  const img = document.querySelector<HTMLImageElement>("#avatar")!;
  try {
    img.src = base64ToImgSrc(base64);
  } catch (error) {
    console.error("Failed to display avatar:", error.message);
    img.src = "/default-avatar.png"; // fallback
  }
}

🔄 Example: Base64 to PNG Conversion Flow

import { base64ToPngFile, downloadBase64AsPng } from "avatar64";

// Example 1: Upload stored base64 as a file
async function uploadStoredAvatar(base64: string) {
  try {
    // Convert base64 to PNG File
    const pngFile = await base64ToPngFile(base64, "avatar.png");
    
    // Upload using FormData
    const formData = new FormData();
    formData.append("avatar", pngFile);
    
    await fetch("/api/upload", {
      method: "POST",
      body: formData,
    });
    
    console.log(`✓ Uploaded ${pngFile.name}`);
  } catch (error) {
    console.error("Upload failed:", error.message);
  }
}

// Example 2: Download button functionality
async function handleDownloadClick(base64: string) {
  try {
    await downloadBase64AsPng(base64, "my-profile-pic.png");
    console.log("✓ Download started");
  } catch (error) {
    console.error("Download failed:", error.message);
    alert(`Failed to download: ${error.message}`);
  }
}

// Example 3: Convert and get file for programmatic use
async function processAvatar(base64: string) {
  try {
    const pngFile = await base64ToPngFile(base64, "processed-avatar.png");
    
    // Use the File object however you need
    console.log(`File created: ${pngFile.name}`);
    console.log(`Size: ${pngFile.size} bytes`);
    console.log(`Type: ${pngFile.type}`);
    
    // Can be used with any API that accepts File objects
    return pngFile;
  } catch (error) {
    console.error("Processing failed:", error.message);
    throw error;
  }
}

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


📄 License

MIT © Binidu01


🔗 Links


Made with ❤️ for the web