Upgrade Guide
Modules in @deck.gl-community are independently maintained, so this page will only list occasional major changes.
Please refer the documentation of each module for detailed upgrade guides.
Unreleased
Consolidated sidebars
SidePanelContainer and SidePanelContainerProps are removed without compatibility aliases.
Use SidebarPanelContainer for both overlay drawers and docked side chrome:
new SidebarPanelContainer({
side: 'left', pinned: true, hidable: true, panel: toolsPanel
});
- Set
pinned: trueto preserve the old docked layout. The sidebar's default side isright; setside: 'left'to preserve the old side-panel default. - Replace
hiddenwithopen: !hidden,defaultHiddenwithdefaultOpen: !defaultHidden, andonHiddenChangewithonOpenChange, inverting the callback value. hidablenow defaults to true. Use{pinned: true, pinnable: false, hidable: false}for permanent chrome without user controls. Application-ownedopenstill applies even when hiding controls are disabled.- Enable
pinnableto expose pin/unpin controls. Closing releases layout space; reopening restores pin state, user sizing, and mounted content. WithoutcontentElement, overlays remain available while configured pinned sidebars stay hidden. - Remove old
side-panel-containerimport paths and reference links; use the sidebar reference.
Declarative panel props
This is a breaking panel API cleanup. No compatibility exports or aliases are provided.
- Rename
AccordeonPanel,AccordeonPanelProps,AccordeonPanelContainer, andAccordeonPanelContainerPropsto theirAccordion…spellings. Update direct source paths toaccordion-paneland documentation links to the renamed reference page. - Rename
SplitterPanel.onChangetoonSplitChangeandinitialSplittodefaultSplit.defaultSplitis now initialization-only. To change the ratio after mounting, use controlledsplitwithonSplitChange. A suppliedsplittakes precedence over the default. Controlled dragging requests changes and waits for the application's next value. - Panel IDs are optional in every constructor. Each concrete panel has a stable default ID; supply an explicit ID when multiple instances of that kind share a parent.
- Specialized panel classes now extend
Panel<TheirPublicProps>and render from current props. UsemarkdownPanel.setProps({markdown}),tabs.setProps({panels}), and equivalent typed updates directly, including when nested. Fresh definitions with stable IDs still reconcile. - Custom subclasses should render live values in
renderContent()rather than capture specialized constructor values in a permanent JSXcontentsnapshot. OverridegetChildPanels()when implementing a composition over child definitions. - Panel metadata and
contentaccessors are read-only. Replace direct field assignments withsetProps. Keep IDs stable while updating; use a new definition/ID to start a new lifecycle.
See Panel and SplitterPanel.
@deck.gl-community/layers: SplatLayer legacy props removed
SplatLayer no longer accepts the top-level source and hierarchy props. Pass the source
through getSource, with its hierarchy in a prepared descriptor:
// Before
new SplatLayer({data: rows, source, hierarchy});
// After
new SplatLayer({data: rows, getSource: {type: 'prepared-splats', source, hierarchy}});
TreeLayer canopy overrides follow the same rule: set getSource in _subLayerProps instead of
source or hierarchy.
v9.4.7
@deck.gl-community/layers: tree and splat shadows
TreeLayer and SplatLayer now cast deck.gl shadows when a LightingEffect has a
DirectionalLight with _shadow: true; they previously forced shadowEnabled: false on their
sub-layers. Pass shadowEnabled: false to either layer to keep the old behavior. A lit
SimpleMeshLayer ground plane under a shadow light should also set shadowEnabled: false: in
deck.gl 9.4 it writes a shaded depth and shadows itself. See
TreeLayer shadows.
v9.4.6
Removed @deck.gl-community/three
The deprecated compatibility workspace has been removed. Import TreeLayer, TreeLayerProps,
TreeType, Season, and CropConfig from @deck.gl-community/layers instead. This is a
breaking package removal; previously published @deck.gl-community/three versions remain on npm.
v9.4.3
RadialLayout.radius now sets the radius of the deepest hierarchy ring. Existing layouts that
compensated for oversized rings may need their radius retuned. Angular sectors use the leaf
count rather than all graph nodes, so hierarchies with visible internal nodes fill the circle.
Nodes outside the hierarchy return no position, and edges with absent endpoints return no geometry.
@deck.gl-community/layers: prepared SplatLayer
Use data for a direct prepared Gaussian asset or owner rows, and getSource for a constant
or per-row asset. Put new hierarchies in a {type: 'prepared-splats', source, hierarchy}
descriptor. The compatibility form {data: rows, source, hierarchy} remains supported, but
cannot be combined with direct asset data or an explicit getSource.
Sources and hierarchies are immutable; replace them when their columns change. Submission
budgets retain minimum visible coverage and transition overlap, and do not cap GPU memory.
A tighter maxRenderPixels can take one frame to apply while visibility expands for the broader filter.
Planar Cartesian and Web Mercator views in the unwrapped world are supported. Wrapped world copies
(MapView.repeat), GlobeView and URL/RAD inputs report explicit unsupported-input errors.
transparency: 'sorted' is supported on WebGL2 and WebGPU, with additional selected-buffer memory
and per-frame CPU sorting cost. See SplatLayer
for input forms and rendering limits. On WebGPU, View.clear is rejected until the upstream
nested-render-pass path is fixed; overlapping views without clearing are supported.
Foliage shadows
Native TreeLayer foliage and SplatLayer ship without built-in deck.gl foliage-shadow
integration. Applications that require foliage shadows must provide them outside these renderers.
@deck.gl-community/layers: native TreeLayer
- Import
TreeLayerand its types from@deck.gl-community/layers. - Remove
detailandTreeDetail. Refinement is automatic. CropConfig.radiusis now the radius in metres; older versions rendered half of it. Halve existing values to keep their apparent size.- Foliage renders as Gaussian splats and winter trees show connected branches, so trees look different from earlier versions.
canopy-{species}-foliage-{tier}sublayers are nowSplatLayers, so mesh-specific canopy overrides no longer apply.wood-{species}-{foliage|winter}-{tier}sublayers own the connected wood mesh, and thetrunksalias applies bark overrides to it. Legacy aliases such ascanopy-cherrystill apply after native defaults; exact sublayer IDs take precedence.
@deck.gl-community/editable-layers
Edit modes now consistently accept SimpleFeatureCollection, which supports Point,
LineString, Polygon and their Multi geometries, and excludes GeometryCollection.
This fixes exported constructors such as TranslateMode being incompatible with
GeoJsonEditModeConstructor in strict TypeScript projects.
Use SimpleFeatureCollection for editable data and ModeProps<SimpleFeatureCollection>
for custom mode handlers. Use SimpleFeature for individual editable features:
import type {
ModeProps,
SimpleFeature,
SimpleFeatureCollection
} from '@deck.gl-community/editable-layers';
const feature: SimpleFeature = {
type: 'Feature',
geometry: {type: 'Point', coordinates: [0, 0]},
properties: {}
};
const data: SimpleFeatureCollection = {type: 'FeatureCollection', features: [feature]};
function handleModeData(props: ModeProps<SimpleFeatureCollection>) {
return props.data.features;
}
GeoJSON's FeatureCollection<SimpleGeometry> is also compatible. Validate or narrow
broader GeoJSON input before editing; GeometryCollection is not supported by the
edit modes. The existing Feature and FeatureCollection re-exports remain available.
SnappableMode strategies
Existing new SnappableMode(customMode) wrappers keep source-handle snapping by default.
Custom modes can implement SnappableEditMode.getSnappingStrategy() to choose
ClickSnappingStrategy, DragSnappingStrategy, or SourceSnappingStrategy; returning
undefined disables snapping. Strategy methods accept ModeProps<SimpleFeatureCollection>.
Enable edge targets with modeConfig.edgeSnapping and supply the current viewport.
pickingRadius controls the pixel threshold. Events resolve the target from the current screen
position, including the first touch click and the first corner of drag-to-draw shapes; an existing
rendered target guide is not required. Committed shapes and their preview share the resolved
pointer position. Current drag-event handle picks take priority over the last hover cache. Source drags keep the real pointer-down origin until a target
qualifies. TransformMode supports snapping directly and remains safe to wrap without duplicate
snap guides. The legacy SnappableMode._handler inspection/replacement property remains available.
Use modeConfig.snapper to provide a custom policy for target lookup, including external
spatial indexes. Implement Snapper.snap with ModeProps<SimpleFeatureCollection> and
omit SnapResult.featureIndex for external targets. Returning null suppresses targets
for that lookup, including source-handle translation.
The layer supplies an optional paired ModeProps.projection (EditModeProjection) for snap
targets in planar views. It accounts for coordinateOrigin, offset coordinate systems,
and modelMatrix; elevated edges retain projected depth before converting back to local data.
Standalone modes without this pair retain viewport-based projection. This does not extend
the existing unsnapped pointer-to-data conversion for offset editing; globe offsets are unverified.
Two-element coordinate origins use zero altitude without mutating the supplied array.
additionalSnapTargets is an array of features in the editable layer's local data frame,
before its modelMatrix. It carries no source-layer transform metadata. When copying
targets from a layer with a different coordinate system, origin or model matrix, convert
their coordinates before supplying them; raw coordinates from another frame are unsupported.
Set snapToAdditionalTargetsOnly: true to make the default snapper ignore editable-layer
features as targets while retaining them as source handles. The default remains the combined
target set. A custom Snapper selects its own targets and can apply the same policy directly.
SelectionLayer polygon selection
Polygon selection no longer waits 250 ms before calling onSelect. If an application relied on
that delay, schedule its own deferred work in the callback. Keep SelectionLayer after its
pickable target layers. Selection continues to return deck.gl GPU picking infos for visible
rendered objects, including GeoJSON and binary layer data.
Private playground schema preview
The layer/view schema preview now rejects unknown props and invalid accessor constants. Extend a
props schema for custom layers or extension props instead of relying on unknown keys passing through.
Use createAccessorSchema(valueSchema) in place of the former untyped AccessorSchema.
Move camera fields into viewState/initialViewState; view constructor props no longer accept them.
Use upstream experimental names (_GlobeView, _WMSLayer, _MultiIconLayer, _TextBackgroundLayer)
in @@type. Abstract View is no longer accepted. See the
schema reference for the supported JSON profile.
v9.4
Update deck.gl and luma.gl packages to ~9.4.0. Modules that use loaders.gl require
@loaders.gl/*@^4.4.3.
@deck.gl-community/editable-layers
EditableGeoJsonLayer and SelectionLayer now prevent primary editing gestures from
bubbling into an interleaved parent map by default. Remove application helpers that disable
and re-enable map drag handlers solely for editing. The layer leaves handler enabled states
unchanged and returns primary navigation to the map in ViewMode or inactive selection.
If the application owns gesture coordination, set autoPreventMapInteractions: false on
both the editable and selection layers. Right-button navigation, wheel zoom, and multi-touch
gestures retain their existing behavior.
@deck.gl-community/panels
Panel APIs now use panel-oriented names consistently:
| v9.3 name | v9.4 replacement |
|---|---|
WidgetPanel | Panel |
WidgetPanelTheme | PanelTheme |
WidgetPanelThemeMode | PanelThemeMode |
AccordionWidgetContainer | AccordionPanelContainer |
TabbedWidgetContainer | TabbedPanelContainer |
ColumnWidgetContainer | ColumnPanelContainer |
PanelBox | BoxPanelContainer |
PanelModal | ModalPanelContainer |
PanelSidebar | SidebarPanelContainer |
PanelFullScreen | FullScreenPanelContainer |
ToolbarPanelContainer | ToolbarComponent |
ToastPanelContainer | ToastComponent |
useEffectiveWidgetPanelThemeMode | useEffectivePanelThemeMode |
Additional migration steps:
- Pass ordered
Panel[]arrays to composite panels instead ofPanelRecordmaps. - Pass a
paneldirectly to shell containers. The descriptor-stylecontainerinput and thePanelContentContainer,PanelContentRenderer, andasPanelContainerhelpers were removed. - Replace
WidgetHostwithPanelManageroutside deck.gl. Inside deck.gl, wrap a component withPanelWidgetor use a named panel widget. - Import
createStudioSettingsWidgetandupdateStudioSettingsWidgetfrom@deck.gl-community/widgets. - Rename the
iconprop on modal and sidebar containers totriggerIcon.
@deck.gl-community/react
Rename the React panel exports:
| v9.3 name | v9.4 replacement |
|---|---|
WidgetPanel | Panel |
WidgetPanelProps | PanelProps |
WidgetPanelThemeMode | PanelHostThemeMode |
@deck.gl-community/graph-layers
Graph loader imports
DOTGraphLoader from @deck.gl-community/graph-layers has been removed. Import
DOTLoaderWithParser from @loaders.gl/graphs/dot-loader for synchronous parsing or
parser-bearing loader use. Pass graph URLs directly to GraphLayer.data with
loaders: [DOTLoaderWithParser] and a layout; the layer converts the parsed
records and creates its own engine. Already loaded graphs can also be passed to
data. A custom graphLoader callback is unnecessary for normalized loader output.
DOT syntax validation and strict-graph behavior follow loaders.gl. The loader returns
plain graph data instead of Arrow data, and the old dot.version option is removed.
v9.3
Dependencies
- Requires
deck.gl@~9.3.0-beta.1or later. - Requires
@luma.gl/*@~9.3.2or later. - Requires
@loaders.gl/*@^4.4.1or later.
@deck.gl-community/panels / @deck.gl-community/widgets
- New package:
@deck.gl-community/panelsnow owns panel composition, standalone mounting, panel containers, theming, and related standalone UI. @deck.gl-community/widgetsis now the deck-facing wrapper layer for panel-based deck.gl widgets.- Migration:
- Import panel definitions and panel containers from
@deck.gl-community/panels - Pass those panel definitions into wrapper widgets from
@deck.gl-community/widgets
- Import panel definitions and panel containers from
- New preferred widget wrapper names:
BoxPanelWidgetModalPanelWidgetSidebarPanelWidgetFullScreenPanelWidget
- Compatibility aliases
BoxWidget,ModalWidget, andSidebarWidgetwere removed in v9.4.
@deck.gl-community/editable-layers
- The
@deck.gl-community/layerspeer dependency has been bumped from^9.2.0-betato^9.3.0.
v9.2
@deck.gl-community/editable-layers
- Breaking change:
DrawPolygonMode.modeConfig.preventOverlappingLineshas been renamed toallowSelfIntersectionwith inverted logic.- Replace
{preventOverlappingLines: true}→{allowSelfIntersection: false}(or simply omit — this is now the default) - Replace
{preventOverlappingLines: false}→{allowSelfIntersection: true}
- Replace
@deck.gl-community/leaflet
- Breaking change:
DeckLayerhas been renamed toDeckOverlay.- Replace all imports and usages:
import {DeckLayer} from '@deck.gl-community/leaflet'→import {DeckOverlay} from '@deck.gl-community/leaflet'
- Replace all imports and usages:
@deck.gl-community/graph-layers
- Deprecation: Graph style constants are now defined using literals instead of objects.
- Replace deprecated
NODE_TYPE.CIRCLEwith'circle',EDGE_TYPE.LINEwith'line', etc.
- Replace deprecated
- Deprecation:
GraphLayernow groups styling under astylesheetprop.- Replace
nodeStyle/edgeStylewithstylesheet.nodesandstylesheet.edges.
- Replace
- Deprecation:
graphprop onGraphLayeris being phased out. Provide graphs via thedataprop instead (supportsGraphEngine,Graph, or raw{nodes, edges}/edge arrays) and supply alayoutwhen the layer must build the engine for you. - Breaking change:
JSONLoaderonly normalizes raw JSON payloads. PassGraphinstances directly toGraphLayer.datarather than routing them through the loader.