cesiumgs/cesiumjs-skills/cesiumjs-viewer-setup

Claude Code and agent skill by cesiumgs/cesiumjs-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

CesiumJS viewer setup - Viewer, CesiumWidget, widgets, Ion token, Scene configuration, SceneMode, factory helpers, geocoders, platform services. Use when initializing a CesiumJS application, configuring viewer widgets, setting Ion access tokens, creating default terrain or imagery, or bootstrapping a 3D globe.

Install

npx vskill@latest install cesiumgs/cesiumjs-skills/cesiumjs-viewer-setup

SKILL.md

CesiumJS Viewer & Scene Setup

Reference for bootstrapping CesiumJS applications: Viewer, CesiumWidget, Ion/GoogleMaps/ITwinPlatform configuration, widgets, factory helpers, geocoder services, viewer mixins, Credits, and related enums.

Quick Start

js
import { Viewer, ImageryLayer, OpenStreetMapImageryProvider } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
const viewer = new Viewer("cesiumContainer", {
baseLayer: new ImageryLayer(new OpenStreetMapImageryProvider({
url: "https://tile.openstreetmap.org/",
maximumLevel: 18,
})),
baseLayerPicker: false,
});

Required HTML: <div id="cesiumContainer" style="width:100%;height:100vh"></div>

Use Cesium ion defaults (Terrain.fromWorldTerrain, ImageryLayer.fromWorldImagery, createOsmBuildingsAsync, Google Photorealistic 3D Tiles) only when the target runtime has the required ion or Google entitlement. For public/no-token examples, choose explicit public providers and URL-backed 3D Tiles.

Framing Loaded Content (Critical)

After adding a tileset, model, or data source, you must explicitly frame it. A Viewer constructed with default options starts the camera at a fixed view of Earth. It does NOT auto-zoom to primitives you add. Forgetting this is the most common cause of "I see only gray surface" or "the asset is a speck in the corner" failures.

js
const tileset = await Cesium3DTileset.fromUrl(url);
viewer.scene.primitives.add(tileset);
// Pick ONE of:
await viewer.zoomTo(tileset); // instant fit to bounding sphere
await viewer.flyTo(tileset, { duration: 0 }); // animated; duration 0 = instant

viewer.zoomTo / viewer.flyTo accept Entity, Entity[], EntityCollection, DataSource, ImageryLayer, Cesium3DTileset, VoxelPrimitive, Model, or TimeDynamicPointCloud. They use the target's bounding sphere, which works for tilesets with arbitrary local coordinate systems where computing an ECEF camera position by hand will miss the asset entirely.

When you do need an explicit camera position (e.g., to satisfy a heading/pitch specification), still use viewer.zoomTo(target, headingPitchRange) so the range is derived from the bounding sphere rather than guessed:

js
import { HeadingPitchRange, Math as CesiumMath } from "cesium";
await viewer.zoomTo(tileset, new HeadingPitchRange(
CesiumMath.toRadians(45), // heading
CesiumMath.toRadians(-30), // pitch
/* range omitted -> auto-fit */
));

Ion & Platform Configuration

Cesium Ion
js
import { Ion } from "cesium";
Ion.defaultAccessToken = "YOUR_TOKEN"; // required for ion assets
Ion.defaultServer = "https://your-ion-server.example.com/"; // optional: self-hosted
IonResource
js
import { IonResource, Cesium3DTileset } from "cesium";
const resource = await IonResource.fromAssetId(96188);
const tileset = await Cesium3DTileset.fromUrl(resource);
viewer.scene.primitives.add(tileset);
await viewer.zoomTo(tileset);
Google Maps Platform
js
import { GoogleMaps, createGooglePhotorealistic3DTileset, Viewer, IonGeocodeProviderType } from "cesium";
GoogleMaps.defaultApiKey = "YOUR_GOOGLE_MAPS_API_KEY"; // optional: without key, served via ion
const viewer = new Viewer("cesiumContainer", {
geocoder: IonGeocodeProviderType.GOOGLE, // required with Google 3D Tiles
});
const tileset = await createGooglePhotorealistic3DTileset({
onlyUsingWithGoogleGeocoder: true,
});
viewer.scene.primitives.add(tileset);
iTwin Platform (experimental)
js
import { ITwinPlatform, ITwinData } from "cesium";
ITwinPlatform.defaultAccessToken = "YOUR_ITWIN_TOKEN";
const tileset = await ITwinData.createTilesetForIModel(viewer, "imodel-id");
// 1.140+ (#13208): Reality Data of type GaussianSplat3DTiles is now supported
const splats = await ITwinData.createTilesetForRealityDataId(
iTwinId,
realityDataId,
ITwinPlatform.RealityDataType.GaussianSplat3DTiles,
);
viewer.scene.primitives.add(splats);

