Release notes for 4.16

Layer blending

We are introducing a new capability called layer blending. This powerful capability allows you to apply one of more than 30 blend modes to your layers to create interesting effects, or even to produce what seems like a new layer. This is done by applying the desired blend mode by setting the layer's blendMode property.

In the following screenshot, we see the result of applying destination-in blendMode to an imageryLayer that displays areas of cultivated crops with a black color. This layer is displayed over the county crops feature layer. The result of destination-in blendMode shows contents of the featurelayer where two layers overlap while everything else is removed. With one line of a code, we are able to create a focused map that shows the cultivated areas in US. To see the blend mode in action, please check out layer blending samples.


Clustering updates

Labeling point clusters

You can now label clusters with the count of points represented by the cluster.


Or any summary statistics used by the cluster popup, such as average of a number field, and predominant value of a string field.


Labeling is configured on the labelingInfo property of FeatureReductionCluster. You can take advantage of all LabelClass functionality when labeling clusters.

layer.featureReduction = {
  type: "cluster",
  clusterRadius: "100px",
  clusterMinSize: "24px",
  clusterMaxSize: "60px",
  labelingInfo: [{
    // disabling label deconfliction ensures
    // all cluster counts are displayed
    deconflictionStrategy: "none",
    labelExpressionInfo: {
      // Displays the cluster count in the center of the cluster
      expression: "Text($feature.cluster_count, '#,###')"
    symbol: {
      type: "text",
      color: "#004a5d",
      font: {
        weight: "bold",
        family: "Noto Sans",
        size: "12px"
    labelPlacement: "center-center",

The following are aggregate fields you can reference in your cluster labels.

// cluster count

// If a number field is used in the layer's renderer
// you can display the average value of this field
// within each cluster

// If a UniqueValueRenderer is applied to the layer
// you can display the predominant type of
// features in each cluster

Generate defaults for clusters

You can use the following convenience methods for generating default labels and popup templates for clustering based on the layer's renderer.

The Point clustering - generate suggested configuration sample demonstrates how to use these functions.



The new OGCFeatureLayer can be used in a MapView or SceneView to create a layer based on individual collections from a OGC API Features service. You can work with these features from the service similar to our FeatureLayer, by adding your own rendering, labeling, clustering, etc.

The OGC API Features standard is the successor to the earlier OGC Web Feature Service (WFS) specification. The new standard is better, faster, and follows a modernized approach that is consistent and modularized. Note that support for WFS is still under consideration. However, the OGC API Features is adopted by several server implementations and is a better and faster option than WFS for consuming data.


3D Updates

Water reflections

Buildings, mountains and other 3D objects are now reflected on water surfaces, making scenes that use the WaterSymbol3DLayer look more realistic than ever. In addition animated waves and reflected sunlight are more visible from top down views.

Water reflections

Check out the updated sample to see how you can toggle reflections for water bodies.

Integrated mesh modifications

Change the shape of an IntegratedMeshLayer by applying client-side modifications. A new class SceneModifications changes the outline or flatten parts of an integrated mesh using polygon geometries. This allows you to focus on specific areas of the mesh, trim its outline or load alternative 3D data using a single IntegratedMeshLayer.

SceneModifications can be persisted using, allowing users to share their modified integrated mesh through web scenes. See how you can interactively modify IntegratedMeshLayers using the Sketch widget in this new sample.

IntegratedMesh modifications

New BuildingExplorer widget

Better understand comprehensive building data coming from BIM models using the new BuildingExplorer widget. Preconfigured and intuitive UI components allow you to isolate specific levels, categories or construction phases for one or multiple buildings in your scene.

To customize the UI for your specific BIM workflows, the widget provides simple options to toggle the visibility for each component.

BuildingSceneLayer widget

Try out the BuildingExplorer in the updated Filter BuildingSceneLayer sample.

Improved Slice tool

Provide users specific and predefined viewpoints of interior and underground details in your scene. When slicing through terrain and 3D objects, it's now possible to arbitrarily tilt the slice plane and also programmatically set the slice shape using a new class SlicePlane.

Slice widget

Check out the Slice sample to see how you can customize the behavior and UI of the widget.

SceneView memory

Gather insights on the performance and memory consumption of layers in your scene. Depending on the complexity of a scene and the amount of available memory, the SceneView might not be able to render all features.

A new sample shows how you can use SceneView.performanceInfo to inspect the amount and complexity of visualized data in your scene. Please note that this property is experimental and should therefore only be used for debugging purposes.

SceneView memory

Symbol updates

CIMSymbol lines and polygons

CIMSymbol now supports CIMLineSymbol and CIMPolygonSymbol. Create custom symbols in your visualizations by using multiple symbol layers to achieve your desired effect. See the CIM specification for more details. CIM lines and polygons are not currently supported in 3D SceneViews. Click here for the full list of limitations.


Draw lines with marker symbols

The SimpleLineSymbol now supports markers of different styles (arrow, diamond, cross, etc.) at the beginning and/or end of each line symbol in a 2D MapView. Markers can enhance the cartographic information of a line by providing additional visual cues about the associated feature.


Imagery layer updates

The RasterShadedReliefRenderer and RasterColormapRenderer are new at 4.16 and can be used to render ImageryLayer and ImageryTileLayer. To see how the RasterShadedReliefRenderer in action, please refer to the ImageryTileLayer - shaded relief renderer sample.

The TileImageryLayer is removed and replaced by the ImageryTileLayer and the popupTemplate is now supported on the new class.

ImageryTileLayer - shaded relief renderer

Webmap saving updates

We enhanced our support for reading and writing the WebMap.initialViewProperties property (extent, rotation, and scale). Also, added support for reading and writing CIM symbols in web maps.

Widget updates

FeatureTable widget (Beta release)

We’ve added editing support to the FeatureTable widget. In order to enable editing within the table, set the editingEnabled property to true. This allows updating values within a table’s cell via double-clicking on it. Note that the service hosting the data must be enabled to allow editing. The FeatureTable is similar to other client editing APIs in that it does not override the permissions set on the service.

Editing date fields is not yet supported but is planned in a future release.

In addition to allowing editing at the tabular level, it is possible to configure editing functionality per field. This is handled via the editable property within the table’s field configs.

To see editing within the FeatureTable, please check out the FeatureTable widget with editing enabled sample.

featuretable editing


A new class was added to aid in formatting the FeatureForm widget. The FormTemplate can be set directly on a FeatureLayer, a FeatureForm, or its view model. The template consists of various elements that display a specific type of form data. The two that are currently supported are field and group. Field elements provide a mechanism to format data collection for field input, whereas group elements are a grouping of multiple field elements nested into one group. Additional types will be added in future releases.

Prior to this version, any type of field configuration for the form was handled by setting its fieldConfigs to an array of FieldConfigs and/or FieldGroupConfigs. The preferred way to do this now is with FieldElements and GroupElements. The older method of using fieldConfigs is still supported but will eventually be deprecated in the future in favor of setting the elements directly within the layer's or form's formTemplate property. The images below depict how a form displays when configuring its fields via fieldConfigs in comparison to setting the fields via the form template's elements. There is no detectable difference in how it renders within the UI.

Fields configured via the form's fieldConfigFields configured via the template's elements
Form fieldConfig Form elements

For an example of how to do this, please refer to the updated Update Feature Attributes sample which sets the formTemplate on the FeatureLayer and another updated sample, Advanced Attribute Editing, which sets the formTemplate on the FeatureForm directly.

New Custom content element

A new popup element, CustomContent, was added at 4.16. Now in addition to fields, media, text, and attachments, we now have an additional custom type. This type of content element can work with multiple types of content such as strings, HTMLElements, Widgets, and/or a Promise.

To see an example of this type of popup content, please check out the Custom popup content sample.

custom popup content

Smart detection of fields

The default Popup has been improved to no longer display system fields that do not hold significant value, e.g. Shape__Area and Shape__Length are two fields that no longer display.

A new popupUtils object was added. This contains three utility functions to aid in Popup content creation.

API Modernization

At the 2020 Esri Developer Summit, we announced that we were working on a project to modernize how the ArcGIS API for JavaScript is consumed for seamless integration with frameworks and developer tooling. Here are the current enhancements:

  • Native Promises have been activated by default. The has flag "esri-native-promise" is no longer supported.
  • Localization has been improved. The preferred way to set an application's locale is at runtime via the intl.setLocale() method. Please refer to the updated Localization guide topic for additional details regarding this.
  • Classes are now using native class syntax instead of dojo/_base/declare. If you built classes like custom widgets, then now is a good opportunity to make some updates.
  • Multiple class inheritance is no longer supported.
  • The current class syntax still works but will be deprecated. To update your TypeScript classes:
    • Remove the amd-dependency comments, they are no longer necessary.
    • Add importHelpers: true to your tsconfig.json compiler options. See TypeScript documentation for more details.
    • Remove use of Dojo’s declare module. This means that apps with classes that leverage the API class framework and multiple inheritance will stop working. The recommended approach is to use mixins with Accessor.

Here is an example of the syntax before and after this update:

Previous TypeScript syntax

/// <amd-dependency path="esri/core/tsSupport/declareExtendsHelper" name="__extends" />
/// <amd-dependency path="esri/core/tsSupport/decorateHelper" name="__decorate" />

import Accessor = require("esri/core/Accessor");

import { subclass, declared } from "esri/core/accessorSupport/decorators";

class Color extends declared(Accessor) {

New TypeScript syntax

import Accessor = require("esri/core/Accessor");

import { subclass } from "esri/core/accessorSupport/decorators";

class Color extends Accessor {

Labeling updates

The LabelClass.deconflictionStrategy property defines how labels should be placed relative to one another for FeatureLayer, CSVLayer, and StreamLayer in 2D MapViews. By default, labels have a static deconfliction strategy, meaning labels that overlap are dropped to make them easier to read. While we've had label deconfliction for awhile, we are now providing an option to turn it off. This provides developers with the flexibility to display all labels when appropriate.

Smart mapping modules have a new home

Because Smart Mapping no longer applies only to renderers, we reorganized the module structure to more clearly indicate which properties of the FeatureLayer you may use to generate good default renderers, popupTemplates, and labels.

These modules previously resided in esri/renderers/smartMapping folders.


Now the structure follows the following format:

    labels/     // new at 4.16
    popup/      // new at 4.16
    renderers/  // renamed from `creators`

See the deprecated classes below for a complete list of changes.

Generate popup template from renderer

You can now generate default popup templates that only includes data used in the layer's renderer.

  layer: layer
  // a suggested popupTemplate for the layer based on its renderer
  layer.popupTemplate = response.primaryTemplate.value;

This provides a better default popup template than the traditional approach of providing a long table of unformatted values.

Suggested default template based on rendererTraditional default
popup-sm-default popup-default

The following samples were updated to demonstrate how to use this method:

Arcade template literals

You can now leverage template literals within Arcade expressions. The Summarize intersecting points in a popup sample demonstrates how to use template literals in an expression referenced in a PopupTemplate.

var output = "";
if(Count(topCrimes) == 0){
  return "No crimes committed in this area";
var num = 0;

for(var item in topCrimes){
  var num_crimes =;
  var crimeType = item["desc_"];

  var timeOfDay = When(
    item.night_avg >= 0.6, "at night",
    item.night_avg <= 0.4, " during the daytime hours",
  " at both night and day");

  // Display crime type with count using template literals

  output += `${num}. ${crimeType}
    -- Total offenses: ${Text(num_crimes, "#,###")}
    -- Most crimes were reported ${timeOfDay}

return output;

This is cleaner than concatenating multiple strings with hardcoded newline characters.

output += num + ". " + crimeType + "\n" +
  "-- Total offenses: " + Text(num_crimes, "#,###") + "\n" +
  "-- Most crimes were reported " + timeOfDay + "\n\n";

Breaking changes

  • Removed Dojo promises. Native Promises have been activated by default. The has flag "esri-native-promise" is no longer supported.
  • Removed use of Dojo’s declare module. This means that apps with classes that leverage the API class framework and multiple inheritance will stop working. The recommended approach is to use mixins with Accessor.
  • The TileImageryLayer is removed and replaced by the ImageryTileLayer.
  • The TimeExtent's intersection method now returns an instance of TimeExtent with undefined values for start and end properties if the two time extents do not intersect.
  • The suspended property of the View is now set to false when the view container's css style visibility is set to hidden (visibility:hidden). The view is hidden but it renders and updates data now.
  • CIMSymbol's data property now only supports CIMSymbolReference JSON. The CIMSymbol JSON should be applied at

Please refer to the Breaking Changes guide topic for a complete list of breaking changes across all releases of the 4x API.

Bug fixes and enhancements

  • BUG-000117528 & ENH-000116007: Added support for arrow marker symbols on the end of lines.
  • BUG-000117869 Fixed an issue where changing the field alias for the cluster_count attribute in point clustering wasn't displaying properly in the Legend.
  • BUG-000125118: Fixed an issue where SVG symbols were unable to be printed if added as a PictureMarkerSymbol.
  • BUG-000127749: Fixed an issue where the stationary property in MapView and SceneView was handled inconsistently.
  • BUG-000128066: Fixed an issue where an ImageryLayer was throwing an error when the layer is added from portalItem.
  • BUG-000128672: Fixed an issue where the FeatureForm would not validate text fields for NULL values if the field did not allow this.
  • BUG-000129390: Fixed an issue where the LayerSearchSource.zoomScale property fails to set zoom scale for the selected search result.
  • BUG-000129738: Fixed an issue in LayerList where actions with the visible property set to false are still visible.
  • BUG-000130303: Updated the documentation to state that PictureMarkerSymbol does not support PNG symbols in Internet Explorer 11.
  • BUG-000130363: Fixed an issue where the Sublayer.clone() method wasn't doing deep cloning properly.
  • BUG-000130559: The ScaleBar widget now displays the correct distance when padding is set on the MapView.
  • BUG-000130770: Fixed an issue where UniqueValueRenderer failed to display multiple SimpleMarkerSymbols if the only difference between the symbols was a value in an outline.
  • GEONET-251354: Fixed an issue where the PrintTemplate did not support custom print templates, which affected both the PrintTask and Print widget.
  • GEONET-253742: Fixed an issue where client-side FeatureLayer fails to display >60,000 features.
  • GEONET-254318: Fixed an issue where multipoints create artifacts at the tile boundaries.
  • GEONET-254997: Fixed an issue where RasterStretchRenderer.statistics is not converted to server stats properly.
  • Fixed an issue where reordering stops in the Directions widget could cause display issues.
  • Fixed an issue where the Map and widgets stop rendering when the View container div visibility is set to hidden.
  • Fixed an issue where the Sublayer capabilities.operations.supportsQuery did not work properly for all layer types.
  • Fixed an issue where the printed legend was styled incorrectly when using a RelationshipRenderer or a DotDensityRenderer. Requires a print service from version 10.8.1 or higher.
  • Improved shadow rendering: fixed artifacts along the edges of shadows casted by 3D objects.
  • Enhanced the 3D editing widget to now use the same visual tools and helpers for creating and updating features.
  • Enhanced the Directions widget and Search widget to display a notification when a user selects Use current location and the current location cannot be retrieved due to current browser restrictions or settings.
  • Enhanced the Directions widget to allow the user to select a source from multiple searchProperties.sources.
  • Enhanced the Directions widget to display times based on stop locations.
  • Enhanced the Directions widget to include placeholder text for custom locators.
  • Enhanced the MapView.hitTest() method to add an options parameter to include or exclude layers or graphics from the hitTest.
  • Enhanced the Sublayer.createFeatureLayer() method to include the MapImageLayer.refreshInterval property value (if defined) for the created FeatureLayer.

Added Classes, Properties, Methods, Events

Complete list of added Classes, Properties, Methods, Events.

Deprecated Classes, Properties, Methods, Events

Complete list of deprecated Classes, Properties, Methods, Events.

Additional packages

Version 4.16 of the ArcGIS API for JavaScript uses ArcGIS Arcade 1.11 (since 4.16), From Dojo 5 we use @dojo/framework version 5.0.4 (since 4.12).

Previous Releases