
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
| Option | Description and default |
|---|---|
animation | Show the animation widget. Default true. |
baseLayerPicker | Show the imagery and terrain picker. Default true. |
fullscreenButton | Show the fullscreen control. Default true. |
vrButton | Show the VR control. Default false. |
geocoder | Configure geocoding or hide search with false. Default IonGeocodeProviderType.DEFAULT. |
homeButton | Show the home-view button. Default true. |
infoBox | Show entity descriptions in the info box. Default true. |
sceneModePicker | Show the 3D, 2D, and Columbus View picker. Default true. |
selectionIndicator | Show the selected-entity indicator. Default true. |
timeline | Show the timeline widget. Default true. |
navigationHelpButton | Show navigation help. Default true. |
navigationInstructionsInitiallyVisible | Initially display the navigation instructions. Default true. |
shouldAnimate | Start clock animation on initialization. Default false. |
clockViewModel | Supply a ClockViewModel. Default new ClockViewModel(clock). |
fullscreenElement | Choose the fullscreen DOM element or ID. Default document.body. |
blurActiveElementOnCanvasFocus | Blur the active element on canvas click. Default true. |
Imagery, Terrain, and Scene
| Option | Description and default |
|---|---|
selectedImageryProviderViewModel | Initial imagery entry when the base layer picker is enabled. Defaults to the first available entry. |
imageryProviderViewModels | Imagery entries in the picker. Default createDefaultImageryProviderViewModels(). |
selectedTerrainProviderViewModel | Initial terrain entry when the base layer picker is enabled. Defaults to the first available entry. |
terrainProviderViewModels | Terrain entries in the picker. Default createDefaultTerrainProviderViewModels(). |
baseLayer | Initial bottom imagery layer or false. Default ImageryLayer.fromWorldImagery(). Requires baseLayerPicker: false and a globe. |
ellipsoid | Ellipsoid for geographic calculations. Default Ellipsoid.default. |
terrainProvider | Terrain provider. Default new EllipsoidTerrainProvider(). |
terrain | Asynchronous Terrain instance. Cannot be set alongside terrainProvider. |
skyBox | Stars background or false. Default stars for the WGS84 ellipsoid. false also omits the Sun and Moon. |
skyAtmosphere | Sky and atmosphere or false. Enabled for the WGS84 ellipsoid. |
sceneMode | Initial view mode. Default SceneMode.SCENE3D. |
projectionPicker | Show the map projection selector. Default false. |
scene3DOnly | Restrict geometry rendering to 3D. Set false for applications that switch to 2D. Default false. |
mapProjection | Projection in 2D and Columbus View. Default new GeographicProjection(options.ellipsoid). |
globe | Custom globe or false to hide it. Default new Globe(options.ellipsoid). |
mapMode2D | 2D rotation/scroll behavior. Default MapMode2D.INFINITE_SCROLL. |
shadows | Enable shadows cast by light sources. Default false. |
terrainShadows | Terrain shadow behavior. Default ShadowMode.RECEIVE_ONLY. |
Rendering and Performance
| Option | Description and default |
|---|---|
useDefaultRenderLoop | Let Viewer render and resize automatically. Default true. |
targetFrameRate | Preferred rate for the default rendering loop. No specified default. |
showRenderLoopErrors | Display errors from the render loop on the page. Default true. |
useBrowserRecommendedResolution | Render at the browser’s recommended resolution. Default true. |
automaticallyTrackDataSourceClocks | Follow new data sources’ clocks. Default true. |
contextOptions | WebGL context and scene creation settings. |
orderIndependentTranslucency | Use order-independent transparency when available. Default true. |
requestRenderMode | Render frames only when needed. External scene changes can require viewer.scene.requestRender(). Default false. |
maximumRenderTimeChange | Maximum simulation-time change before rendering in request-render mode. Default 0.0. |
depthPlaneEllipsoidOffset | Offset the depth plane to address artifacts below zero elevation. Default 0.0. |
msaaSamples | Multisample antialiasing rate for compatible WebGL2 contexts. Default 4. |
Data and Attribution
| Option | Description and default |
|---|---|
creditContainer | DOM element or ID for map attribution. Default is the viewer’s bottom area. |
creditViewport | DOM element or ID for the attribution popup. Default is the viewer. |
dataSources | Existing DataSourceCollection. Default new DataSourceCollection(). Caller-owned collections are not destroyed with Viewer. |
Viewer Properties
Scene and Data Properties
| Property | Description |
|---|---|
camera | Read-only camera instance. |
scene | Read-only scene instance. |
canvas | Read-only rendering canvas. |
container | Read-only parent DOM element. |
cesiumWidget | Read-only underlying Cesium widget. |
ellipsoid | Read-only default ellipsoid. |
entities | Read-only collection of entities outside custom data sources. |
dataSources | Read-only collection of data sources. |
dataSourceDisplay | Read-only data source renderer. |
imageryLayers | Read-only imagery layer collection. |
terrainProvider | Get or set the terrain provider. |
postProcessStages | Read-only collection of postprocessing stages. |
shadowMap | Read-only shadow map. |
creditDisplay | Attribution display for on-screen credit text and the credit popup. |
bottomContainer | Read-only bottom DOM container for attribution and controls. |
Widgets, Clock, and Selection
| Property | Description |
|---|---|
animation | Read-only animation control. |
baseLayerPicker | Read-only base layer selector. |
fullscreenButton | Read-only fullscreen widget. |
geocoder | Read-only search widget. |
homeButton | Read-only home button. |
infoBox | Read-only entity information widget. |
navigationHelpButton | Read-only navigation help button. |
projectionPicker | Read-only projection selector. |
sceneModePicker | Read-only scene mode selector. |
selectionIndicator | Read-only selection marker widget. |
timeline | Read-only timeline widget. |
vrButton | Read-only VR widget. |
clock | Read-only simulation clock. |
clockViewModel | Read-only clock view model. |
clockTrackedDataSource | Get or set the data source driving the simulation clock. |
selectedEntity | Get or set the currently selected entity. |
trackedEntity | Get or set the entity followed by the camera. |
Rendering State and Events
| Property | Description |
|---|---|
allowDataSourcesToSuspendAnimation | Permit data sources to pause animation while loading. |
resolutionScale | Render-resolution multiplier. Default 1.0. |
shadows | Enable or disable light-source shadows. |
targetFrameRate | Get or set the preferred frame rate for the default render loop. Must be greater than zero if set. |
terrainShadows | Get or set terrain shadow mode. |
useBrowserRecommendedResolution | Ignore the device pixel ratio and render at CSS-pixel resolution when true. Default true. |
useDefaultRenderLoop | Let Viewer manage rendering and resizing. |
screenSpaceEventHandler | Read-only scene input handler. |
selectedEntityChanged | Event raised when selectedEntity changes. |
trackedEntityChanged | Event raised when trackedEntity changes. |
Viewer Methods
| Method | Description |
|---|---|
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
| Event | Trigger |
|---|---|
selectedEntityChanged | The selected entity changes. Listener receives the new selection. |
trackedEntityChanged | The 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
- Cobe: 3D Globe With Dotted World Map Using WebGL
- Interactive SVG World Map Library – svgMap.js
- 212 Interactive SVG Maps for JavaScript – svg-world-maps
- jsvectormap: JavaScript Library For Interactive Vector Maps
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.







