/cesiumjs-primitives
CesiumJS primitives and geometry - Primitive, GeometryInstance, Appearance, BufferPrimitive collections, GeoJsonPrimitive, Billboard/Label/PointPrimitive collections, built-in geometry shapes, ground primitives, classification. Use when rendering performance-critical static or
$ npx -y skills add CesiumGS/cesiumjs-skills --skill cesiumjs-primitives --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/cesiumjs-primitives
Context preview
The summary Claude sees to decide when to auto-load this skill.
CesiumJS primitives and geometry - Primitive, GeometryInstance, Appearance, BufferPrimitive collections, GeoJsonPrimitive, Billboard/Label/PointPrimitive collections, built-in geometry shapes, ground primitives, classification. Use when rendering performance-critical static or
SKILL.md
cesiumjs-primitives.SKILL.mdname: cesiumjs-primitives
description: "CesiumJS primitives and geometry - Primitive, GeometryInstance, Appearance, BufferPrimitive collections, GeoJsonPrimitive, Billboard/Label/PointPrimitive collections, built-in geometry shapes, ground primitives, classification. Use when rendering performance-critical static or vector geometry, loading GeoJSON without entities, creating custom shapes, batching draw calls, or using low-level collections."
CesiumJS Primitives & Geometry
> **Applies to:** CesiumJS v1.143+ (ES module imports, `??` instead of `defaultValue`)
Architecture
The Primitive API is the low-level rendering layer beneath the Entity API, trading convenience for performance.
**Core formula:** `Primitive = GeometryInstance[] + Appearance`
- **GeometryInstance** -- positions a Geometry in world space with per-instance attributes (color, show).
- **Geometry** -- vertex data describing a shape (polygon, box, ellipsoid, etc.).
- **Appearance** -- GLSL shaders + render state + optional Material that shade the geometry.
Primitives are **immutable after first render** -- geometry cannot change, but per-instance attributes update via `primitive.getGeometryInstanceAttributes(id)`.
Primitive
import {
Viewer, Primitive, GeometryInstance, EllipseGeometry,
EllipsoidSurfaceAppearance, Material, Cartesian3, Math as CesiumMath,
} from "cesium";
const viewer = new Viewer("cesiumContainer");
const scene = viewer.scene;
const primitive = scene.primitives.add(new Primitive({
geometryInstances: new GeometryInstance({
geometry: new EllipseGeometry({
center: Cartesian3.fromDegrees(-100.0, 40.0),
semiMinorAxis: 250000.0,
semiMajorAxis: 400000.0,
rotation: CesiumMath.PI_OVER_FOUR,
vertexFormat: EllipsoidSurfaceAppearance.VERTEX_FORMAT, // must match appearance
}),
id: "myEllipse", // returned by Scene.pick()
}),
appearance: new EllipsoidSurfaceAppearance({ material: Material.fromType("Stripe") }),
}));Key Options
| Option | Default | Purpose | |---|---|---| | `geometryInstances` | -- | Single instance or array | | `appearance` | -- | Shading (Appearance subclass) | | `show` | `true` | Toggle visibility | | `modelMatrix` | `Matrix4.IDENTITY` | Transform all instances | | `asynchronous` | `true` | Build geometry on web worker | | `releaseGeometryInstances` | `true` | Free geometry after GPU upload | | `allowPicking` | `true` | `false` saves GPU memory | | `shadows` | `ShadowMode.DISABLED` | Cast/receive shadows |
Batching Multiple Instances
All instances in one Primitive share a single draw call.
import {
Primitive, GeometryInstance, RectangleGeometry, EllipseGeometry,
PerInstanceColorAppearance, ColorGeometryInstanceAttribute,
Cartesian3, Rectangle, Color,
} from "cesium";
scene.primitives.add(new Primitive({
geometryInstances: [
new GeometryInstance({
geometry: new RectangleGeometry({
rectangle: Rectangle.fromDegrees(-140, 30, -100, 40),
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
}),
id: "rect",
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.RED.withAlpha(0.5)) },
}),
new GeometryInstance({
geometry: new EllipseGeometry({
center: Cartesian3.fromDegrees(-80, 35),
semiMinorAxis: 200000.0,
semiMajorAxis: 300000.0,
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
}),
id: "ellipse",
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.BLUE.withAlpha(0.5)) },
}),
],
appearance: new PerInstanceColorAppearance(),
}));Updating Per-Instance Attributes
import { ColorGeometryInstanceAttribute, ShowGeometryInstanceAttribute } from "cesium";
// Wait for async geometry compilation
const removeListener = scene.postRender.addEventListener(() => {
if (!primitive.ready) return;
const attrs = primitive.getGeometryInstanceAttributes("rect");
attrs.color = ColorGeometryInstanceAttribute.toValue(Color.YELLOW);
attrs.show = ShowGeometryInstanceAttribute.toValue(true);
removeListener();
});PrimitiveCollection
Nestable container -- `scene.primitives` is itself a PrimitiveCollection.
import { PrimitiveCollection, BillboardCollection, LabelCollection } from "cesium";
const group = new PrimitiveCollection();
group.add(new BillboardCollection());
group.add(new LabelCollection());
scene.primitives.add(group);
group.show = false; // toggle all childrenChoosing a Vector Data Path
| Need | Use | |---|---| | Entity lifecycle, clustering, per-entity styling, time-dynamic values | `GeoJsonDataSource` in `cesiumjs-entities` | | One large GeoJSON object with low overhead and primitive-level performance | `GeoJsonPrimitive` in this skill | | Tiled vector data, 3D Tiles LOD, metadata styling, feature picking | `MVTDataProvider` in `cesiumjs-3d-tiles` | | Fully manual high-throughput point/polyline/polygon buffers | `BufferPointCollection`, `BufferPolylineCollection`, `BufferPolygonCollection` |
Buffer Primitive Collections (Experimental, 1.140+)
Use `BufferPointCollection`, `BufferPolylineCollection`, and `BufferPolygonCollection` for very large vector datasets where Entity/DataSource overhead is too high. These APIs were introduced in 1.140 (#13212) and refined through 1.142; they are experimental and use flyweight primitive objects: reuse one `BufferPoint`, `BufferPolyline`, or `BufferPolygon` when adding or iterating thousands of items.
import {
BlendOption,
BoundingSphere,
BufferPoint,
BufferPointCollection,
BufferPointMaterial,
Cartesian3,
Color,
} from "cesium";
const positions = [
Cartesian3.fromDegrees(-75.16, 39.95),
Cartesian3.fromDegrees(-73.98, 40.75),
];
const points = scene.primitives.add(new BufferPointCollection({
primitiveCountMax: positions.length,
allowPicking: true,
blendOption: BlendOption.TRANSLUCENT,
boundingVolume: BoundingSphere.fromPoints(positioRead more
name: cesiumjs-primitives description: "CesiumJS primitives and geometry - Primitive, GeometryInstance, Appearance, BufferPrimitive collections, GeoJsonPrimitive, Billboard/Label/PointPrimitive collections, built-in geometry shapes, ground primitives, classification. Use when rendering performance-critical static or vector geometry, loading GeoJSON without entities, creating custom shapes, batching draw calls, or using low-level collections."
CesiumJS Primitives & Geometry
> **Applies to:** CesiumJS v1.143+ (ES module imports, `??` instead of `defaultValue`)
Architecture
The Primitive API is the low-level rendering layer beneath the Entity API, trading convenience for performance.
**Core formula:** `Primitive = GeometryInstance[] + Appearance`
- **GeometryInstance** -- positions a Geometry in world space with per-instance attributes (color, show).
- **Geometry** -- vertex data describing a shape (polygon, box, ellipsoid, etc.).
- **Appearance** -- GLSL shaders + render state + optional Material that shade the geometry.
Primitives are **immutable after first render** -- geometry cannot change, but per-instance attributes update via `primitive.getGeometryInstanceAttributes(id)`.
Primitive
import {
Viewer, Primitive, GeometryInstance, EllipseGeometry,
EllipsoidSurfaceAppearance, Material, Cartesian3, Math as CesiumMath,
} from "cesium";
const viewer = new Viewer("cesiumContainer");
const scene = viewer.scene;
const primitive = scene.primitives.add(new Primitive({
geometryInstances: new GeometryInstance({
geometry: new EllipseGeometry({
center: Cartesian3.fromDegrees(-100.0, 40.0),
semiMinorAxis: 250000.0,
semiMajorAxis: 400000.0,
rotation: CesiumMath.PI_OVER_FOUR,
vertexFormat: EllipsoidSurfaceAppearance.VERTEX_FORMAT, // must match appearance
}),
id: "myEllipse", // returned by Scene.pick()
}),
appearance: new EllipsoidSurfaceAppearance({ material: Material.fromType("Stripe") }),
}));Key Options
| Option | Default | Purpose | |---|---|---| | `geometryInstances` | -- | Single instance or array | | `appearance` | -- | Shading (Appearance subclass) | | `show` | `true` | Toggle visibility | | `modelMatrix` | `Matrix4.IDENTITY` | Transform all instances | | `asynchronous` | `true` | Build geometry on web worker | | `releaseGeometryInstances` | `true` | Free geometry after GPU upload | | `allowPicking` | `true` | `false` saves GPU memory | | `shadows` | `ShadowMode.DISABLED` | Cast/receive shadows |
Batching Multiple Instances
All instances in one Primitive share a single draw call.
import {
Primitive, GeometryInstance, RectangleGeometry, EllipseGeometry,
PerInstanceColorAppearance, ColorGeometryInstanceAttribute,
Cartesian3, Rectangle, Color,
} from "cesium";
scene.primitives.add(new Primitive({
geometryInstances: [
new GeometryInstance({
geometry: new RectangleGeometry({
rectangle: Rectangle.fromDegrees(-140, 30, -100, 40),
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
}),
id: "rect",
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.RED.withAlpha(0.5)) },
}),
new GeometryInstance({
geometry: new EllipseGeometry({
center: Cartesian3.fromDegrees(-80, 35),
semiMinorAxis: 200000.0,
semiMajorAxis: 300000.0,
vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
}),
id: "ellipse",
attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.BLUE.withAlpha(0.5)) },
}),
],
appearance: new PerInstanceColorAppearance(),
}));Updating Per-Instance Attributes
import { ColorGeometryInstanceAttribute, ShowGeometryInstanceAttribute } from "cesium";
// Wait for async geometry compilation
const removeListener = scene.postRender.addEventListener(() => {
if (!primitive.ready) return;
const attrs = primitive.getGeometryInstanceAttributes("rect");
attrs.color = ColorGeometryInstanceAttribute.toValue(Color.YELLOW);
attrs.show = ShowGeometryInstanceAttribute.toValue(true);
removeListener();
});PrimitiveCollection
Nestable container -- `scene.primitives` is itself a PrimitiveCollection.
import { PrimitiveCollection, BillboardCollection, LabelCollection } from "cesium";
const group = new PrimitiveCollection();
group.add(new BillboardCollection());
group.add(new LabelCollection());
scene.primitives.add(group);
group.show = false; // toggle all childrenChoosing a Vector Data Path
| Need | Use | |---|---| | Entity lifecycle, clustering, per-entity styling, time-dynamic values | `GeoJsonDataSource` in `cesiumjs-entities` | | One large GeoJSON object with low overhead and primitive-level performance | `GeoJsonPrimitive` in this skill | | Tiled vector data, 3D Tiles LOD, metadata styling, feature picking | `MVTDataProvider` in `cesiumjs-3d-tiles` | | Fully manual high-throughput point/polyline/polygon buffers | `BufferPointCollection`, `BufferPolylineCollection`, `BufferPolygonCollection` |
Buffer Primitive Collections (Experimental, 1.140+)
Use `BufferPointCollection`, `BufferPolylineCollection`, and `BufferPolygonCollection` for very large vector datasets where Entity/DataSource overhead is too high. These APIs were introduced in 1.140 (#13212) and refined through 1.142; they are experimental and use flyweight primitive objects: reuse one `BufferPoint`, `BufferPolyline`, or `BufferPolygon` when adding or iterating thousands of items.
import {
BlendOption,
BoundingSphere,
BufferPoint,
BufferPointCollection,
BufferPointMaterial,
Cartesian3,
Color,
} from "cesium";
const positions = [
Cartesian3.fromDegrees(-75.16, 39.95),
Cartesian3.fromDegrees(-73.98, 40.75),
];
const points = scene.primitives.add(new BufferPointCollection({
primitiveCountMax: positions.length,
allowPicking: true,
blendOption: BlendOption.TRANSLUCENT,
boundingVolume: BoundingSphere.fromPoints(positioShowing the first part of this file.
Curated agent skills for CesiumJS development — 14 domain skills covering ~551 public symbols across the CesiumJS v1.143 API surface.
Repo: CesiumGS/cesiumjs-skills
Other skills on cesiumjs-skills.
- /cesiumjs-3d-tiles
CesiumJS 3D Tiles - Cesium3DTileset, compressed and CAD-style glTF content, MVTDataProvider, styling, metadata, feature picking, voxels, point clouds, I3S, Gaussian splats, clipping. Use when loading 3D Tiles or Mapbox Vector Tiles, rendering KHR meshopt/CAD content, styling or
Open skill - /cesiumjs-camera
CesiumJS camera control - Camera, flyTo, lookAt, setView, ScreenSpaceCameraController, CameraEventAggregator, flight animation. Use when positioning the camera, creating flyTo animations, constraining user navigation, tracking entities, or converting between screen and world
Open skill - /cesiumjs-core-utilities
CesiumJS core utilities and networking - Resource, Color, Event, Request, RequestScheduler, error handling, helper functions, feature detection. Use when fetching remote data, managing HTTP requests, working with colors, handling events, debugging errors, or using utility
Open skill - /cesiumjs-custom-shader
CustomShader authoring — vertexShaderText and fragmentShaderText against VertexInput, FragmentInput, FeatureIds, Metadata, czm_modelMaterial. Use when reading EXT_mesh_features or EXT_structural_metadata property textures/tables, vertex displacement, or shading VoxelPrimitive.
Open skill - /cesiumjs-entities
CesiumJS entities and data sources - Entity, EntityCollection, DataSource, GeoJsonDataSource, KmlDataSource, CzmlDataSource, Graphics types, PathGraphics, PathMode, Visualizers. Use when adding points, labels, models, polygons, polylines, or time-segmented paths, loading
Open skill - /cesiumjs-imagery
CesiumJS imagery layers - ImageryProvider, ImageryLayer, ImageryLayerCollection, WMS, WMTS, Bing, OpenStreetMap, ArcGIS, Mapbox, tile discard policies. Use when adding or swapping base map layers, configuring imagery providers, layering multiple map sources, or creating
Open skill

