blazor-threejs-migration
A guide for porting or rebuilding Three.js implementations in .NET Blazor environments.
Install
mkdir -p .claude/skills/blazor-threejs-migration && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15216" && unzip -o skill.zip -d .claude/skills/blazor-threejs-migration && rm skill.zipInstalls to .claude/skills/blazor-threejs-migration
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Reconstruye o migra una integración de Three.js en Blazor WebAssembly hacia otro proyecto .NET, incluso cuando el proyecto destino no tenga acceso al código fuente original. Preserva vendoring local, bridge JS, página Razor, cleanup, y deploy consistente en GitHub Pages.Key capabilities
- →Reconstruct or migrate a Three.js integration in Blazor WebAssembly.
- →Preserve local vendoring of Three.js from npm to `wwwroot/lib/three`.
- →Migrate the JavaScript bridge with 3D world logic, lifecycle, and cleanup.
- →Port a minimal Razor page that imports and coordinates the bridge.
- →Configure consistent deployment to GitHub Pages.
- →Handle local assets like JSON fonts for offline functionality.
How it works
The skill provides a proven workflow to move or reconstruct a Three.js integration in a Blazor WebAssembly project, focusing on local vendoring, a separate JS bridge, explicit resource cleanup, and GitHub Pages deployment.
Inputs & outputs
When to use blazor-threejs-migration
- →Migrating Three.js to a new Blazor repo
- →Reconstructing 3D world logic
- →Setting up local asset handling in .NET
About this skill
Blazor Three.js Migration
GUIDANCE DERIVED FROM A WORKING REPOSITORY
Esta skill empaqueta un flujo probado para mover o reconstruir una integración de Three.js en un proyecto Blazor WebAssembly nuevo. No asumas que el template vacío ya trae soporte para assets JS ESM, vendoring offline o deploy a GitHub Pages: verifícalo y añádelo explícitamente.
IMPORTANTE: esta skill debe poder ejecutarse aunque el proyecto destino no tenga este repositorio ni acceso a sus archivos. Si el código original existe, úsalo sólo como referencia opcional; si no existe, genera los archivos equivalentes desde cero usando las plantillas y criterios de esta skill.
Triggers
Activa esta skill cuando el usuario pida:
- Migrar Three.js a un Blazor WebAssembly nuevo o vacío
- Reproducir la página 3D de este repo en otro proyecto
- Portar el bridge JS y la lógica del mundo 3D a otro template .NET
- Reconstruir la integración desde cero en otro repo sin copiar archivos del original
- Dejar Three.js offline o sin CDN en Blazor
- Mantener el deploy a GitHub Pages funcionando después de agregar Three.js
Operating Modes
Mode A: Source-Assisted Migration
Usa este modo sólo si el repositorio original está disponible. En ese caso, toma como referencia:
- el
.csprojcon vendoring automático de Three.js en Build/Publish - el bridge JS con el mundo 3D, ciclo de vida y limpieza
- una página Razor mínima y, si aplica, otra interactiva
- el workflow de GitHub Pages
Mode B: Standalone Reconstruction
Usa este modo cuando el proyecto destino no tiene acceso al repo original. En ese caso, esta skill debe producir desde cero estos artefactos mínimos:
- un
.csprojcon targetVendorThreeJs - un módulo
wwwroot/js/three-bridge.js - una página Razor que importe el bridge
- opcionalmente, un workflow de GitHub Pages
- opcionalmente, assets locales como fuentes JSON para offline total
En modo standalone, no hagas referencia a archivos inexistentes del repo original. La skill debe generar el resultado final directamente.
Rules
- No uses CDN para la librería Three.js. Replica el vendoring local desde npm a
wwwroot/lib/threevía MSBuild. - Mantén un bridge JS separado. La lógica del mundo 3D vive en un módulo ESM dentro de
wwwroot/js; la página Razor sólo importa y coordina. - Limpia recursos explícitamente. Cancela
requestAnimationFrame, remueve listeners globales, libera controles, geometrías, materiales y renderer. - No recrees la escena sin motivo. Si sólo cambian colores, luces o cámara, actualiza en sitio. Si cambia geometría o texto, recrea la escena preservando la cámara cuando aplique.
- GitHub Pages es un caso especial. Si el destino publica bajo un subpath, actualiza
base href, genera404.htmly crea.nojekyll. - Modo offline real requiere revisar fuentes y otros assets remotos. En este repo, Three.js está vendorizado localmente, pero la fuente 3D por defecto sigue cargándose desde
threejs.org. Si el objetivo es 100% offline, mueve también la fuente awwwrooty usa una URL local. - Valida con build real. No cierres la migración si no pasa
dotnet buildy si no existen los archivos esperados bajowwwroot/lib/three. - La skill debe ser autosuficiente. Si el usuario pide migrar a otro repo sin compartir el código original, entrega archivos nuevos completos o cambios concretos que puedan aplicarse directamente en el proyecto destino.
Decision Points
1. Qué variante de página mover
- Si el usuario sólo necesita mostrar una escena o texto 3D sin edición en vivo, usa el patrón mínimo de
Pages/Love3d.razor. - Si el usuario necesita controles de UI, reconfiguración en caliente o sincronización cámara/UI, usa el patrón de
Pages/3D.razor. - Si el proyecto destino no tiene el código fuente anterior, genera una variante mínima primero y añade la avanzada sólo si el usuario la necesita.
2. Qué nivel de offline necesita
- Si basta con evitar CDN para Three.js y addons, replica el
VendorThreeJsdel.csproj. - Si el requerimiento es cero dependencias remotas en runtime, localiza también la fuente JSON del texto 3D y cualquier asset externo adicional.
3. Qué cambios deben recrear la escena
- Requieren reinicialización: texto, tamaño del texto, profundidad, geometría distinta.
- Se actualizan en sitio: colores, intensidad de luces, fondo, niebla, posición de cámara.
4. Cómo se desplegará
- Si se desplegará en GitHub Pages, replica el workflow con
actions/setup-node,dotnet publish, ajuste debase href,404.htmly.nojekyll. - Si se ejecutará sólo localmente o en otro host, el ajuste de
base hrefpuede no ser necesario.
Workflow
Phase 1: Auditar el template Blazor destino
- Confirma que el proyecto destino es Blazor WebAssembly y que el
.csprojcompila con la versión de .NET esperada. - Verifica si ya existe carpeta
wwwroot/jsy si el proyecto admite import dinámico de módulos JS desde Razor. - Verifica si el deploy será local, GitHub Pages u otro hosting con subpath.
- Pregunta si el requisito offline es parcial o estricto.
- Si el usuario no provee el repo original, asume modo standalone y reconstruye los artefactos desde esta skill.
Phase 2: Migrar el vendoring de Three.js al .csproj
- Copia las propiedades necesarias al
PropertyGroup:ThreeJsVersionThreeJsWwwrootDirErrorOnMissingNpm
- Agrega un target
VendorThreeJsconBeforeTargets="Build;Publish". - Dentro del target:
- valida que
npmexista - crea un proyecto temporal bajo
obj/threejs - instala
threecon versión fija - limpia
wwwroot/lib/three - copia
three.module.js - copia
three.core.js - copia
examples/jsm/**awwwroot/lib/three/addons
- valida que
- No reemplaces este paso por copias manuales en el repo destino; la intención es que Build y Publish produzcan el mismo árbol de assets.
Plantilla mínima del target a generar si no existe implementación previa:
<PropertyGroup>
<ThreeJsVersion>0.183.1</ThreeJsVersion>
<ThreeJsWwwrootDir>$(MSBuildProjectDirectory)\wwwroot\lib\three</ThreeJsWwwrootDir>
<ErrorOnMissingNpm>true</ErrorOnMissingNpm>
</PropertyGroup>
<Target Name="VendorThreeJs" BeforeTargets="Build;Publish">
<PropertyGroup>
<_ThreeObjDir>$(BaseIntermediateOutputPath)threejs</_ThreeObjDir>
</PropertyGroup>
<Exec Command="npm --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="_NpmExitCode" />
</Exec>
<Error Condition="'$(_NpmExitCode)' != '0' AND '$(ErrorOnMissingNpm)' == 'true'"
Text="npm no está disponible. Instala Node.js o desactiva ErrorOnMissingNpm." />
<MakeDir Directories="$(_ThreeObjDir)" />
<Exec WorkingDirectory="$(_ThreeObjDir)" Command="npm init -y" />
<Exec WorkingDirectory="$(_ThreeObjDir)" Command="npm i three@$(ThreeJsVersion)" />
<RemoveDir Directories="$(ThreeJsWwwrootDir)" />
<MakeDir Directories="$(ThreeJsWwwrootDir)\addons" />
<Copy SourceFiles="$(_ThreeObjDir)\node_modules\three\build\three.module.js"
DestinationFiles="$(ThreeJsWwwrootDir)\three.module.js" />
<Copy SourceFiles="$(_ThreeObjDir)\node_modules\three\build\three.core.js"
DestinationFiles="$(ThreeJsWwwrootDir)\three.core.js" />
<ItemGroup>
<_ThreeAddons Include="$(_ThreeObjDir)\node_modules\three\examples\jsm\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(_ThreeAddons)"
DestinationFiles="@(_ThreeAddons->'$(ThreeJsWwwrootDir)\addons\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
Phase 3: Migrar el bridge JS
- Crea
wwwroot/js/three-bridge.js. - Importa desde rutas locales:
../lib/three/three.module.js- addons necesarios como
OrbitControls,FontLoader,TextGeometry
- Conserva estas responsabilidades mínimas en el bridge:
- construir
renderer,scene,cameray controles - reaccionar a
resize - iniciar y detener el loop de animación
- encapsular
initThree,updateConfigydisposeThree - liberar recursos al desmontar
- construir
- Si migras el modo interactivo, conserva la distinción entre:
- reinicialización completa para cambios de geometría
- actualización incremental para cambios de color/luz/cámara
- Si el objetivo es offline total, cambia
fontUrla una ruta local enwwwroot, por ejemplo una fuente JSON vendorizada por el proyecto.
Plantilla mínima del bridge cuando hay que reconstruirlo desde cero:
import * as THREE from "../lib/three/three.module.js";
import { OrbitControls } from "../lib/three/addons/controls/OrbitControls.js";
let current = null;
export function initThree(canvas, options = {}) {
disposeThree();
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
const width = Math.max(1, canvas.clientWidth || window.innerWidth || 800);
const height = Math.max(1, canvas.clientHeight || window.innerHeight || 400);
renderer.setSize(width, height, false);
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 200);
camera.position.set(0, 1, 3);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(3, 4, 3);
scene.add(light);
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x00bcd4 })
);
scene.add(mesh);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
const onResize = () => {
const nextWidth = Math.max(1, canvas.clientWidth || window.innerWidth || 800);
const nextHeight = Math.max(1, canvas.clientHeight || window.innerHeight || 400);
camera.aspect = nextWidth / nextHeight;
camera.updateProjectionMatrix();
rendere
---
*Content truncated.*
When not to use it
- →When the task does not involve Three.js integration in Blazor WebAssembly.
- →When the task is not about migrating to another .NET project.
- →When the task is not related to local vendoring, JS bridging, or GitHub Pages deployment.
Limitations
- →It does not use CDN for the Three.js library.
- →It requires explicit cleanup of resources.
- →It assumes GitHub Pages is a special case for deployment.
How it compares
This skill provides a structured workflow for migrating Three.js to Blazor, explicitly addressing local vendoring, JS bridging, and GitHub Pages deployment, which are often overlooked in generic migration guides.
Compared to similar skills
blazor-threejs-migration side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| blazor-threejs-migration (this skill) | 0 | 3mo | No flags | Advanced |
| azure-resource-manager-mysql-dotnet | 1 | 3mo | Review | Intermediate |
| deployment-e2e-testing | 3 | 2mo | Review | Advanced |
| component-development | 1 | 4mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
azure-resource-manager-mysql-dotnet
microsoft
Azure MySQL Flexible Server SDK for .NET. Database management for MySQL Flexible Server deployments. Use for creating servers, databases, firewall rules, configurations, backups, and high availability. Triggers: "MySQL", "MySqlFlexibleServer", "MySQL Flexible Server", "Azure Database for MySQL", "MySQL database management", "MySQL firewall", "MySQL backup".
deployment-e2e-testing
dotnet
Guide for writing Aspire deployment end-to-end tests. Use this when asked to create, modify, or debug deployment E2E tests that deploy to Azure.
component-development
FritzAndFriends
Guidance for creating Blazor components that emulate ASP.NET Web Forms controls. Use this when implementing new components or extending existing ones in the BlazorWebFormsComponents library.
avalonia-viewmodels-zafiro
davila7
Optimal ViewModel and Wizard creation patterns for Avalonia using Zafiro and ReactiveUI.
aspire
davidortinau
**WORKFLOW SKILL** - Orchestrates Aspire applications using the Aspire CLI and MCP tools for running, debugging, deploying, and managing distributed apps. USE FOR: aspire run, aspire stop, aspire deploy, start aspire app, aspire describe, list aspire integrations, debug aspire issues, view aspire lo
syncfusion-blazor-toolkit-calendars
syncfusion
Build and customize calendar-based components in Syncfusion Blazor Toolkit. Covers Calendar, DatePicker, DateTimePicker, and TimePicker. Use when implementing date/time selection features, handling date range restriction, formatting dates, managing calendar events, validating dates, or customizing c