Viewer Constructor Options

new Viewer(container, options?) -- container is a DOM element or its string ID.

Widget Toggles
OptionDefaultPurpose
animationtruePlayback controls
baseLayerPickertrueImagery/terrain switcher
fullscreenButtontrueFullscreen toggle
vrButtonfalseWebVR toggle
geocoderIonGeocodeProviderType.DEFAULTSearch bar (false to hide)
homeButtontrueReset to home view
infoBoxtrueEntity info popup
sceneModePickertrue2D/3D/Columbus toggle
selectionIndicatortrueSelection reticle
timelinetrueTime scrubber
navigationHelpButtontrueMouse/touch help
projectionPickerfalsePerspective/ortho toggle
Scene & Rendering
OptionDefaultPurpose
sceneModeSceneMode.SCENE3DInitial scene mode
scene3DOnlyfalseLock to 3D, saves GPU memory per geometry instance
shadowsfalseShadow casting
terrainShadowsShadowMode.RECEIVE_ONLYTerrain shadow mode
requestRenderModefalseRender only on changes
maximumRenderTimeChange0.0Max sim-time delta for render
msaaSamples4MSAA (1 to disable)
orderIndependentTranslucencytrueTranslucent ordering
mapMode2DMapMode2D.INFINITE_SCROLL2D scroll behavior

Pair requestRenderMode: true with scene3DOnly: true for low-power / dashboard apps; both are commonly required together when the scenario calls for GPU savings.

Layers & Terrain
OptionDefaultPurpose
baseLayerImageryLayer.fromWorldImagery()Base imagery (false for none; needs baseLayerPicker: false)
terrainnoneAsync terrain helper (cannot combine with terrainProvider)
terrainProviderEllipsoidTerrainProviderSync terrain provider
globenew Globe()false for no globe (space scenes)
skyBoxauto (WGS84)false disables sky/sun/moon
skyAtmosphereauto (WGS84)false disables limb glow
Minimal Viewer (No Widgets)
js
import { Viewer, ImageryLayer, OpenStreetMapImageryProvider } from "cesium";
const viewer = new Viewer("cesiumContainer", {
baseLayer: new ImageryLayer(new OpenStreetMapImageryProvider({
url: "https://tile.openstreetmap.org/",
maximumLevel: 18,
})),
animation: false, baseLayerPicker: false, fullscreenButton: false,
geocoder: false, homeButton: false, infoBox: false,
sceneModePicker: false, selectionIndicator: false,
timeline: false, navigationHelpButton: false,
});

CesiumWidget (Lightweight Alternative)

No UI widgets, no Knockout dependency. Suitable for custom UIs or embedding.

js
import { CesiumWidget, Ion } from "cesium";
Ion.defaultAccessToken = "YOUR_TOKEN";
const widget = new CesiumWidget("cesiumContainer", { shouldAnimate: true });
// Exposes: widget.scene, widget.camera, widget.entities

SceneMode Enum

ValueDescription
SceneMode.SCENE3DStandard 3D globe (default)
SceneMode.SCENE2DTop-down orthographic map
SceneMode.COLUMBUS_VIEW2.5D flat map with height
SceneMode.MORPHINGTransitioning between modes
js
import { Viewer, SceneMode } from "cesium";
const viewer = new Viewer("cesiumContainer", { sceneMode: SceneMode.SCENE2D });
viewer.scene.morphTo3D(2.0); // animated transition
viewer.scene.morphToColumbusView(2.0);

Scene Configuration

