https://github.com/daidr/minecraft-skin-renderer
A zero-dependency Minecraft skin renderer with WebGL and WebGPU support
https://github.com/daidr/minecraft-skin-renderer
cape minecraft minecraft-skin skin webgl webgpu
Last synced: 4 months ago
JSON representation
A zero-dependency Minecraft skin renderer with WebGL and WebGPU support
- Host: GitHub
- URL: https://github.com/daidr/minecraft-skin-renderer
- Owner: daidr
- Created: 2026-02-02T19:24:50.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-27T17:37:38.000Z (4 months ago)
- Last Synced: 2026-02-27T21:39:28.932Z (4 months ago)
- Topics: cape, minecraft, minecraft-skin, skin, webgl, webgpu
- Language: TypeScript
- Homepage: https://mcskin.daidr.me
- Size: 3.9 MB
- Stars: 6
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
Awesome Lists containing this project
README
# minecraft-skin-renderer
[](https://www.npmjs.com/package/@daidr/minecraft-skin-renderer)
[](https://jsr.io/@daidr/minecraft-skin-renderer)
[](https://jsr.io/@daidr/minecraft-skin-renderer)
[](https://github.com/daidr/minecraft-skin-renderer/pkgs/npm/minecraft-skin-renderer)
[](https://opensource.org/licenses/MIT)
A high-performance, browser-based 3D Minecraft skin renderer with WebGL and WebGPU support.
[Online Documentation](https://mcskin.daidr.me)
[Online Demo](https://mcskin.daidr.me/playground/)
## Features
- **Dual Rendering Backends** - WebGL2 for broad compatibility, WebGPU for modern performance
- **Skin Variants** - Classic (4px arms) and slim (3px arms) model support
- **Back Equipment** - Cape and elytra rendering
- **Animations** - Built-in presets (idle, walk, run, fly) with custom animation support
- **Camera Controls** - Orbit controls with zoom, rotation, and auto-rotate
- **Panorama Backgrounds** - Equirectangular panorama support via plugin
- **2D Static Rendering** - Lightweight Canvas 2D renders (avatar, full body, isometric, big head)
- **Screenshot Export** - Export renders as PNG or JPEG
- **Tree-Shakable** - Plugin architecture for minimal bundle size
## Quick Start
### Installation
```bash
# npm
npm install minecraft-skin-renderer
# pnpm
pnpm add minecraft-skin-renderer
# yarn
yarn add minecraft-skin-renderer
# bun
bun add minecraft-skin-renderer
```
### Basic Usage
```typescript
import { use, createSkinViewer } from "minecraft-skin-renderer";
import { WebGLRendererPlugin } from "minecraft-skin-renderer/webgl";
// Register renderer plugin (required before creating viewer)
use(WebGLRendererPlugin);
// Create viewer
const viewer = await createSkinViewer({
canvas: document.getElementById("canvas") as HTMLCanvasElement,
skin: "https://example.com/skin.png",
});
// Start rendering
viewer.startRenderLoop();
// Play animation
viewer.playAnimation("walk");
```
## API Reference
### `use(plugin)`
Register a renderer or feature plugin. Must be called before `createSkinViewer()`.
```typescript
import { use } from "minecraft-skin-renderer";
import { WebGLRendererPlugin } from "minecraft-skin-renderer/webgl";
import { WebGPURendererPlugin } from "minecraft-skin-renderer/webgpu";
import { PanoramaPlugin } from "minecraft-skin-renderer/panorama";
use(WebGLRendererPlugin);
use(WebGPURendererPlugin);
use(PanoramaPlugin);
```
### `createSkinViewer(options)`
Create and initialize a skin viewer instance.
```typescript
const viewer = await createSkinViewer({
canvas: HTMLCanvasElement, // Required: canvas element
preferredBackend: "auto", // 'webgl' | 'webgpu' | 'auto'
antialias: true, // Enable antialiasing
pixelRatio: window.devicePixelRatio,
skin: "url" | File | Blob, // Skin texture source
cape: "url" | File | Blob, // Cape texture (64x32)
backEquipment: "none", // 'cape' | 'elytra' | 'none'
slim: false, // Use slim model variant
fov: 70, // Field of view in degrees
zoom: 60, // Initial zoom distance
enableRotate: true, // Enable orbit rotation
enableZoom: true, // Enable zoom controls
autoRotate: false, // Auto-rotate camera
autoRotateSpeed: 30, // Degrees per second
panorama: "url", // Panorama background (requires PanoramaPlugin)
});
```
### SkinViewer Methods
#### Textures
```typescript
await viewer.setSkin(source); // Set skin texture
await viewer.setCape(source); // Set cape texture
viewer.setSlim(true); // Switch to slim model
viewer.setBackEquipment("cape"); // 'cape' | 'elytra' | 'none'
```
#### Visibility
```typescript
// Get current visibility state
const visibility = viewer.getPartsVisibility();
// Set visibility for all parts
viewer.setPartsVisibility({
head: { inner: true, outer: true },
body: { inner: true, outer: false },
// ...
});
// Set single part visibility
viewer.setPartVisibility("head", "outer", false);
```
#### Animation
```typescript
viewer.playAnimation("walk"); // Play animation
viewer.playAnimation("walk", {
// With options
speed: 1.5,
amplitude: 1.0,
});
viewer.pauseAnimation(); // Pause
viewer.resumeAnimation(); // Resume
viewer.stopAnimation(); // Stop
```
#### Camera
```typescript
viewer.setRotation(theta, phi); // Set camera angles
const { theta, phi } = viewer.getRotation();
viewer.setZoom(80); // Set zoom distance
viewer.getZoom(); // Get current zoom
viewer.setAutoRotate(true); // Toggle auto-rotate
viewer.resetCamera(); // Reset to default
```
#### Rendering
```typescript
viewer.render(); // Manual render
viewer.startRenderLoop(); // Start RAF loop
viewer.stopRenderLoop(); // Stop RAF loop
viewer.resize(width, height); // Resize canvas
const dataUrl = viewer.screenshot("png", 0.9); // Export
```
#### Lifecycle
```typescript
viewer.dispose(); // Clean up resources
```
#### Properties
```typescript
viewer.backend; // 'webgl' | 'webgpu' (readonly)
viewer.isPlaying; // Animation playing (readonly)
viewer.currentAnimation; // Current animation name (readonly)
viewer.backEquipment; // Current back equipment (readonly)
```
### Plugins
| Plugin | Import Path | Description |
| -------- | ---------------------------------- | --------------------------- |
| WebGL | `minecraft-skin-renderer/webgl` | WebGL2 rendering backend |
| WebGPU | `minecraft-skin-renderer/webgpu` | WebGPU rendering backend |
| Panorama | `minecraft-skin-renderer/panorama` | Panorama background support |
| Canvas2D | `minecraft-skin-renderer/canvas2d` | 2D static rendering module |
### Canvas 2D Rendering
Lightweight 2D rendering module using Canvas 2D API — no WebGL/WebGPU required.
```typescript
import {
renderAvatar,
renderSkinFront,
renderSkinBack,
renderSkinSide,
renderSkinIsometric,
renderHalfBody,
renderBigHead,
} from "minecraft-skin-renderer/canvas2d";
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
// Render head avatar
await renderAvatar(canvas, {
skin: "https://example.com/skin.png",
});
// Render full body front view
await renderSkinFront(canvas, {
skin: "https://example.com/skin.png",
slim: true, // Use slim model variant
scale: 8, // 1 MC pixel = 8 screen pixels (default)
showOverlay: true, // Show outer overlay layer (default)
overlayInflated: false, // Inflate overlay like 3D (default false)
});
// Render big head (Q-version) style
await renderBigHead(canvas, {
skin: "https://example.com/skin.png",
border: 2, // Border width in virtual pixels (default 2)
borderColor: "black", // Border color (default 'black')
});
```
#### Render Functions
| Function | Description |
| --------------------- | -------------------------------------- |
| `renderAvatar` | Head front face (8×8 MC pixels) |
| `renderSkinFront` | Full body front view |
| `renderSkinBack` | Full body back view |
| `renderSkinSide` | Full body side view |
| `renderSkinIsometric` | 2.5D isometric view |
| `renderHalfBody` | Upper body portrait |
| `renderBigHead` | Big head (Q-version) style with border |
#### Common Options (`BaseRenderOptions`)
| Option | Type | Default | Description |
| ----------------- | --------------- | -------- | ---------------------------------------------------------- |
| `skin` | `TextureSource` | required | Skin texture (URL, Blob, HTMLImageElement, or ImageBitmap) |
| `slim` | `boolean` | `false` | Use slim (3px) arm model |
| `showOverlay` | `boolean` | `true` | Show outer overlay layer |
| `scale` | `number` | `8` | Pixel scale (1 MC pixel = scale screen pixels) |
| `overlayInflated` | `boolean` | `false` | Render overlay slightly larger (3D-like) |
`renderBigHead` also accepts `border` (default `2`) and `borderColor` (default `'black'`).
All functions accept `(canvas: HTMLCanvasElement, options)` and return `Promise`. The canvas is automatically resized to fit the rendered content.
### Built-in Animations
| Name | Description |
| ------ | ------------------------ |
| `idle` | Standing idle animation |
| `walk` | Walking animation |
| `run` | Running animation |
| `fly` | Flying/gliding animation |
## Development
### Prerequisites
- Node.js 18+ or Bun
### Setup
```bash
# Install dependencies
bun install
```
### Scripts
| Command | Description |
| -------------------- | ------------------------- |
| `bun run build` | Build library with tsdown |
| `bun dev` | Build in watch mode |
| `bun dev:playground` | Run playground dev server |
| `bun test` | Run tests |
| `bun test:coverage` | Run tests with coverage |
| `bun lint` | Lint with oxlint |
| `bun lint:fix` | Lint and auto-fix |
| `bun fmt` | Format with oxfmt |
### Project Structure
```
src/
├── core/
│ ├── renderer/ # Renderer abstraction (WebGL/WebGPU)
│ ├── math/ # Math utilities (Vec3, Mat4, Quat)
│ ├── camera/ # Camera system
│ └── plugins/ # Plugin registry
├── model/ # Skeleton and geometry
├── animation/ # Animation system
├── viewer/ # Main SkinViewer
└── plugins/ # Plugin implementations
```
### Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
[MIT](LICENSE)