npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

google-maps-js-api-react

v5.0.1

Published

Lightweight, tree-shakable React components and hooks for the Google Maps JavaScript API — Suspense-based loading and pooled, reusable map instances

Readme

google-maps-js-api-react

A fast, lightweight, tree-shakeable set of React components and hooks for the Google Maps JavaScript API.

  • 🧩 Declarative components for the map, markers, overlays, shapes and layers.
  • ♻️ The map instance is pooled and reused across mounts — no costly re-initialization.
  • ⏳ Libraries load on demand via Suspense.
  • 🌳 Fully tree-shakeable — you ship only what you import.

Requires React 18+. Map-rendering components return null during SSR and mount on the client.

Installation

using npm:

npm i --save google-maps-js-api-react google-maps-js-api-loader && npm i --save-dev @types/google.maps

or yarn:

yarn add google-maps-js-api-react google-maps-js-api-loader && yarn add -D @types/google.maps

or pnpm:

pnpm add google-maps-js-api-react google-maps-js-api-loader && pnpm add -D @types/google.maps

Quick start

import GoogleMap from 'google-maps-js-api-react/GoogleMap';
import AdvancedMarker from 'google-maps-js-api-react/AdvancedMarker';
import OverlayView from 'google-maps-js-api-react/OverlayView';
import { GoogleMapsLoader } from 'google-maps-js-api-loader';

// Configure the loader once, anywhere before the first render.
GoogleMapsLoader({ key: API_KEY });

const center = { lat: -31.56391, lng: 147.154312 };

const Map = () => (
  <GoogleMap
    style={{ width: '100%', height: '100vh' }}
    defaultOptions={{ mapId: 'YOUR_MAP_ID' }}
    center={center}
    zoom={6}
    onClick={() => console.log('map clicked')}
  >
    {/* a customizable pin */}
    <AdvancedMarker
      position={center}
      pin={{ background: '#34a853', glyph: 'A' }}
    />

    {/* fully custom HTML content */}
    <AdvancedMarker position={{ lat: -37.75, lng: 145.116667 }}>
      <div className='price-tag'>$300</div>
    </AdvancedMarker>

    {/* arbitrary DOM anchored to a coordinate */}
    <OverlayView
      lat={-33.87}
      lng={151.21}
      render={(ref) => <div ref={ref}>dot</div>}
    />
  </GoogleMap>
);

Core concepts

Loading & Suspense. Components throw to load the library they need, so render them under a Suspense boundary (GoogleMap has one built in via its fallback prop). Components from secondary libraries (AdvancedMarker, DrawingManager, the Street View components…) accept preventLoad to wait for an existing load instead of triggering one.

Props are uncontrolled by default. A prop sets the value but doesn't lock it — the user can still pan, zoom, drag, etc. Changing the prop later does update the instance.

// zoom starts at 5 but the user can change it freely; setting `zoom` later re-applies
<GoogleMap zoom={zoom} />

(The exception is content: OverlayView's render, AdvancedMarker's children.)

