Skip to content

feat(core): slim createTresApp alternative for tree-shakeable Three.js usage#1345

Open
alvarosabu wants to merge 7 commits intomainfrom
feat/1292-manual-extends-opt-in
Open

feat(core): slim createTresApp alternative for tree-shakeable Three.js usage#1345
alvarosabu wants to merge 7 commits intomainfrom
feat/1292-manual-extends-opt-in

Conversation

@alvarosabu
Copy link
Copy Markdown
Member

@alvarosabu alvarosabu commented Feb 19, 2026

Summary

  • Add createTresApp programmatic API as a slim alternative to <TresCanvas> that does not auto-extend the full THREE namespace, enabling proper tree-shaking
  • Add slim.ts entry point (@tresjs/core/slim) exporting only createTresApp
  • Move extend(THREE) into TresCanvas directly (no change for existing users)
  • Lazy-load devtools registration in Context (dev-only, dynamic import)
  • Add apps/bundle-test app with Rollup Visualizer to compare full vs slim build sizes
  • Add playground demo page for the manual-extend approach

Usage

import { createTresApp } from '@tresjs/core/slim'
import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three'
import MyScene from './MyScene.vue'

const app = createTresApp(canvas, { windowSize: true })
app.extend({ Mesh, BoxGeometry, MeshStandardMaterial })
app.render(MyScene)

Test plan

  • <TresCanvas> still works as before (extends all of THREE automatically)
  • createTresApp renders scene correctly with only registered classes
  • createTresApp with no extend() call does NOT include unused Three.js classes in bundle
  • Existing tests pass (pnpm t)
  • Bundle-test app builds and visualizer shows size difference between full/slim modes

Closes #1292
Closes TRES-214

…ss registration

- Introduced the `extends` prop in the `Context` component to allow users to specify which Three.js classes to register, enabling tree-shaking.
- Updated the `TresCanvas` component to utilize the `extends` prop.
- Added a new `index.vue` page for manual extension demonstration.
- Updated routing to include the new manual extend page.
- Added tests to verify the behavior of the `extends` prop.
@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 19, 2026

Deploy Preview for tresjs-docs ready!

Name Link
🔨 Latest commit 7a143c9
🔍 Latest deploy log https://app.netlify.com/projects/tresjs-docs/deploys/69afafc3240b8400083ff714
😎 Deploy Preview https://deploy-preview-1345--tresjs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 19, 2026

Deploy Preview for tresjs-lab ready!

Name Link
🔨 Latest commit 7a143c9
🔍 Latest deploy log https://app.netlify.com/projects/tresjs-lab/deploys/69afafc3302273000849460a
😎 Deploy Preview https://deploy-preview-1345--tresjs-lab.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 19, 2026

Deploy Preview for cientos-tresjs ready!

Name Link
🔨 Latest commit 7a143c9
🔍 Latest deploy log https://app.netlify.com/projects/cientos-tresjs/deploys/69afafc357ed050008e9217f
😎 Deploy Preview https://deploy-preview-1345--cientos-tresjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@alvarosabu alvarosabu requested a review from Tinoooo February 19, 2026 17:05
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Feb 19, 2026

Open in StackBlitz

@tresjs/cientos

npm i https://pkg.pr.new/@tresjs/cientos@1345

@tresjs/core

npm i https://pkg.pr.new/@tresjs/core@1345

@tresjs/eslint-config

npm i https://pkg.pr.new/@tresjs/eslint-config@1345

@tresjs/leches

npm i https://pkg.pr.new/@tresjs/leches@1345

@tresjs/nuxt

npm i https://pkg.pr.new/@tresjs/nuxt@1345

@tresjs/post-processing

npm i https://pkg.pr.new/@tresjs/post-processing@1345

commit: 7a143c9

