CesiumJS: Interacitve Build 3D Maps and Globes with WebGL & JS

Category: Javascript | October 10, 2026
AuthorCesiumGS
Last UpdateOctober 10, 2026
LicenseMIT
Views0 views
CesiumJS: Interacitve Build 3D Maps and Globes with WebGL & JS

CesiumJS is an open-source JavaScript library for building interactive 3D globes and 2D maps in the browser.

You can display real-world terrain, satellite imagery, 3D buildings, and geographic datasets in a WebGL scene.

The library works with plain JavaScript or npm projects. Cesium ion supplies optional hosted content, and you can use other compatible data providers.

Features

  • Switch between 3D globe, 2D map, and Columbus View modes.
  • Layer raster imagery from multiple geographic data services.
  • Display elevation data and terrain-aware geographic objects.
  • Stream buildings, photogrammetry, and other 3D Tiles content.
  • Draw points, labels, lines, polygons, 3D models, and volumes.
  • Load GeoJSON, TopoJSON, CZML, and KML geographic data.
  • Animate camera flights and track moving entities.
  • Control time-dependent scenes with a simulation clock and timeline.
  • Respond to map selections and pointer interactions.

Use Cases

  • Geospatial dashboards: Plot incident locations, infrastructure assets, or regional measurements against imagery and terrain.
  • Building and urban planning: Examine proposed construction alongside a 3D city model and existing terrain.
  • Flight and vehicle tracking: Animate position samples across the globe with camera tracking and time controls.
  • 3D geographic data exploration: Inspect city-scale 3D Tiles and filter individual features by metadata.

How To Use It

Installation

CesiumJS Viewer loads Cesium ion imagery by default, and the examples here use Cesium World Terrain. Create a Cesium ion access token for these services.

You can also use other imagery and terrain providers if you configure them.

CDN

<link rel="stylesheet" href="https://cesium.com/downloads/cesiumjs/releases/1.146/Build/Cesium/Widgets/widgets.css">
<script src="https://cesium.com/downloads/cesiumjs/releases/1.146/Build/Cesium/Cesium.js"></script>

npm

Install the package with NPM:

npm install cesium

CesiumJS needs four runtime directories: Workers, ThirdParty, Assets, and Widgets. Copy them from node_modules/cesium/Build/Cesium/ to a public directory.

Set window.CESIUM_BASE_URL to their parent URL before CesiumJS is imported. If the directories are served from /cesium/, place these scripts in the HTML page:

<script>window.CESIUM_BASE_URL = "/cesium/";</script>
<script type="module" src="/src/main.js"></script>

In /src/main.js, import the Viewer and widget CSS. Include <div id="cesiumContainer"></div> in the HTML page and give that element a nonzero height.

import { Ion, Terrain, Viewer } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
Ion.defaultAccessToken = "YOUR_CESIUM_ION_TOKEN";
const viewer = new Viewer("cesiumContainer", {
  terrain: Terrain.fromWorldTerrain(),
});

Basic Usage

Replace YOUR_CESIUM_ION_TOKEN with an access token. This HTML example loads the browser build, displays terrain, and flies the camera over San Francisco.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CesiumJS 3D Globe</title>
  <link rel="stylesheet" href="https://cesium.com/downloads/cesiumjs/releases/1.146/Build/Cesium/Widgets/widgets.css">
  <style>
    html, body, #cesiumContainer {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div id="cesiumContainer"></div>
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.146/Build/Cesium/Cesium.js"></script>
  <script>
    Cesium.Ion.defaultAccessToken = "YOUR_CESIUM_ION_TOKEN";
    const viewer = new Cesium.Viewer("cesiumContainer", {
      terrain: Cesium.Terrain.fromWorldTerrain(),
    });
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(-122.4194, 37.7749, 15000),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-35),
        roll: 0,
      },
    });
  </script>
</body>
</html>

Advanced Examples

