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

characterforge-js

v1.0.0

Published

AI-powered 3D character generation SDK for web and React Native

Readme

CharacterForge SDK

AI-powered 3D character generation SDK for web and React Native applications.

npm version License: MIT

Features

  • 🎨 Generate stylized 3D vinyl toy characters using AI
  • Zero dependencies - lightweight and fast
  • 🔄 Built-in caching - IndexedDB for web, file system for React Native
  • 🔁 Automatic retry logic - with exponential backoff
  • 📱 Cross-platform - works on web and React Native
  • 🎯 TypeScript support - fully typed for excellent IDE support
  • 🖼️ Transparent backgrounds - production-ready PNG images

Installation

npm install characterforge

React Native Additional Setup

For React Native, you'll need to install one of the following file system packages:

Expo:

npx expo install expo-file-system @react-native-async-storage/async-storage

Bare React Native:

npm install react-native-fs @react-native-async-storage/async-storage

Quick Start

Web / React

import { createCharacterForgeClient } from 'characterforge';

// Create a client instance
const client = createCharacterForgeClient({
  apiKey: 'your-api-key-here',
});

// Generate a character
const imageUrl = await client.generate({
  gender: 'female',
  skinTone: 'medium',
  hairStyle: 'bob',
  hairColor: 'brown',
  clothing: 'hoodie',
  clothingColor: 'blue',
  eyeColor: 'brown',
  accessories: ['glasses'],
  transparent: true,
});

// Use the image URL
console.log('Generated image:', imageUrl);

React Native

import { createCharacterForgeClient } from 'characterforge';
import { Image } from 'react-native';

// Create a client instance
const client = createCharacterForgeClient({
  apiKey: 'your-api-key-here',
});

// In your component
function MyComponent() {
  const [imageUrl, setImageUrl] = React.useState(null);

  const generateCharacter = async () => {
    const url = await client.generate({
      gender: 'male',
      skinTone: 'light',
      hairStyle: 'quiff',
      hairColor: 'blonde',
      clothing: 'tshirt',
      clothingColor: 'red',
      eyeColor: 'blue',
      accessories: ['cap'],
      transparent: true,
    });
    setImageUrl(url);
  };

  return (
    <>
      <Button title="Generate Character" onPress={generateCharacter} />
      {imageUrl && <Image source={{ uri: imageUrl }} style={{ width: 300, height: 300 }} />}
    </>
  );
}

API Reference

createCharacterForgeClient(config)

Creates a new SDK client instance.

Parameters:

  • config - Client configuration object

Configuration Options:

interface CharacterForgeClientConfig {
  /** API key for authentication (required) */
  apiKey: string;
  
  /** Base URL for the API (optional, defaults to production) */
  baseUrl?: string;
  
  /** Enable/disable client-side caching (default: true) */
  cache?: boolean;
  
  /** Custom cache manager implementation (optional) */
  cacheManager?: CacheManager;
  
  /** Request timeout in milliseconds (default: 60000) */
  timeout?: number;
  
  /** Retry configuration (optional) */
  retry?: {
    maxRetries: number;      // default: 3
    baseDelayMs: number;     // default: 1000
    maxDelayMs: number;      // default: 10000
  };
}

Returns: CharacterForgeClient instance

client.generate(config, onStatusUpdate?)

Generates a character image based on the provided configuration.

Parameters:

  • config - Character configuration object
  • onStatusUpdate (optional) - Callback function for status updates

Character Configuration:

interface CharacterConfig {
  /** Gender: 'male' | 'female' */
  gender: Gender;
  
  /** Age group (optional): 'kid' | 'preteen' | 'teen' | 'young_adult' | 'adult' */
  ageGroup?: AgeGroupId;
  
  /** Skin tone: 'porcelain' | 'fair' | 'light' | 'medium' | 'olive' | 'brown' | 'dark' | 'deep' */
  skinTone: SkinToneId;
  
  /** Hair style: 'bob' | 'ponytail' | 'buns' | 'long' | 'pixie' | 'undercut' | 'quiff' | 'sidepart' | 'buzz' | 'combover' | 'messy' | 'afro' | 'curly' */
  hairStyle: HairStyleId;
  
  /** Hair color: 'black' | 'dark_brown' | 'brown' | 'auburn' | 'ginger' | 'dark_blonde' | 'blonde' | 'platinum' | 'grey' | 'white' | 'blue' | 'purple' */
  hairColor: HairColorId;
  
  /** Clothing: 'tshirt' | 'hoodie' | 'sweater' | 'jacket' | 'tank' | 'dress' | 'blouse' | 'polo' | 'buttonup' | 'henley' */
  clothing: ClothingItemId;
  
  /** Clothing color: 'white' | 'black' | 'navy' | 'red' | 'blue' | 'green' | 'yellow' | 'purple' | 'pink' | 'orange' | 'teal' */
  clothingColor: ClothingColorId;
  
  /** Eye color: 'dark' | 'brown' | 'blue' | 'green' | 'hazel' | 'grey' */
  eyeColor: EyeColorId;
  
  /** Accessories: array of 'none' | 'glasses' | 'sunglasses' | 'headphones' | 'cap' | 'beanie' */
  accessories: AccessoryId[];
  