- Created a new bundle-test application with multiple HTML entry points for different build modes (full, slim, createTres).
- Added Vue components for rendering scenes using Tres.js, including AppFull.vue and SceneCreateTres.vue.
- Configured Vite for building the application with rollup visualizer integration.
- Updated pnpm-lock.yaml to include new dependencies and devDependencies for the bundle-test app.
- Introduced various HTML files for visualizing build statistics and rendering different app configurations.
@alvarosabu alvarosabu changed the title feat(core): add extends prop to TresCanvas for selective Three.js class registration feat(core): selective Three.js registration via extends prop and slim createTresApp Feb 20, 2026
@alvarosabu alvarosabu changed the title feat(core): selective Three.js registration via extends prop and slim createTresApp feat(core): slim createTresApp alternative for tree-shakeable Three.js usage Feb 20, 2026
@alvarosabu alvarosabu marked this pull request as draft February 20, 2026 08:30
- Added `tsdown` as a dependency and created build scripts for slim and full configurations.
- Introduced new HTML stats files for both slim and full builds.
- Updated `vite.config.ts` to target ESNext and disable module preload polyfill.
- Enhanced `pnpm-lock.yaml` with new dependencies and updated versions for existing packages.
@alvarosabu alvarosabu marked this pull request as ready for review March 10, 2026 05:44
expect(catalogue.value).toHaveProperty('Mesh')
expect(catalogue.value).toHaveProperty('BoxGeometry')
sceneWrapper.unmount()
})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion(non-blocking): It would be nice to have a test for the manual extending here.

import { extend as catalogueExtend } from '../../core/catalogue'
import type { TresContext } from '../useTresContextProvider'

type ContextExposed = { context: ShallowRef<TresContext>, dispose: () => void }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The lint check fails. This should be an interface.

Suggested change
type ContextExposed = { context: ShallowRef<TresContext>, dispose: () => void }
interface ContextExposed { context: ShallowRef<TresContext>, dispose: () => void }

Comment on lines +65 to +74
Object.assign(canvas.style, {
display: 'block',
width: '100%',
height: '100%',
position: windowSize ? 'fixed' : 'relative',
top: '0',
left: '0',
pointerEvents: 'auto',
touchAction: 'none',
})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: For better maintainability, I suggest putting the styles in a central position and using them in both this composable and TresCanvas.

let contextInstance: ContextExposed | null = null
const eventHandlers: Partial<Record<keyof ContextEmits, ((...args: unknown[]) => void)[]>> = {}

function buildEmitBindings(): Record<string, (...args: unknown[]) => void> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I think arrow functions are more common in our codebase.

Suggested change
function buildEmitBindings(): Record<string, (...args: unknown[]) => void> {
const buildEmitBindings = (): Record<string, (...args: unknown[]) => void> => {

Comment on lines +126 to +132
on(event, handler) {
if (!eventHandlers[event]) {
eventHandlers[event] = []
}
eventHandlers[event]!.push(handler as (...args: unknown[]) => void)
return tresApp
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: How is this supposed to work? eventHandlers is already used above in it's original state. I tried using event hooks for context emits here, but it dod not work. What was the intention here?

Comment on lines +1 to +19
/* import {
AmbientLight,
BoxGeometry,
DirectionalLight,
Mesh,
MeshStandardMaterial,
PerspectiveCamera,
} from 'three'
import { createTresApp } from '@tresjs/core/slim'
import SceneCreateTres from './SceneCreateTres.vue'

const canvas = document.getElementById('canvas') as HTMLCanvasElement

const root = createTresApp(canvas, { windowSize: true })

root
.extend({ AmbientLight, BoxGeometry, DirectionalLight, Mesh, MeshStandardMaterial, PerspectiveCamera })
.render(SceneCreateTres)
*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* import {
AmbientLight,
BoxGeometry,
DirectionalLight,
Mesh,
MeshStandardMaterial,
PerspectiveCamera,
} from 'three'
import { createTresApp } from '@tresjs/core/slim'
import SceneCreateTres from './SceneCreateTres.vue'
const canvas = document.getElementById('canvas') as HTMLCanvasElement
const root = createTresApp(canvas, { windowSize: true })
root
.extend({ AmbientLight, BoxGeometry, DirectionalLight, Mesh, MeshStandardMaterial, PerspectiveCamera })
.render(SceneCreateTres)
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue/suggestion/question: The bundle test pages throw an error and don't show anything. Shall we maybe not have the bundle-test folder in the repo? This might reduce maintenance work in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tree-shakable Three.js Imports for TresJS

2 participants