A powerful TypeScript/Node.js library for rendering Minecraft skin avatars. Convert Minecraft usernames or UUIDs into beautiful 2D and 3D isometric avatar images.
- 2D Renderings: Face, bust, and full-body flat renders
- 3D Isometric Renderings: Head, bust, and full-body 3D models
- Automatic Skin Resolution: Resolves usernames to UUIDs via Mojang API
- Smart Caching: In-memory caching with TTL for optimal performance
- Fallback Support: Automatic fallback to default Steve/Alex skins
- Promise Coalescing: Prevents duplicate API requests
- TypeScript Support: Full type definitions included
| Face | Bust | Full Body |
|---|---|---|
![]() |
![]() |
![]() |
| Head | Bust | Full Body |
|---|---|---|
![]() |
![]() |
![]() |
npm install winter-avatar- Node.js >= 18.0.0
- npm or yarn
import { WinterAvatar } from 'winter-avatar';
// Initialize the avatar renderer
const avatar = new WinterAvatar();
await avatar.initialize();
// Render a 2D face
const faceBuffer = await avatar.render2dFace('COSMICxO11y', 256);
// Save to file
import fs from 'fs/promises';
await fs.writeFile('face.png', faceBuffer);
// Render a 3D head
const headBuffer = await avatar.render3dHead('COSMICxO11y', 256);
await fs.writeFile('head.png', headBuffer);
// Render a 3D full body
const bodyBuffer = await avatar.render3dFull('COSMICxO11y', 256);
await fs.writeFile('body.png', bodyBuffer);new WinterAvatar(assetsDir?: string)assetsDir(optional): Custom directory for storing default skin assets. Defaults to./assets
Initializes the client and downloads default Steve/Alex skins if they don't exist.
await avatar.initialize();Renders a 2D flat face/avatar.
username: Minecraft username or UUIDsize: Output image size in pixels (default: 128)overlay: Whether to include the skin overlay layer (default: true)
const buffer = await avatar.render2dFace('COSMICxO11y', 256, true);Renders a 2D flat bust (head, torso, and arms).
const buffer = await avatar.render2dBust('COSMICxO11y', 128, true);Renders a 2D flat full body.
const buffer = await avatar.render2dFull('COSMICxO11y', 256, false);Renders a 3D isometric head.
const buffer = await avatar.render3dHead('COSMICxO11y', 128, true);Renders a 3D isometric bust (head + torso + arms).
const buffer = await avatar.render3dBust('COSMICxO11y', 256, true);Renders a 3D isometric full body.
const buffer = await avatar.render3dFull('COSMICxO11y', 512, true);Gets raw skin data for a username.
const { buffer, model } = await avatar.getSkinData('COSMICxO11y');
// model is either 'steve' or 'alex'Gets the raw skin texture buffer.
const skinBuffer = await avatar.getRawSkin('COSMICxO11y');Clears all memory caches.
avatar.clearCaches();interface SkinData {
buffer: Buffer;
model: 'steve' | 'alex';
}import express from 'express';
import { WinterAvatar } from 'winter-avatar';
const app = express();
const avatar = new WinterAvatar();
await avatar.initialize();
app.get('/avatar/:username', async (req, res) => {
try {
const { username } = req.params;
const buffer = await avatar.render3dFull(username, 256);
res.set('Content-Type', 'image/png');
res.send(buffer);
} catch (error) {
res.status(500).send('Error rendering avatar');
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});const avatar = new WinterAvatar('/path/to/custom/assets');
await avatar.initialize();// You can also use UUIDs directly
const buffer = await avatar.render3dFull('069a79f444e94726a5befca90e38aaf5', 256);- Username Resolution: Converts Minecraft usernames to UUIDs using the Mojang API
- Profile Fetching: Retrieves skin URL and model type from Mojang's session server
- Skin Download: Downloads the skin texture with caching
- Rendering: Renders the skin using canvas-based 2D or 3D isometric projection
- Fallback: If any step fails, falls back to default Steve/Alex skins
The library implements multiple layers of caching:
- UUID Cache: 24-hour TTL for username-to-UUID mappings
- Profile Cache: 24-hour TTL for skin profile data
- Skin Cache: 24-hour TTL for downloaded skin textures
- Render Cache: 24-hour TTL for rendered images (LRU eviction at 500 items)
- Reuse the avatar instance: Create one avatar instance and reuse it across your application
- Pre-initialize: Call
initialize()during app startup - Adjust sizes: Smaller sizes render faster
- Disable overlay: Set
overlay: falseif you don't need the outer layer
If you encounter build errors related to import.meta, ensure your tsconfig.json has:
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "Node"
}
}If you get errors about missing @napi-rs/canvas or axios, reinstall dependencies:
npm installMIT
Contributions are welcome! Please feel free to submit issues and pull requests.





