Asset Studio — Sprite, Spine & GLTF Viewer
One extension. Three viewers. Built for Three.js / React / JS game & web devs.
Preview sprite sheets, Spine animations and GLTF/GLB models without leaving VS Code —
then hit Copy as Component and paste working React code into your project.
|
|
| 🎞️ Sprite Sheet Player |
Grid slicing, TexturePacker & Aseprite atlases, onion skinning, per-frame durations |
| 🦴 Spine 2D Player |
.json/.skel + .atlas + texture, animation & skin dropdowns, mix slider, bone debug |
| 🧊 GLTF / GLB Viewer |
Orbit + auto-frame, animation clip picker with scrub timeline, wireframe/normals/UV-checker modes, triangle & texture-memory overlay |
Add demo GIFs here before publishing. Marketplace listings without them get far fewer
installs — record 5–10s clips of each viewer (Windows Game Bar, ScreenToGif, or the VS Code
screen recorder) and drop them at the top of this file.
Why this instead of a plain previewer
- Copy as Component on every viewer — emits code that uses the actual filenames and clip
names of the asset you are looking at. No other asset previewer does this.
- Auto-detection by content, not extension — a
.json with skeleton + bones opens the
Spine player; a .json with frames + meta opens the sprite player; a .json with a
matching .atlas next to it is treated as Spine.
- Hot reload — re-export from Aseprite, Blender or Spine and the open preview updates.
- One shared UI shell — the same toolbar and timeline across all three viewers, themed with
VS Code's own CSS variables, so light/dark/high-contrast all work.
- Perf overlay on the 3D viewer — triangles, vertices, meshes, materials, textures and an
estimated texture-memory figure, so you catch bloated assets before they hit your runtime.
- Onion skinning on the sprite player — ghost of the previous frame at low opacity.
Usage
| How |
What happens |
Double-click a .gltf / .glb |
Opens in the Asset Studio 3D viewer (custom editor, priority: option — use Reopen Editor With… if another editor claims it) |
| Right-click any asset → Asset Studio: Open Asset (Auto-Detect) |
Picks the right viewer from the file's contents |
| Command Palette → Asset Studio: Open … |
Opens a specific viewer for the active file |
File pairs are resolved for you. Click player.png and a matching player.json atlas is
picked up automatically (and vice versa via meta.image). Click a Spine .json/.skel and the
sibling .atlas plus its texture page are resolved from the atlas header.
Copy as Component
- Sprite sheet → plain React using
background-position stepping (uniform grids) or an
explicit frame table (trimmed/packed atlases), or a @pixi/react AnimatedSprite.
- GLTF →
@react-three/fiber + drei with useGLTF/useAnimations and the detected clip
pre-wired. If @react-three/fiber is not in your workspace package.json, you get plain
three.js boilerplate instead. Override with assetStudio.codegen.reactThreeFiber.
The generated code is copied to your clipboard and opened in a new editor tab.
Settings
| Setting |
Default |
What it does |
assetStudio.sprite.defaultFps |
12 |
Playback FPS when the atlas has no per-frame durations |
assetStudio.sprite.assetBasePath |
/assets |
Public base path used in generated code (url(/assets/player-run.png)) |
assetStudio.codegen.reactThreeFiber |
auto |
auto | always | never — which flavour of 3D code to emit |
assetStudio.gltf.showGrid |
true |
Ground grid visible on load |
assetStudio.gltf.autoRotate |
false |
Auto-rotate the camera on load |
assetStudio.hotReload |
true |
Reload the preview when the asset changes on disk |
Building from source
npm run install:all # installs the extension host + webview-ui dependencies
npm run build # esbuild bundle + Vite webview build
npm run package # produces asset-studio-0.1.0.vsix
code --install-extension asset-studio-0.1.0.vsix
Other scripts: npm run watch (extension host), npm run typecheck, npm run icon
(regenerates media/icon.png), npm run samples (regenerates samples/).
Test assets
npm run samples writes into samples/:
bouncer.png + bouncer.json — an 8-frame Aseprite-format sprite sheet with a bounce
frame tag and 90 ms per-frame durations
cube.gltf and cube.glb — the same animated cube with two clips (Spin, Hop), one with
an embedded data-URI buffer, one as a binary .glb
Spine test data is not generated: Spine exports require the Spine Editor, so bring your own
(see the licensing note below).
⚠️ Spine licensing
The Spine runtimes bundled here (@esotericsoftware/spine-player, which wraps
spine-webgl) are free to use under the
Spine Runtimes License. Exported Spine
data — the .json / .skel / .atlas files — requires the developer using them to own a
valid Spine Editor license for commercial use.
This extension only plays files you already have. It is not a free alternative to the
Spine Editor and does not bundle any Spine editing capability.
Known limitations (v0.1)
- Draco-compressed models decode with the decoder bundled in the extension (no network needed);
KTX2/Basis and Meshopt compression are not wired up yet.
- Spine assets are loaded without cache-busting because the Spine player infers JSON vs binary
from the URL's extension. If a Spine hot reload ever shows stale data, close and reopen the panel.
- The GLTF custom editor is registered with
priority: option, so VS Code will not steal
.gltf/.glb from another extension you already have installed — use Reopen Editor With…
once and VS Code remembers the choice.
- Very large models load inside the webview (not the extension host), so the editor stays
responsive, but a multi-hundred-MB
.glb will still take a while to parse.
Roadmap
v0.2 is the "wow layer" from the spec: QR-code phone AR preview, live sync into a running dev
server, a one-click sprite-sheet packer, CodeSandbox export, an actionable performance advisor,
a PBR channel inspector, and an optional (BYO-key) Claude assist panel.
License
MIT — see LICENSE. Spine runtimes are licensed separately, as described above.