Upgrade Guide v3.3
kepler.gl 3.3 upgrades the rendering stack from deck.gl 8 / luma.gl 8 to deck.gl 9 / luma.gl 9. This is a major dependency upgrade that changes how WebGL resources, shaders, and rendering parameters are handled under the hood. Most kepler.gl users will not need to change application code, but library consumers who extend layers, interact with the WebGL context directly, or depend on internal types should review this guide.
Dependency Changes
@deck.gl/*
8.9.x
9.2.11
@luma.gl/*
8.x
9.2.6
@loaders.gl/*
3.x / 4.3.2
4.3.4
math.gl
—
^4.1.0
typescript
4.7.2
5.6.3
New dependencies
@deck.gl-community/editable-layers
9.2.8
Replaces @nebula.gl/layers for editor layer
@deck.gl-community/layers
9.2.8
Community layers package
@deck.gl/widgets
9.2.11
New deck.gl 9 module
@luma.gl/effects
9.2.6
New luma.gl 9 module
@luma.gl/webgpu
9.2.6
Dev dependency for test environment
Removed dependencies
hubble.gl/core, hubble.gl/react
Removed from kepler.gl
@nebula.gl/layers
Replaced by @deck.gl-community/editable-layers
Yarn resolutions
All @deck.gl/*, @loaders.gl/*, and @luma.gl/* packages are pinned via resolutions. If your project has its own resolutions for these packages, make sure they are consistent with the versions above.
Breaking Changes for Library Consumers
1. WebGL context callback renamed
The DeckGL component callback changed from onWebGLInitialized to onDeviceInitialized. The callback now receives a luma.gl Device instead of a raw WebGLRenderingContext.
If you override MapContainerFactory and rely on the initialization callback:
2. Layer blending is now declarative
In deck.gl 8, kepler.gl called setParameters(gl, {...}) with GL constants before each render to set blending mode. In deck.gl 9, blending is set via a parameters prop on DeckGL using WebGPU-style string constants.
Old (removed):
New:
If your application calls setParameters for blending, migrate to the parameters prop instead.
3. GPU parameter constants
A new module @kepler.gl/constants exports WebGPU-style string constants that replace the old GL enum values throughout the codebase:
BLEND_FACTOR—'zero','one','src-alpha', etc.BLEND_OPERATION—'add','subtract', etc.FILTER_MODE—'nearest','linear'ADDRESS_MODE—'clamp-to-edge','repeat','mirror-repeat'TEXTURE_FORMAT—'r8uint','rgba8unorm', etc.TOPOLOGY—'triangle-list','triangle-strip', etc.
If you referenced GL constants for kepler.gl layer configuration, switch to these string constants.
4. setLayerBlending removed
setLayerBlending removedThe function setLayerBlending (previously exported from @kepler.gl/utils) is removed. Use getLayerBlendingParameters instead, which returns a parameters object for deck.gl 9.
5. Aggregation layers use deck.gl 9 native CPU aggregation
GridLayer and HexagonLayer now use deck.gl 9's built-in CPU aggregation (gpuAggregation: false) instead of kepler.gl's custom CPUAggregator. This means:
onSetColorDomain/onSetElevationDomaincallbacks now receive[min, max]number arrays instead of{domain, aggregatedBins}objects.Per-bin filtering is applied at the accessor level (
getColorValue,getElevationValue) rather than via a_filterDataprop.ClusterLayerstill uses the internalCPUAggregator.
If you listen to domain callbacks on aggregation layers, update your handler to accept the new format:
6. Shader changes — GLSL 300 es and UBOs
All custom shaders now target GLSL 300 es:
attribute→in,varying→in/outtexture2D()→texture()gl_FragColor→ explicitout vec4 fragColorUniforms are declared inside Uniform Buffer Objects (UBOs) instead of standalone
uniformdeclarations. For example,uniform float opacitybecomes a field inside auniform layerUniforms { float opacity; } layer;block, accessed aslayer.opacity.
If you have custom layers that inject into kepler.gl's shaders (via editShader or shader hooks), review the new GLSL 300 es syntax.
7. Model API changes in custom layers
If you extend any kepler.gl layer and interact with Model objects:
The _getModel(gl) pattern is replaced — models are now created from super._getModel() and modified via model.setGeometry().
8. PickInfo type change
PickInfo type changeA custom PickInfo<DataT> type is now defined in @kepler.gl/types. This type is a relaxed version of deck.gl 9's PickingInfo to work around stricter generic inference in the DeckGL component's callback types. If you import PickingInfo from @deck.gl/core, be aware that kepler.gl's callbacks use PickInfo instead.
9. MapViewState type is locally defined
MapViewState type is locally definedMapViewState is no longer imported from @deck.gl/core/typed. It is defined locally in @kepler.gl/types (from reducers.d.ts). If you were importing it from deck.gl, import from @kepler.gl/types instead.
10. Editor layers migrated to @deck.gl-community
@deck.gl-communityThe editor layer (EditableGeoJsonLayer) is now imported from @deck.gl-community/editable-layers instead of @nebula.gl/layers. If you extend or replace the editor layer factory, update your imports.
11. Lighting effect API changes
CustomDeckLightingEffect (kepler.gl's lighting/shadow effect) has been rewritten for deck.gl 9:
preRender→setup(context)/cleanup(context)lifecyclegetModuleParameters→getShaderModulePropsShadow module uses UBO-based uniforms with
uniformTypesdeclarationsTexture2Dconstructor →device.createTexture()addDefaultShaderModule/removeDefaultShaderModuleAPI ondeckinstance
If you extend CustomDeckLightingEffect, review the new lifecycle methods.
12. MapView with legacyMeterSizes
MapView with legacyMeterSizeskepler.gl now creates MapView with {legacyMeterSizes: true} to preserve backward-compatible meter-based sizing behavior from deck.gl 8.
Runtime Patches
kepler.gl 3.3 applies two patches to work around deck.gl 9 / luma.gl 9 issues. These are applied automatically and require no action, but are documented for awareness:
patchDeckRendererForPostProcessing()— PatchesDeckRenderer._resizeRenderBuffersto add depth-stencil attachments to post-processing framebuffers. In deck.gl 9, FBOs are created without depth buffers by default, which breaks depth testing when post-processing effects are active.patchPipelineValidation()— PatchesWEBGLRenderPipeline._getLinkStatusto suppress false-positive "mixed sampler type" validation errors in luma.gl 9. This patch is applied lazily only when a raster tile layer is instantiated.
New Features
3D Tile Layer (experimental)
A new 3D Tile Layer enables rendering of photogrammetry meshes, buildings, terrain and other 3D content from OGC 3D Tiles and I3S tilesets. Supported providers:
OGC 3D Tiles 1.0 / 1.1 — any standard
tileset.jsonendpoint.Google Photorealistic 3D Tiles — requires a Google Maps API key.
Cesium Ion — requires a Cesium Ion access token.
ArcGIS I3S — scene service endpoints.
Add a 3D tileset via the Add Data → Tilesets modal by selecting the "3D Tile" type. The layer supports opacity, point size configuration, zoom-to-layer, and the Light and Shadow effect. See the 3D Tile Layer user guide for details.
Fog post-processing effects
Two new post-processing effects are available:
Distance Fog (
distanceFog) — depth-buffer-based fog that increases with camera distance. Parameters:density,fogStart,fogRange,fogColor.Surface Fog (
surfaceFog) — elevation-based ground fog applied below a configurable height in meters. Parameters:density,height,thickness,fogColor.
Both effects are registered in POSTPROCESSING_EFFECTS and can be created via createEffect(). Only one fog effect can be active at a time (enforced by the effect manager UI). Fog effects are ordered early in the post-processing chain to read the depth buffer before subsequent effects clear it.
Known Issues
Performance with tiled layers on older hardware
The deck.gl 9 upgrade introduces additional per-frame overhead in the layer management and GPU state pipelines compared to deck.gl 8. This may cause noticeable slowness when interacting with tiled layers (Tile3DLayer, raster tile layers) — especially when changing visual properties like opacity or when moving the camera over a scene with many visible tiles. The issue is more pronounced on older or lower-end GPUs and is currently under investigation.
Last updated
Was this helpful?