Place a Marker on the Globe

Run this after initializing viewer. Cartesian3.fromDegrees() takes longitude, latitude, and an optional height in meters. viewer.zoomTo() frames the marker.

const location = viewer.entities.add({
  name: "San Francisco",
  description: "Sample location marker",
  position: Cesium.Cartesian3.fromDegrees(-122.4194, 37.7749),
  point: {
    pixelSize: 12,
    color: Cesium.Color.ORANGE,
    outlineColor: Cesium.Color.WHITE,
    outlineWidth: 2,
  },
  label: {
    text: "San Francisco",
    font: "16px sans-serif",
    pixelOffset: new Cesium.Cartesian2(0, -24),
  },
});
viewer.zoomTo(location);

Import a GeoJSON File

Put a GeoJSON file at /data/districts.geojson or change the URL to your dataset. For a remote domain, the server must permit cross-origin requests. GeoJsonDataSource.load() also accepts an in-memory GeoJSON object.

async function showGeoJSON() {
  const geojson = await Cesium.GeoJsonDataSource.load("/data/districts.geojson", {
    stroke: Cesium.Color.YELLOW,
    fill: Cesium.Color.CYAN.withAlpha(0.35),
    strokeWidth: 2,
    clampToGround: true,
  });
  await viewer.dataSources.add(geojson);
  await viewer.zoomTo(geojson);
}
showGeoJSON().catch(console.error);

Load a 3D Tileset

Replace 123456 with the numeric asset ID of a 3D Tiles dataset in Cesium ion. The token must have access to that asset. For a self-hosted 3D Tiles dataset, use Cesium.Cesium3DTileset.fromUrl("/tiles/tileset.json") instead.

async function showTileset() {
  const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(123456);
  viewer.scene.primitives.add(tileset);
  await viewer.zoomTo(tileset);
}
showTileset().catch(console.error);

Switch Between 3D and 2D

Use these methods to switch an existing scene between 3D and 2D. Each argument is the transition duration in seconds. Leave scene3DOnly at false when the application needs 2D mode.

viewer.scene.morphTo2D(1.5);
// Restore the 3D globe when needed.
viewer.scene.morphTo3D(1.5);

Respond to Entity Selection

Listen for selectedEntityChanged when an application needs to react to map selections. This is a Cesium event. The callback receives an Entity or undefined. Keep the returned removal function for component cleanup.

const removeSelectionListener = viewer.selectedEntityChanged.addEventListener(
  (entity) => {
    console.log(entity ? entity.name : "No selection");
  }
);
// Call removeSelectionListener() when the listener is no longer needed.

Viewer Configuration Options

UI Controls and Simulation

OptionDescription and default
animationShow the animation widget. Default true.
baseLayerPickerShow the imagery and terrain picker. Default true.
fullscreenButtonShow the fullscreen control. Default true.
vrButtonShow the VR control. Default false.
geocoderConfigure geocoding or hide search with false. Default IonGeocodeProviderType.DEFAULT.
homeButtonShow the home-view button. Default true.
infoBoxShow entity descriptions in the info box. Default true.
sceneModePickerShow the 3D, 2D, and Columbus View picker. Default true.
selectionIndicatorShow the selected-entity indicator. Default true.
timelineShow the timeline widget. Default true.
navigationHelpButtonShow navigation help. Default true.
navigationInstructionsInitiallyVisibleInitially display the navigation instructions. Default true.
shouldAnimateStart clock animation on initialization. Default false.
clockViewModelSupply a ClockViewModel. Default new ClockViewModel(clock).
fullscreenElementChoose the fullscreen DOM element or ID. Default document.body.
blurActiveElementOnCanvasFocusBlur the active element on canvas click. Default true.

Imagery, Terrain, and Scene

