About build-with-arcgis-and-openlayers
A skill for developers building ArcGIS maps with OpenLayers, explaining how to combine ol, ol-mapbox-style, and ArcGIS REST JS. It stresses explicit handling of ArcGIS data formats, authentication, projections, and service limits.
Key features
- 01OpenLayers map and layer setup
- 02Applying ArcGIS basemap styles
- 03REST JS authentication and location services
- 04Feature queries, edits, and pagination
- 05Coordinate system and geometry handling
Use cases
- 01Build browser maps with ArcGIS services
- 02Query and render feature service data
- 03Add basemaps while preserving attribution
- 04Handle map edits and query pagination
MCP support
The skill supports querying official OpenLayers and ArcGIS REST JS documentation through Esri's developer documentation MCP.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ esri/ esri-developer-agent-skills --skill build-with-arcgis-and-openlayersAfter installing, type/build-with-arcgis-and-openlayersin Claude Code to confirm it loaded.
Details
From the project READMEBuild with OpenLayers and ArcGIS
OpenLayers (OL) renders browser maps with ArcGIS services. Use ol (maps/layers), ol-mapbox-style (ArcGIS Basemap Styles v2), and ArcGIS REST JS (@esri/arcgis-rest-*; auth, queries, location services).
OpenLayers is not an ArcGIS Maps SDK: it has no FeatureLayer/WebMap classes and does not interpret ArcGIS popup templates or renderers. Resolve endpoints and translate ArcGIS JSON explicitly.
ArcGIS account requirements
Developers must have one of the following ArcGIS accounts to create applications: ArcGIS Location Platform (free), or ArcGIS Online or ArcGIS Enterprise with a Creator, Professional, or Professional Plus user type. The account's user type, role, and privileges provide access to different resources and operations.
Authentication
DO NOT SKIP: Refer to the follow-arcgis-authentication-patterns skill for ArcGIS authentication requirements, including the appropriate type of authentication for different audiences, use cases, and types of application. If the skill is not available, search the project for any existing authentication patterns, and if none are found, query the documentation MCP for authentication best practices.
Installation and setup
Use ol-mapbox-style for vector basemaps and REST JS for location services including geocoding, routing, elevation, geoenrichment, and authentication. Load OpenLayers CSS, give the map container a definite non-zero width/height, serve over HTTP(S), never file://, and verify current APIs/versions.
New application
Infer requirements from the prompt/project; clarify uncertainties before scaffolding.
New application with CDN
Use current ArcGIS OpenLayers examples: link ol.css as a stylesheet; load dist/ol.js, and needed REST JS UMD scripts in dependency order. These bundles expose globals; don't load them as ESM. Check URLs/versions via MCP. Most ArcGIS documentation shows CDN imports; use them for testing, demos, tutorials, samples, and lightweight quickstarts.
New application with npm
Use npm create ol-app my-app or Vite unless a framework is specified. Install ol, ol-mapbox-style, and any required @esri/arcgis-rest-* packages (request, feature-service, geocoding, routing, places). Use ESM imports and import ol/ol.css through the bundler; pin compatible versions per ol-mapbox-style notes. Prefer this for production, larger, or framework apps; use the project's package manager. React, Angular, Vue, and Svelte are supported frameworks. If using a framework-specific template other than create ol-app, remove all template files that are not relevant to the user's request (e.g. counter.js).
Existing application
Before installing, identify package manager/lockfile, framework, CDN vs modules, TypeScript/ESLint config, and bundler. Conform; add only needed ol, ol-mapbox-style, and REST JS packages. Preserve credential/environment conventions, import ol/ol.css, size the map, and check compatibility before upgrades.
How to query documentation
Documentation can be queried using the MCP for Esri developer documentation server:
https://developers-mcp.arcgis.com/mcp
Use the search_esri_developer_docs tool to surface authoritative documentation pages with openlayers as the focus_area parameter in addition to a specified search_term; use the arcgis-rest-js focus area for ArcGIS REST JS queries. Use the fetch_esri_developer_docs tool with the page_url parameter set to return the full content of a documentation page in Markdown format.
Clearly indicate any recommendations and assumptions that are not grounded in the official documentation. If MCP is unavailable, consult official documentation URLs below.
Documentation links
Patterns and guidelines
Authentication integration
- Verify service-specific account support: Enterprise credentials alone do not authorize ArcGIS Location Services; use a supported Location Platform/Online credential for those services.
- API keys: Use
ApiKeyManager.fromKey(apiKey)from@esri/arcgis-rest-requestas REST JSauthentication. Grant least privileges/item access; restrict browser keys by referrer. Browser keys are visible, even when set via build-time env vars. Never expose client secrets. - OAuth: Use REST JS
ArcGISIdentityManagerwith PKCE and exact redirect URIs. - Native OL sources: REST JS does not integrate directly. Attach/refresh credentials in source loaders or
tileLoadFunction; never expose client secrets or log tokenized URLs. - See
arcgis-rest-jsandfollow-esri-authentication-patternsskills.
Basemaps, styles, and attribution
- Apply Basemap Styles v2 with
ol-mapbox-styleapply(layerGroup, styleUrl)to a dedicatedLayerGroup, then add it to the map. - Await style application before adding dependent layers; handle failures. Replace only this group when switching styles.
- Preserve visible Powered by Esri and each data item's required attribution/acknowledgments; do not overwrite source credits.
Layer and source selection
- Feature services: Query the layer endpoint (
FeatureServer/<layerId>) with REST JS. Parse withEsriJSON/GeoJSONand add toVectorSource. Set read optionsdataProjectionto response CRS andfeatureProjectionto view CRS. Usebboxfromol/loadingstrategy.jsfor viewport loading; assign stable feature IDs from service object IDs to avoid duplicates. On loader failure,removeLoadedExtent(extent)permits reloading but does not trigger it; retry on a later load cycle or deliberate trigger, with bounded retries. - Feature styling: Inspect layer metadata (
drawingInfo.renderer); translate relevant symbols, unique-value/class-break rules, and scale limits into OpenLayers styles. Keep legends consistent with rendered symbols. Report unsupported renderer details rather than claiming faithful reproduction. - Editing: Check capability/privileges. Submit ArcGIS geometry/attributes, not OpenLayers feature objects, with REST JS
applyEdits. Inspect each add/update/delete result; a resolved request can contain failed edits. Update/refresh only successful edits and surface failures. - Vector tiles:
VectorTileLayer+VectorTileSource(ol/format/MVT) for large data/hit detection. Useol-mapbox-stylewith the service's style JSON for published styling, or explicit OpenLayers styles for intentional overrides. Attributes vary by tile/zoom; use feature services for full queries/edits. - Cached tiles:
TileLayer+XYZwith/MapServer/tile/{z}/{y}/{x}. InspecttileInfoand the service spatial reference; verify tile size, origin, resolutions, and level IDs before assuming a standard XYZ grid. Configure a matching tile grid and level mapping when needed. For canvas export setcrossOrigin: "anonymous"and verify service CORS; the option alone is insufficient. - Dynamic map services: Use
ImageLayer+ImageArcGISRestorTileLayer+TileArcGISRestfor exportedMapServerimages. - Popups: Treat attributes as untrusted. Prefer DOM
textContent; sanitize any HTML.
Coordinate systems and geometry handling
- OpenLayers’ default view projection is Web Mercator (
EPSG:3857). Many ArcGIS location-service examples use WGS 84 (EPSG:4326) coordinates in[longitude, latitude]order, but supported input and output spatial references vary by service and operation. Check the service requirements, and usefromLonLat/toLonLatwhen converting between geographic coordinates and the map view projection. For non-default views, register unsupported projections as needed and pass the actual view projection tofromLonLat/toLonLatandol/spheremeasurements. - Set query
inSRto the input geometry's spatial reference andoutSRto the requested output CRS; do not hardcode 3857 for non-Web-Mercator views. - Match response format (
EsriJSON/GeoJSON); set readerdataProjectionandfeatureProjection. - Use
ol/spherefor real-world distance/area; Web Mercator planar measurements distort, especially at high latitudes.
Queries, pagination, and performance
- Check
?f=pjsonformaxRecordCountand capabilities. - On
exceededTransferLimit, useresultOffset/resultRecordCountonly if supported, with stable ordering where supported; otherwise retrieve object IDs and query them in batches. See Query docs. - Request needed
outFields; setreturnGeometry: falsefor attribute-only queries. - For large datasets, limit request concurrency and query at useful zoom levels.
bboxloading retains features as users pan; choose bounded caching or viewport replacement. Keep loaded-extent bookkeeping consistent with feature eviction so revisiting an area reloads missing data. - Build
whereclauses from known fields and validated/escaped values, never raw user input. - Restrict popup hit tests with
layerFilterinforEachFeatureAtPixel. - Debounce geocoding; prevent stale results. Show loading/empty/error states; don't treat failures as empty data.
Framework lifecycle and resilience
- In React/Vue/Angular, initialize in lifecycle hooks (
useEffect,onMounted,ngAfterViewInit) after DOM mount; keep map in a ref/service, not reactive state. - On unmount,
unByKeylisteners, remove controls/overlays, cancel pending work/observers, and callmap.setTarget(undefined)to detach the map. Ignore late async results after teardown. - Call
map.updateSize()when the container resizes or becomes visible. - Handle rejected requests and source load errors (
tileloaderror,imageloaderror,featuresloaderror); make errors actionable without exposing tokens. - Require labeled controls, keyboard access, accessible status messages, touch-friendly layouts, and an alternative list/table for important results.
- Give the map container a definite height and verify the rendered viewport is nonzero.
Validation process
- Compatible packages install and build.
- CSS/container dimensions are set; map renders without layout collapse.
- Auth succeeds without client secrets in browser code.
- Basemap/layers render with required Esri and data credits.
- Feature styles and legends match intended renderer rules; unsupported details are documented.
- Queries use correct
inSR/outSR, request needed data, handle limits, and render correctly. - Repeated panning keeps requests/features bounded; evicted areas reload and failed loads can be retried.
- Interactions handle empty/error results, partial edit failures, and stale responses without unsafe HTML or unhandled rejections.
- Teardown removes listeners, detaches map, and handles
updateSize(). - Controls/results work with keyboard and touch, status messages are accessible, and layouts adapt to small screens.
- Browser smoke test covers rendering, service requests, interactions, resizing, and teardown; check console/network errors. If browser testing is unavailable, report what remains unverified.