js
const scene = viewer.scene;
scene.globe.depthTestAgainstTerrain = true; // entities interact with terrain
scene.globe.enableLighting = true; // sun-based lighting
// Key sub-objects
scene.camera; // Camera
scene.primitives; // PrimitiveCollection
scene.groundPrimitives; // PrimitiveCollection (ground-clamped)
scene.imageryLayers; // ImageryLayerCollection
scene.postProcessStages;
scene.requestRender(); // trigger frame in requestRenderMode

Important: never touch `scene.globe.*` or `scene.skyAtmosphere.*` when the matching constructor option was set to `false`. Disabling these in the Viewer options leaves the corresponding property as undefined on the scene, and accessing .enableLighting, .depthTestAgainstTerrain, .show, or any other field throws TypeError: Cannot set properties of undefined. For space scenes, configure once in the constructor and do not mutate those properties afterward (see "Space Scene" below).

Factory Helpers

createOsmBuildingsAsync
js
import { createOsmBuildingsAsync, Cesium3DTileStyle } from "cesium";
// Default styling (colors from OSM tags)
const tileset = await createOsmBuildingsAsync();
viewer.scene.primitives.add(tileset);
// Custom style
const styled = await createOsmBuildingsAsync({
style: new Cesium3DTileStyle({
color: { conditions: [
["${feature['building']} === 'hospital'", "color('#0000FF')"],
[true, "color('#ffffff')"],
]},
}),
});
createGooglePhotorealistic3DTileset
js
import { createGooglePhotorealistic3DTileset, IonGeocodeProviderType } from "cesium";
// Must use Google geocoder
const viewer = new Viewer("cesiumContainer", { geocoder: IonGeocodeProviderType.GOOGLE });
const tileset = await createGooglePhotorealistic3DTileset({ onlyUsingWithGoogleGeocoder: true });
viewer.scene.primitives.add(tileset);
Terrain.fromWorldTerrain / fromWorldBathymetry

Preferred for the terrain constructor option. Non-blocking with error events.

js
import { Viewer, Terrain } from "cesium";
// World terrain with normals and water
const viewer = new Viewer("cesiumContainer", {
terrain: Terrain.fromWorldTerrain({ requestVertexNormals: true, requestWaterMask: true }),
});
// Bathymetry (ocean floor)
const viewer2 = new Viewer("cesiumContainer", {
terrain: Terrain.fromWorldBathymetry({ requestVertexNormals: true }),
});
Terrain Event Handling
js
import { Terrain, CesiumTerrainProvider } from "cesium";
const terrain = new Terrain(CesiumTerrainProvider.fromUrl("https://my-terrain.example.com"));
viewer.scene.setTerrain(terrain);
terrain.readyEvent.addEventListener((provider) => {
viewer.scene.globe.enableLighting = true;
});
terrain.errorEvent.addEventListener((error) => console.error("Terrain failed:", error));
createWorldTerrainAsync / createWorldImageryAsync

Lower-level: return raw providers. Use when you need the provider directly.

js
import { createWorldTerrainAsync, createWorldImageryAsync, IonWorldImageryStyle } from "cesium";
const terrainProvider = await createWorldTerrainAsync({ requestVertexNormals: true });
viewer.terrainProvider = terrainProvider;
const imageryProvider = await createWorldImageryAsync({ style: IonWorldImageryStyle.AERIAL_WITH_LABELS });

IonWorldImageryStyle: AERIAL (default) | AERIAL_WITH_LABELS | ROAD

Geocoder Configuration

The geocoder option accepts false, an IonGeocodeProviderType, or a GeocoderService[].

IonGeocodeProviderType: DEFAULT | GOOGLE (required with Google tiles) | BING

js
import { Viewer, CartographicGeocoderService, IonGeocoderService, OpenCageGeocoderService } from "cesium";
// Multiple services (searched in order)
const viewer = new Viewer("cesiumContainer", {
geocoder: [
new CartographicGeocoderService(), // accepts "lat, lon" input
new IonGeocoderService({ scene: viewer.scene }),
],
});
Custom GeocoderService

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
76
Repository forks
10
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 30 May 2026, 5 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cesiumgs/cesiumjs-skills/cesiumjs-viewer-setup/badge)](https://verified-skill.com/skills/cesiumgs/cesiumjs-skills/cesiumjs-viewer-setup)

Something wrong with this skill or its page? Tell us.