You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The production bundles for the core, WebGL and WebGPU modules contain several large optional or diagnostic code paths that are currently part of the default runtime. A focused set of changes should materially reduce application transfer size, especially for WebGPU.
Status update — 2026-08-03
Landed
Bundle-size fixtures, gzip/Brotli reporting and regression ceilings: #2853.
Lightweight WGSL interface scanning, engine consumption of assembled layouts and removal of the default wgsl_reflect dependency: #2854, #2855 and #2856. This was the largest true-transfer win, saving about 34.5 KB gzip in the representative WebGPU application.
Optional WebGL debug/Spector entry: #2857, saving about 9.1 KB gzip in the representative WebGL application.
Decoupled luma from the complete Device defaults: #2859.
Closed the ten residual bundle-size drafts after assessment; their links and measurements are retained below.
Current tracked fixtures
All regression ceilings pass. The goal column remains the aspirational target rather than the current CI failure threshold.
Fixture
gzip
Brotli
gzip goal
Gap to goal
@luma.gl/core
27,121 B
23,955 B
24,000 B
+3,121 B
@luma.gl/webgl backend
37,319 B
32,081 B
30,000 B
+7,319 B
@luma.gl/webgpu backend
22,388 B
19,823 B
22,000 B
+388 B
core + WebGL
64,440 B
56,036 B
54,000 B
+10,440 B
core + WebGPU
49,509 B
43,778 B
46,000 B
+3,509 B
luma + webgl2Adapter
50,385 B
42,912 B
50,000 B
+385 B
luma + webgpuAdapter
43,669 B
37,609 B
45,000 B
1,331 B under
Closed follow-up PRs, ranked by largest published gzip effect
The figures are incremental measurements published on each PR. These drafts were closed on 2026-08-03 after the major wins landed; their links and measurements are retained for future reference.
Small application saving for a v10 compatibility/preload change.
Assessment and disposition
The dominant true-transfer wins have landed. Apart from #2864's adoption-dependent initial-load deferral, every remaining PR saves at most about 2.5 KB gzip on its best fixture, and representative default-application savings are generally 0.5–2.0 KB per PR.
They were nevertheless closed with the rest of the residual drafts to keep the bundle-size tranche focused on the landed high-impact work. The archived PRs remain useful as design and measurement references.
The remaining ideas should be evaluated as explicit v10 capability or compatibility decisions rather than pure bundle-size wins. In particular, #2865 changes mipmap setup; #2863 → #2866 → #2873 changes diagnostics/logging behavior for roughly 2.6 KB cumulative core gzip savings; #2858 changes enum semantics; and #2868 adds a preload/global-hook contract for less than 0.5 KB application gzip.
Decision: close the remaining draft PRs and preserve their links and measurements in this tracker. Revisit an individual idea only if future bundle regressions or product requirements justify its semantic and maintenance cost; continue enforcing the landed regression ceilings in CI.
Measurements below were taken from the current checkout using the repository's production targets and minification, with gzip-9 for compressed size.
Current baseline
Artifact
Minified
gzip
@luma.gl/core
98.7 KB
27.8 KB
@luma.gl/webgl backend
137.2 KB
38.7 KB
@luma.gl/webgpu backend
275.0 KB
57.1 KB
The backend prebundles expect core separately. When served separately, current totals are approximately:
1. Replace general WGSL reflection in the default WebGPU runtime
wgsl_reflect contributes approximately 195 KB minified / 36.7 KB gzip, over 60% of the WebGPU backend. It is imported by modules/webgpu/src/wgsl/get-shader-layout-wgsl.ts and made mandatory through WebGPUDevice.getShaderLayout().
Most of the lightweight replacement already exists in modules/shadertools/src/lib/shader-assembly/wgsl-binding-debug.ts. It extracts binding names and locations, resource kinds, access modes and texture properties for about 1.3 KB gzip. Shadertools also already contains selected-entry-point and vertex-interface scanning.
Proposed work:
Promote the existing WGSL scanners into a delimiter-aware scanWGSLInterface(source, {vertexEntryPoint}) that produces a ShaderLayout. (#2854)
Have assembleWGSLShader() return this layout. (#2854)
Update Model and Computation to consume assembler metadata instead of reflecting assembled WGSL again. (#2855)
Require an explicit layout or use the lightweight scanner for raw low-level pipelines. (#2856)
Remove wgsl_reflect from the default WebGPU dependency graph. (#2856)
If compatibility requires it, expose the current full implementation through an optional @luma.gl/webgpu/wgsl-reflect entry.
Expected saving: more than 185 KB minified and approximately 30–35 KB compressed. A representative WebGPU application should move from 78.4 KB toward 42–45 KB gzip.
The scanner should cover aliases, nested generic types, reordered attributes, comments, multiple entry points and struct inputs, with a clear fallback requiring an explicit layout when inference is not safe.
2. Move WebGL debugging and the full GL enum off the normal adapter path
modules/webgl/src/context/debug/webgl-developer-tools.ts deliberately imports the complete reverse-mapped GL enum for debug strings. The adapter and device import WebGLDeveloperTools and Spector statically even though their use is conditional.
Proposed work:
Move WebGLDeveloperTools and Spector into @luma.gl/webgl/debug. (#2857)
Load/register them through the explicit optional debug entry. (#2857)
Define synchronous debug behavior through an explicit preload. (#2857)
Remove GL from the main root in the next major while retaining @luma.gl/webgl/constants.
If root compatibility is required, replace the numeric enum with a generated forward-only as const object.
Fix the WebGL constant-inlining transform so it removes imports whose member accesses have all been inlined.
Measured adapter saving from separating debug and Spector: approximately 35.6 KB minified / 9.1 KB gzip. A forward-only constant object saves another approximately 2.6 KB gzip versus the reverse-mapped enum when the constants must remain exported.
3. Make core runtime links and diagnostics optional
Several small imports defeat tree shaking:
Luma.defaultProps imports the complete Device class only to spread Device.defaultProps.
Device imports Buffer for usage constants.
UniformStore imports the Buffer hierarchy for usage constants.
Resource always includes stats bookkeeping, memory accounting, profiling and debug state.
Proposed work:
Extract shared default props so Luma no longer retains the complete Device class. (#2859)
Extract buffer usage flags into a small shared runtime module while preserving existing aliases.
Introduce an optional ResourceInstrumentation hook for resource lifecycle/allocation events.
Move rich probe logging, stats ordering, legacy stat mirroring, profiling and debug-data snapshots into @luma.gl/core/diagnostics.
Preserve luma.log and luma.stats through a compatibility facade.
Replace the exhaustive shader-type lookup table with a parser plus a small cache, validated against every current table entry.
Measured effects:
luma named import: 12.1 KB -> 5.2 KB gzip
Device named import: approximately 1.6 KB gzip smaller
UniformStore: approximately 2.0 KB gzip smaller
Diagnostics/logger extraction: approximately 13.9 KB minified / 4.0 KB gzip
Shader-type parser: approximately 3.1 KB minified / 0.6 KB gzip
A credible complete-core target is approximately 23–24 KB gzip.
Entrypoints and secondary work
Add narrow entries such as @luma.gl/webgl/adapter, /classes, /debug, /legacy.
Move WebGL1 enforcement and legacy parameter interception out of the normal WebGL runtime.
Consider splitting DOM canvas observation from compute/headless core entrypoints.
Convert declaration-like runtime enums/classes in spector-types.ts into actual declarations/interfaces to reduce published package size. (#2870)
An adapter-only WebGPU entry currently defers approximately 55 KB gzip on unsupported-WebGPU or WebGL-fallback paths. This is initial-load deferral rather than an eventual WebGPU transfer reduction.
Conditional lean build
deck.gl PR #10504 demonstrates a smaller supporting technique: a TypeScript transform plus custom export condition selecting a WebGL-only artifact.
luma.gl already separates WebGL and WebGPU packages, so a backend-only condition is not the main solution here. However, an ecosystem-scoped condition such as visgl:lean could help stage or deliver builds with diagnostics and debugging stripped while retaining normal import paths. Semantically different capabilities such as full WGSL reflection should remain explicit subpaths.
The long-term goal should be for the default architecture to become lean, rather than indefinitely maintaining two complete builds.
Proposed bundle budgets
Add CI coverage for full package bundles and representative named-import/application fixtures.
Initial target budgets:
Fixture
gzip target
@luma.gl/core
<= 24 KB
@luma.gl/webgl backend
<= 30 KB
@luma.gl/webgpu backend
<= 22 KB
core + WebGL
approximately 52–54 KB
core + WebGPU
approximately 42–46 KB
luma + webgl2Adapter
<= 50 KB
luma + webgpuAdapter
<= 45 KB
CI should record minified, gzip and Brotli sizes and fail on material regressions.
Suggested implementation order
Add bundle fixtures and budgets.
Replace wgsl_reflect with assembler-produced lightweight layout metadata.
Lazy-load WebGL debug/Spector and remove the full GL enum from adapter imports.
Extract shared core defaults/constants and optional diagnostics.
Add narrow adapter/capability entrypoints.
Optionalize mipmaps and retire legacy compatibility surfaces.
Motivation
The production bundles for the core, WebGL and WebGPU modules contain several large optional or diagnostic code paths that are currently part of the default runtime. A focused set of changes should materially reduce application transfer size, especially for WebGPU.
Status update — 2026-08-03
Landed
wgsl_reflectdependency: #2854, #2855 and #2856. This was the largest true-transfer win, saving about 34.5 KB gzip in the representative WebGPU application.lumafrom the complete Device defaults: #2859.Current tracked fixtures
All regression ceilings pass. The goal column remains the aspirational target rather than the current CI failure threshold.
@luma.gl/core@luma.gl/webglbackend@luma.gl/webgpubackendluma + webgl2Adapterluma + webgpuAdapterClosed follow-up PRs, ranked by largest published gzip effect
The figures are incremental measurements published on each PR. These drafts were closed on 2026-08-03 after the major wins landed; their links and measurements are retained for future reference.
/deviceentry; stacked on #2864.UniformStorefixture; isolated and behavior-compatible, but closed with the remaining drafts.Resourcefixture; full core regresses by 49 B gzip. Primarily enables #2866 and #2873.Assessment and disposition
The dominant true-transfer wins have landed. Apart from #2864's adoption-dependent initial-load deferral, every remaining PR saves at most about 2.5 KB gzip on its best fixture, and representative default-application savings are generally 0.5–2.0 KB per PR.
The lowest-risk candidates were:
Buffer.*aliases preserved.They were nevertheless closed with the rest of the residual drafts to keep the bundle-size tranche focused on the landed high-impact work. The archived PRs remain useful as design and measurement references.
The remaining ideas should be evaluated as explicit v10 capability or compatibility decisions rather than pure bundle-size wins. In particular, #2865 changes mipmap setup; #2863 → #2866 → #2873 changes diagnostics/logging behavior for roughly 2.6 KB cumulative core gzip savings; #2858 changes enum semantics; and #2868 adds a preload/global-hook contract for less than 0.5 KB application gzip.
Decision: close the remaining draft PRs and preserve their links and measurements in this tracker. Revisit an individual idea only if future bundle regressions or product requirements justify its semantic and maintenance cost; continue enforcing the landed regression ceilings in CI.
Measurements below were taken from the current checkout using the repository's production targets and minification, with gzip-9 for compressed size.
Current baseline
@luma.gl/core@luma.gl/webglbackend@luma.gl/webgpubackendThe backend prebundles expect core separately. When served separately, current totals are approximately:
Representative tree-shaken application fixtures were:
luma + webgl2Adapter: 211.9 KB minified / 59.7 KB gzipluma + webgpuAdapter: 353.5 KB minified / 78.4 KB gzipHighest-impact findings
1. Replace general WGSL reflection in the default WebGPU runtime
wgsl_reflectcontributes approximately 195 KB minified / 36.7 KB gzip, over 60% of the WebGPU backend. It is imported bymodules/webgpu/src/wgsl/get-shader-layout-wgsl.tsand made mandatory throughWebGPUDevice.getShaderLayout().Most of the lightweight replacement already exists in
modules/shadertools/src/lib/shader-assembly/wgsl-binding-debug.ts. It extracts binding names and locations, resource kinds, access modes and texture properties for about 1.3 KB gzip. Shadertools also already contains selected-entry-point and vertex-interface scanning.Proposed work:
scanWGSLInterface(source, {vertexEntryPoint})that produces aShaderLayout. (#2854)assembleWGSLShader()return this layout. (#2854)ModelandComputationto consume assembler metadata instead of reflecting assembled WGSL again. (#2855)wgsl_reflectfrom the default WebGPU dependency graph. (#2856)@luma.gl/webgpu/wgsl-reflectentry.Expected saving: more than 185 KB minified and approximately 30–35 KB compressed. A representative WebGPU application should move from 78.4 KB toward 42–45 KB gzip.
The scanner should cover aliases, nested generic types, reordered attributes, comments, multiple entry points and struct inputs, with a clear fallback requiring an explicit layout when inference is not safe.
2. Move WebGL debugging and the full GL enum off the normal adapter path
modules/webgl/src/context/debug/webgl-developer-tools.tsdeliberately imports the complete reverse-mappedGLenum for debug strings. The adapter and device import WebGLDeveloperTools and Spector statically even though their use is conditional.Proposed work:
@luma.gl/webgl/debug. (#2857)GLfrom the main root in the next major while retaining@luma.gl/webgl/constants.as constobject.Measured adapter saving from separating debug and Spector: approximately 35.6 KB minified / 9.1 KB gzip. A forward-only constant object saves another approximately 2.6 KB gzip versus the reverse-mapped enum when the constants must remain exported.
3. Make core runtime links and diagnostics optional
Several small imports defeat tree shaking:
Luma.defaultPropsimports the completeDeviceclass only to spreadDevice.defaultProps.DeviceimportsBufferfor usage constants.UniformStoreimports theBufferhierarchy for usage constants.Resourcealways includes stats bookkeeping, memory accounting, profiling and debug state.Proposed work:
Lumano longer retains the completeDeviceclass. (#2859)ResourceInstrumentationhook for resource lifecycle/allocation events.@luma.gl/core/diagnostics.luma.logandluma.statsthrough a compatibility facade.Measured effects:
lumanamed import: 12.1 KB -> 5.2 KB gzipDevicenamed import: approximately 1.6 KB gzip smallerUniformStore: approximately 2.0 KB gzip smallerA credible complete-core target is approximately 23–24 KB gzip.
Entrypoints and secondary work
@luma.gl/webgl/adapter,/classes,/debug,/legacy.@luma.gl/webgpu/adapter,/classes,/mipmaps,/wgsl-reflect./device,/resources,/uniforms,/diagnosticsand test utilities.spector-types.tsinto actual declarations/interfaces to reduce published package size. (#2870)An adapter-only WebGPU entry currently defers approximately 55 KB gzip on unsupported-WebGPU or WebGL-fallback paths. This is initial-load deferral rather than an eventual WebGPU transfer reduction.
Conditional lean build
deck.gl PR #10504 demonstrates a smaller supporting technique: a TypeScript transform plus custom export condition selecting a WebGL-only artifact.
luma.gl already separates WebGL and WebGPU packages, so a backend-only condition is not the main solution here. However, an ecosystem-scoped condition such as
visgl:leancould help stage or deliver builds with diagnostics and debugging stripped while retaining normal import paths. Semantically different capabilities such as full WGSL reflection should remain explicit subpaths.The long-term goal should be for the default architecture to become lean, rather than indefinitely maintaining two complete builds.
Proposed bundle budgets
Add CI coverage for full package bundles and representative named-import/application fixtures.
Initial target budgets:
@luma.gl/core@luma.gl/webglbackend@luma.gl/webgpubackendluma + webgl2Adapterluma + webgpuAdapterCI should record minified, gzip and Brotli sizes and fail on material regressions.
Suggested implementation order
wgsl_reflectwith assembler-produced lightweight layout metadata.Related architectural discussion: #2634.