OptionDescription and default
selectedImageryProviderViewModelInitial imagery entry when the base layer picker is enabled. Defaults to the first available entry.
imageryProviderViewModelsImagery entries in the picker. Default createDefaultImageryProviderViewModels().
selectedTerrainProviderViewModelInitial terrain entry when the base layer picker is enabled. Defaults to the first available entry.
terrainProviderViewModelsTerrain entries in the picker. Default createDefaultTerrainProviderViewModels().
baseLayerInitial bottom imagery layer or false. Default ImageryLayer.fromWorldImagery(). Requires baseLayerPicker: false and a globe.
ellipsoidEllipsoid for geographic calculations. Default Ellipsoid.default.
terrainProviderTerrain provider. Default new EllipsoidTerrainProvider().
terrainAsynchronous Terrain instance. Cannot be set alongside terrainProvider.
skyBoxStars background or false. Default stars for the WGS84 ellipsoid. false also omits the Sun and Moon.
skyAtmosphereSky and atmosphere or false. Enabled for the WGS84 ellipsoid.
sceneModeInitial view mode. Default SceneMode.SCENE3D.
projectionPickerShow the map projection selector. Default false.
scene3DOnlyRestrict geometry rendering to 3D. Set false for applications that switch to 2D. Default false.
mapProjectionProjection in 2D and Columbus View. Default new GeographicProjection(options.ellipsoid).
globeCustom globe or false to hide it. Default new Globe(options.ellipsoid).
mapMode2D2D rotation/scroll behavior. Default MapMode2D.INFINITE_SCROLL.
shadowsEnable shadows cast by light sources. Default false.
terrainShadowsTerrain shadow behavior. Default ShadowMode.RECEIVE_ONLY.

Rendering and Performance

OptionDescription and default
useDefaultRenderLoopLet Viewer render and resize automatically. Default true.
targetFrameRatePreferred rate for the default rendering loop. No specified default.
showRenderLoopErrorsDisplay errors from the render loop on the page. Default true.
useBrowserRecommendedResolutionRender at the browser’s recommended resolution. Default true.
automaticallyTrackDataSourceClocksFollow new data sources’ clocks. Default true.
contextOptionsWebGL context and scene creation settings.
orderIndependentTranslucencyUse order-independent transparency when available. Default true.
requestRenderModeRender frames only when needed. External scene changes can require viewer.scene.requestRender(). Default false.
maximumRenderTimeChangeMaximum simulation-time change before rendering in request-render mode. Default 0.0.
depthPlaneEllipsoidOffsetOffset the depth plane to address artifacts below zero elevation. Default 0.0.
msaaSamplesMultisample antialiasing rate for compatible WebGL2 contexts. Default 4.

Data and Attribution

OptionDescription and default
creditContainerDOM element or ID for map attribution. Default is the viewer’s bottom area.
creditViewportDOM element or ID for the attribution popup. Default is the viewer.
dataSourcesExisting DataSourceCollection. Default new DataSourceCollection(). Caller-owned collections are not destroyed with Viewer.

Viewer Properties

Scene and Data Properties

PropertyDescription
cameraRead-only camera instance.
sceneRead-only scene instance.
canvasRead-only rendering canvas.
containerRead-only parent DOM element.
cesiumWidgetRead-only underlying Cesium widget.
ellipsoidRead-only default ellipsoid.
entitiesRead-only collection of entities outside custom data sources.
dataSourcesRead-only collection of data sources.
dataSourceDisplayRead-only data source renderer.
imageryLayersRead-only imagery layer collection.
terrainProviderGet or set the terrain provider.
postProcessStagesRead-only collection of postprocessing stages.
shadowMapRead-only shadow map.
creditDisplayAttribution display for on-screen credit text and the credit popup.
bottomContainerRead-only bottom DOM container for attribution and controls.

Widgets, Clock, and Selection