props vs defaultOptions. Each component exposes the settable options of its underlying google.maps class as individual, reactive props, plus on* event handlers (called with the instance as this). Options that can only be set at construction (and the map's pool identity keys) are passed together through defaultOptions — set once, never reactive.

Map pooling. GoogleMap creates a google.maps.Map once and reuses it across mounts. The pool is keyed by the defaultOptions identity keys (backgroundColor, controlSize, mapId, renderingType, minZoom, maxZoom, restriction) — maps with different values for those get separate instances.

Components

| Component | Description | | :------------------------------------------------------------------------------------------ | :----------------------------------------------------------- | | GoogleMap | The map. | | StreetViewPanorama | A panorama, standalone or linked to a map. | | AdvancedMarker | Modern marker (AdvancedMarkerElement) with custom content. | | OverlayView | Arbitrary DOM anchored to a coordinate. | | Marker | ⚠️ Legacy marker (deprecated by Google). | | Polygon · Polyline · Circle · Rectangle | Vector shapes. | | TrafficLayer · TransitLayer · BicyclingLayer | Built-in overlay layers. | | StreetViewCoverageLayer | Street View coverage overlay. | | FeatureLayer | Data-driven styling (needs a Map ID with DDS). | | KmlLayer | ⚠️ Renders KML/GeoRSS (deprecated by Google). | | DrawingManager | Interactive drawing tools. |

All components forward a ref to their underlying google.maps instance.

GoogleMap

google.maps.Map. Pooled and reused across mounts.

  • Reactive props: every settable MapOptions field (center, zoom, heading, tilt, mapTypeId, clickableIcons, streetView, gestureHandling, controls, …) + all map event handlers (onClick, onBoundsChanged, onZoomChanged, onIdle, onTilesLoaded, …).
  • defaultOptions (creation-only): backgroundColor, controlSize, mapId, renderingType, minZoom, maxZoom, restriction.
  • Layout: className, style, id. Loading: fallback (Suspense fallback).
<GoogleMap
  style={mapStyle}
  defaultOptions={{ mapId: 'DEMO_MAP_ID', minZoom: 3 }}
  center={center}
  zoom={6}
  gestureHandling='greedy'
  fallback={<Spinner />}
  ref={mapRef}
/>

StreetViewPanorama

google.maps.StreetViewPanorama. Two modes:

  • Standalone — renders its own viewport. Style it via className/style/id.
  • Connected — when rendered as a child of GoogleMap, it drives the map's built-in panorama (the one the pegman opens). It renders no element of its own.

To get a styled, separately-placed panorama that's still linked to a map, render a standalone one and pass it to the map's streetView prop.

  • Reactive props: position, pov, zoom, visible, pano + other StreetViewPanoramaOptions + handlers (onPositionChanged, onPovChanged, onStatusChanged, …). defaultOptions: controlSize. preventLoad.
// standalone, linked to a map (split view)
const [pano, setPano] = useState<google.maps.StreetViewPanorama | null>(null);

<GoogleMap streetView={pano} {...othersProps} />
<StreetViewPanorama ref={setPano} style={{ width: 400, height: 300 }} position={p} />

AdvancedMarker

google.maps.marker.AdvancedMarkerElement. The modern marker; requires a map with a Map ID.

  • Reactive props: position, title, zIndex, gmpClickable, gmpDraggable, collisionBehavior.
  • Content: children (any React node) or pin (PinElementOptions: background, borderColor, glyph, glyphColor, scale). children wins; omit both for the default pin.
  • Handlers: onClick (fires only when gmpClickable), onDrag, onDragStart, onDragEnd. preventLoad.
<AdvancedMarker position={p} gmpClickable onClick={() => open(p)}>
  <div className="bubble">Hi</div>
</AdvancedMarker>

<AdvancedMarker position={p} pin={{ background: '#1a73e8', glyph: '7' }} />

OverlayView

google.maps.OverlayView. Anchors arbitrary DOM to a coordinate — works on any map (no Map ID required).

| Prop | Description | Default | | :--------------------------- | :------------------------------------------------------------------------------------------------------------------------ | :--------------------- | | lat, lng | Position. | — | | render(ref) | Returns the element; attach the given ref to it. | — | | mapPaneLayer? | Which pane to render into. | 'overlayMouseTarget' | | preventMapHits? | Stop clicks bubbling to the map. | false | | preventMapHitsAndGestures? | Stop clicks, drags and wheel from reaching the map. | false |

<OverlayView lat={0} lng={0} render={(ref) => <Pin ref={ref} />} />

Marker

⚠️ Deprecated by Google — use AdvancedMarker.

google.maps.Marker. Settable MarkerOptions as props (position, icon, label, draggable, …) + handlers. defaultOptions (creation-only): anchorPoint, collisionBehavior, crossOnDrag, optimized.

Shapes

Polygon, Polyline, Circle, Rectangle — settable options of the matching google.maps class as props, plus mouse/drag handlers and the shape's on*Changed events.

| Component | Key props | Reference | | :---------- | :----------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------- | | Polygon | paths, editable, draggable, … | Polygon | | Polyline | path, editable, draggable, … | Polyline | | Circle | center, radius, editable, … (onRadiusChanged, onCenterChanged) | Circle | | Rectangle | bounds, editable, … (onBoundsChanged) | Rectangle |

Layers

Toggle layers — render them inside GoogleMap to show, unmount to hide.

| Component | Notes | | :------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TrafficLayer | autoRefresh? prop. ref | | TransitLayer | No props. ref | | BicyclingLayer | No props. ref | | StreetViewCoverageLayer | No props. preventLoad. ref | | KmlLayer ⚠️ | url + handlers (onClick, onStatusChanged, onDefaultviewportChanged). defaultOptions: preserveViewport, screenOverlays, suppressInfoWindows. Deprecated by Google — convert KML to GeoJSON and use the Data layer instead. |

FeatureLayer

Data-driven styling. Requires a vector map whose Map ID has the feature type enabled.

| Prop | Description | | :------------ | :----------------------------------------------------------------------------------------------------------------------------------- | | featureType | The FeatureType to style. | | style? | A FeatureStyleOptions (same for all) or a FeatureStyleFunction (per-feature). | | onClick? | Receives a FeatureMouseEvent. |

<FeatureLayer
  featureType={google.maps.FeatureType.LOCALITY}
  style={{ strokeColor: '#810FCB', fillColor: '#810FCB', fillOpacity: 0.2 }}
/>

DrawingManager

google.maps.drawing.DrawingManager. drawingMode + DrawingManagerOptions as props, plus the on*Complete handlers (onPolygonComplete, onMarkerComplete, …). preventLoad.

Hooks

useGoogleMap

const useGoogleMap: () => google.maps.Map;

The map instance from the nearest GoogleMap.

usePane

const usePane: (pane: keyof google.maps.MapPanes) => Element;

A specific map pane — handy for portals. Must be used inside a GoogleMap.

useGoogleMapsLoad / useGoogleMapsCompletion

// load (or await) the script / specific libraries; Suspense-based
function useGoogleMapsLoad<L extends GoogleMapsLibrary>(
  library: L
): GoogleMapsLibraries[L];
function useGoogleMapsLoad<const A extends GoogleMapsLibrary[]>(
  ...libraries: A
): { [I in keyof A]: GoogleMapsLibraries[A[I]] };

useGoogleMapsLoad triggers loading; useGoogleMapsCompletion only awaits an existing load. Both work only inside a Suspense boundary.

useGoogleMapsStatus

const useGoogleMapsStatus: (
  library?: GoogleMapsLibrary
) => 'none' | 'loading' | 'loaded' | 'error';

The load status of the script or a specific library. Does not trigger loading.

useMarkerCluster

Moved to use-marker-cluster.

License

MIT © Krombik