ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
Leaflet interactive maps. Use when building a 2D map with tile layers, markers, popups, GeoJSON, layer control, custom controls or marker clustering.
$ npx -y skills add agents-inc/skills --skill web-maps-leaflet --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web-maps-leafletContext preview
The summary Claude sees to decide when to auto-load this skill.
Leaflet interactive maps. Use when building a 2D map with tile layers, markers, popups, GeoJSON, layer control, custom controls or marker clustering.
name: web-maps-leaflet description: Leaflet interactive maps. Use when building a 2D map with tile layers, markers, popups, GeoJSON, layer control, custom controls or marker clustering.
> **Quick Guide:** Leaflet is a small 2D mapping library: `L.map` initializes against a DOM element, > `L.tileLayer` supplies the base map, and everything drawn on top — markers, popups, GeoJSON, > controls — is a layer added to and removed from the map independently. `L.geoJSON` does most of > the data work through its `pointToLayer`, `onEachFeature`, `style` and `filter` callbacks. Marker > count is the decision that shapes the rest: past a hundred, DOM markers stop scaling and the work > moves to clustering or the canvas renderer. **Current: v1.9.4**, with types in `@types/leaflet`.
**Detailed Resources:**
---
<critical_requirements>
**Call `map.remove()` when the map goes away.** It is the one call that tears down the resize observers, animation frames and DOM listeners Leaflet attached; without it a re-mount on the same element throws "Map container is already initialized".
**Give every tile layer an `attribution`.** OpenStreetMap and most other providers require it in their terms, and there is no default.
**Move past DOM markers at around a hundred points** — `L.markerClusterGroup`, or `L.circleMarker` on the canvas renderer. Each `L.marker` is an element in the document, and the page slows in proportion.
</critical_requirements>
---
**Auto-detection:** Leaflet, `L.map`, `L.tileLayer`, `L.marker`, `L.popup`, `L.geoJSON`, `L.control.layers`, `L.layerGroup`, `L.featureGroup`, `L.icon`, `L.divIcon`, `L.circleMarker`, `L.polyline`, `L.polygon`, `L.Control.extend`, `L.DomUtil`, `L.DomEvent`, markerClusterGroup, leaflet.markercluster, `@types/leaflet`, leaflet.css, addTo(map), bindPopup, bindTooltip, onEachFeature, pointToLayer, invalidateSize, flyTo, fitBounds, latLngBounds
**Applies to:**
**Handled elsewhere:**
meeting its terms is a separate decision
not the map's concern
inside them is settled by whatever owns styling
SVG or canvas vector layer over it
---
<philosophy>
**Everything on the map is a layer.** Tiles, markers, GeoJSON, even controls — each is added and removed independently, which is why toggling a dataset is `map.removeLayer(group)` rather than a rebuild.
**The core is deliberately small** (~42KB gzipped) and covers the common map. Clustering, heatmaps, drawing and vector tiles are plugins, and a plugin is how the library expects those needs to be met.
**Methods return `this`**, so setup reads as a chain: `L.marker(pos).addTo(map).bindPopup(html)`.
**Interaction is events.** Maps, markers and layers all emit; `.on()` subscribes and `.off()` unsubscribes, and `map.off()` with no arguments is part of teardown.
</philosophy>
---
<decision_framework>
< 100 → L.marker with L.icon or L.divIcon 100 – 10K → L.markerClusterGroup 10K – 50K → L.markerClusterGroup with chunkedLoading, and L.circleMarker rather than L.marker 50K+ → canvas rendering, or pre-tiled vector data
One coordinate → L.marker (with an icon) or L.circleMarker (for data viz) A path → L.polyline An area → L.polygon, or L.circle for a radius in metres A GeoJSON dataset → L.geoJSON, which handles every geometry type A group you need to toggle → L.layerGroup, or L.featureGroup where you need getBounds()/bindPopup()
The default pin → L.marker() with no icon option
A custom image → L.icon({ iconUrl, iconSize, iconAnchor })
Several image variants → L.Icon.extend({ options }), then construct per variant
HTML or CSS content → L.divIcon({ html, className, iconSize })
A data point, many of → L.circleMarker — a vector shape, not a DOM element</decision_framework>
---
<patterns>
Target a DOM element, set the view, add a base layer with its attribution.
import L from "leaflet";
import "leaflet/dist/leaflet.css";
const map = L.map("map").setView([51.505, -0.09], 13);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);The CSS import is not optional — without it controls, popups and markers render unpositioned.
Full code: [examples/core.md](examples/core.md)
---
const marker = L.marker([51.5, -0.09]).addTo(map);
marker.bindPopup("<b>Hello</b><br>I am a popup.");
marker.bindTooltip("Hover text", { direction: "top" });The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation,…