  /** Generate with transparent background (default: true) */
  transparent: boolean;
  
  /** Use caching for this generation (default: true) */
  cache?: boolean;
}

Returns: Promise<string> - URL to the generated image

Example with status updates:

const imageUrl = await client.generate(
  {
    gender: 'female',
    skinTone: 'medium',
    hairStyle: 'bob',
    hairColor: 'brown',
    clothing: 'hoodie',
    clothingColor: 'blue',
    eyeColor: 'brown',
    accessories: ['glasses'],
    transparent: true,
  },
  (status) => {
    console.log('Status:', status);
    // "Calling AI Cloud..."
    // "Caching result..."
    // "Retrieved from Client Cache!"
  }
);

client.clearCache()

Clears all cached images.

Returns: Promise<void>

await client.clearCache();

Error Handling

The SDK provides specific error classes for different failure scenarios:

import { 
  AuthenticationError,
  InsufficientCreditsError,
  NetworkError,
  RateLimitError,
  GenerationError,
} from 'characterforge';

try {
  const imageUrl = await client.generate(config);
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof InsufficientCreditsError) {
    console.error('Not enough credits. Please purchase more.');
  } else if (error instanceof NetworkError) {
    console.error('Network error. Please check your connection.');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited. Please slow down.');
  } else if (error instanceof GenerationError) {
    console.error('Generation failed:', error.message);
  }
}

Caching

The SDK automatically caches generated images to reduce API calls and improve performance.

Web Caching

  • Uses IndexedDB for persistent storage
  • Automatically manages object URLs to prevent memory leaks
  • Configurable cache size (default: 100 images)
  • Auto-expires after 7 days
  • Automatically cleans up old entries

React Native Caching

  • Uses file system for image storage
  • Uses AsyncStorage for metadata
  • Platform-specific implementations for Expo and bare React Native
  • Same cache size and expiry settings as web

Disabling Cache

You can disable caching globally or per-request:

// Disable globally
const client = createCharacterForgeClient({
  apiKey: 'your-api-key',
  cache: false,
});

// Disable per-request
const imageUrl = await client.generate({
  ...config,
  cache: false,
});

Custom Cache Manager

For advanced use cases, you can provide a custom cache implementation:

import { CacheManager } from 'characterforge';

class MyCustomCache implements CacheManager {
  async get(key: string): Promise<string | null> {
    // Your implementation
  }

  async set(key: string, data: Blob | string): Promise<string> {
    // Your implementation
  }

  async clear(): Promise<void> {
    // Your implementation
  }
}

const client = createCharacterForgeClient({
  apiKey: 'your-api-key',
  cacheManager: new MyCustomCache(),
});

Advanced Configuration

Custom Base URL

If you're self-hosting or using a custom endpoint:

const client = createCharacterForgeClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://your-custom-domain.com/functions/v1',
});

Custom Timeout

Adjust the request timeout (default is 60 seconds):

const client = createCharacterForgeClient({
  apiKey: 'your-api-key',
  timeout: 30000, // 30 seconds
});

Custom Retry Configuration

Adjust the retry behavior:

const client = createCharacterForgeClient({
  apiKey: 'your-api-key',
  retry: {
    maxRetries: 5,
    baseDelayMs: 2000,
    maxDelayMs: 20000,
  },
});

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import type {
  CharacterConfig,
  CharacterForgeClientConfig,
  Gender,
  SkinToneId,
  HairStyleId,
  // ... and more
} from 'characterforge';

All types are exported for your convenience, enabling excellent IDE autocomplete and type checking.

Examples

Complete React Component

import React, { useState } from 'react';
import { createCharacterForgeClient } from 'characterforge';

const client = createCharacterForgeClient({
  apiKey: process.env.REACT_APP_CHARACTER_FORGE_KEY!,
});

export function CharacterGenerator() {
  const [imageUrl, setImageUrl] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [status, setStatus] = useState('');
  const [error, setError] = useState<string | null>(null);

  const handleGenerate = async () => {
    setLoading(true);
    setError(null);
    
    try {
      const url = await client.generate(
        {
          gender: 'female',
          skinTone: 'medium',
          hairStyle: 'bob',
          hairColor: 'brown',
          clothing: 'hoodie',
          clothingColor: 'blue',
          eyeColor: 'brown',
          accessories: ['glasses'],
          transparent: true,
        },
        (status) => setStatus(status)
      );
      
      setImageUrl(url);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Generation failed');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={handleGenerate} disabled={loading}>
        {loading ? 'Generating...' : 'Generate Character'}
      </button>
      
      {status && <p>Status: {status}</p>}
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
      
      {imageUrl && (
        <img 
          src={imageUrl} 
          alt="Generated character" 
          style={{ width: 300, height: 300 }}
        />
      )}
    </div>
  );
}

Getting an API Key

  1. Visit characterforge.app
  2. Sign up for an account
  3. Navigate to the Developer Dashboard
  4. Create a new API key
  5. Copy your API key and use it in your application

Important: Keep your API key secret and never commit it to version control. Use environment variables or secure key management systems.

Support

Note: This package is published as characterforge on npm.

License

MIT © CharacterForge

Contributing

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