PropertyDescription
animationRead-only animation control.
baseLayerPickerRead-only base layer selector.
fullscreenButtonRead-only fullscreen widget.
geocoderRead-only search widget.
homeButtonRead-only home button.
infoBoxRead-only entity information widget.
navigationHelpButtonRead-only navigation help button.
projectionPickerRead-only projection selector.
sceneModePickerRead-only scene mode selector.
selectionIndicatorRead-only selection marker widget.
timelineRead-only timeline widget.
vrButtonRead-only VR widget.
clockRead-only simulation clock.
clockViewModelRead-only clock view model.
clockTrackedDataSourceGet or set the data source driving the simulation clock.
selectedEntityGet or set the currently selected entity.
trackedEntityGet or set the entity followed by the camera.

Rendering State and Events

PropertyDescription
allowDataSourcesToSuspendAnimationPermit data sources to pause animation while loading.
resolutionScaleRender-resolution multiplier. Default 1.0.
shadowsEnable or disable light-source shadows.
targetFrameRateGet or set the preferred frame rate for the default render loop. Must be greater than zero if set.
terrainShadowsGet or set terrain shadow mode.
useBrowserRecommendedResolutionIgnore the device pixel ratio and render at CSS-pixel resolution when true. Default true.
useDefaultRenderLoopLet Viewer manage rendering and resizing.
screenSpaceEventHandlerRead-only scene input handler.
selectedEntityChangedEvent raised when selectedEntity changes.
trackedEntityChangedEvent raised when trackedEntity changes.

Viewer Methods

MethodDescription
addController(controller)Install a Controller for camera and input behavior.
removeController(controller)Remove a previously installed controller.
extend(mixin, options?)Apply a Viewer mixin with optional mixin settings.
flyTo(target, options?)Animate the camera to an entity, data source, imagery layer, or compatible scene object.
zoomTo(target, offset?)Frame a geographic object immediately after it is ready.
resize()Recalculate viewer dimensions. Needed in custom render loops.
forceResize()Recalculate viewer widget layout and attribution placement.
render()Render one frame. Needed in custom render loops.
isDestroyed()Return whether the Viewer has been destroyed.
destroy()Release Viewer resources when permanently removing it.

Viewer Events

EventTrigger
selectedEntityChangedThe selected entity changes. Listener receives the new selection.
trackedEntityChangedThe entity followed by the camera changes. Listener receives the new tracked entity.

Styling and Customization

CesiumJS includes widgets.css for the default Viewer controls. Set the container size in application CSS, change visible controls through Viewer options, and style imagery or geographic objects through the corresponding Cesium APIs.

Keep attribution visible for any content that requires it.

For a dashboard layout, initialize the Viewer with these settings to hide selected controls:

const compactViewer = new Cesium.Viewer("cesiumContainer", {
  animation: false,
  timeline: false,
  baseLayerPicker: false,
  geocoder: false,
  navigationHelpButton: false,
});

Alternatives & Related Resources

FAQs

Q: Does CesiumJS require a Cesium ion account?

A: CesiumJS is open source and can load data from other compatible services or local files. Cesium ion content, including Cesium World Terrain, requires an access token with the appropriate permissions.

Q: Why is the CesiumJS map blank after installation?

A: Check the browser console, confirm that the container has a nonzero height, and verify the imagery and terrain requests. For npm projects, check the four runtime directories and CESIUM_BASE_URL.

Q: Can CesiumJS run without a framework or bundler?

A: Yes. The prebuilt browser distribution exposes Cesium as a global object and works with a normal script tag and the widget stylesheet.

Q: Why do 3D Tiles fail to appear even when the globe works?

A: Confirm that the asset ID is correct and that your Cesium ion token has access to the asset. For self-hosted tilesets, check the tileset JSON URL, referenced content files, and cross-origin permissions.

Q: Can I use CesiumJS offline?

A: You can host CesiumJS and geographic datasets locally. An offline application also needs local imagery and terrain sources, plus a local geocoder if search is required.

You Might Be Interested In:


Leave a Reply