React Simple Maps
React Simple Maps is a component library designed to facilitate the creation of interactive SVG maps within React applications. As of version 3.0.0, released in July 2022, it provides a declarative API built on top of `d3-geo` and `topojson-client`, specifically handling common complexities like panning, zooming, and rendering optimizations. Unlike many mapping solutions, it does not bundle map data; users are required to provide their own GeoJSON or TopoJSON files. This approach makes the library lean and flexible, allowing seamless integration with other React ecosystem tools such as `react-spring` or `react-annotation`. While its average release cycle was historically around 145 days, v3.0.0 has been the latest stable release for some time, suggesting a slower development cadence or maintenance mode. Its core differentiator lies in its minimalist design, offering building blocks for custom map charts without unnecessary bloat, focusing on the core task of rendering and interacting with geographic data.
Common errors
-
SyntaxError: Cannot use import statement outside a module
cause Attempting to use ES module `import` syntax in a CommonJS (CJS) environment, or a build process that doesn't correctly transpile ESM to CJS. The library primarily uses ESM.fixEnsure your project is configured for ES Modules (e.g., `"type": "module"` in `package.json` for Node.js, or using a bundler like Webpack/Rollup/Vite that handles ESM correctly). For older environments, a transpilation step is necessary. -
The map is very small or not appearing at all.
cause Incorrect `projectionConfig` properties, especially `scale` and `center`, or issues with the loaded GeoJSON/TopoJSON data.fixAdjust `projectionConfig={{ scale: N, center: [lat, lon] }}` on `ComposableMap`. Start with a low scale to locate the map, then increase. Verify your `geoUrl` is correct and the map file is valid. -
Error: Objects are not valid as a React child (found: object with keys {type, properties, geometry, rsmKey}). If you meant to render a collection of children, use an array instead.cause Attempting to render the raw `geo` object directly within JSX instead of wrapping it in the `Geography` component or providing a valid React element.fixEnsure that within the `Geographies` component's render prop, each `geo` object is passed to a `Geography` component, like so: `<Geography key={geo.rsmKey} geography={geo} />`. -
Uncaught (in promise) TypeError: Failed to fetch
cause The `geoUrl` for the TopoJSON/GeoJSON file is incorrect, inaccessible, or there's a network issue (e.g., CORS).fixDouble-check the `geoUrl` for typos. Verify the URL is publicly accessible. If fetching from a different domain, ensure the server provides appropriate CORS headers. For local development, ensure the file path is correct relative to your public assets.
Warnings
- breaking The official `react-simple-maps` package, as of its current version 3.0.0, is not fully compatible with React 19 due to unaddressed dependency issues. Users targeting React 19 should be aware that they might need to use a community-maintained fork or pin older React versions.
- gotcha Map components might appear extremely small or not at all if the `projectionConfig.scale` property within `ComposableMap` is too low, or if the `center` property positions the map off-screen.
- gotcha Performance can significantly degrade when using very large or highly detailed TopoJSON/GeoJSON files, especially when combined with many markers or complex styling.
- gotcha The library does not include any map data. Users must provide valid GeoJSON or TopoJSON files themselves, typically by fetching them from an external URL or including them locally.
- gotcha Older versions of `d3-color` (a transitive dependency) had known security vulnerabilities (CWE-400). While `react-simple-maps` itself is a wrapper, ensuring up-to-date dependencies is crucial.
Install
-
npm install react-simple-maps -
yarn add react-simple-maps -
pnpm add react-simple-maps
Imports
- ComposableMap
const ComposableMap = require('react-simple-maps').ComposableMap;import { ComposableMap } from 'react-simple-maps'; - Geographies
import Geographies from 'react-simple-maps/lib/Geographies';
import { Geographies } from 'react-simple-maps'; - Geography
import { default as Geography } from 'react-simple-maps/Geography';import { Geography } from 'react-simple-maps'; - Marker
const { Marker } = require('react-simple-maps');import { Marker } from 'react-simple-maps'; - ZoomableGroup
import * as ZoomableGroup from 'react-simple-maps/ZoomableGroup';
import { ZoomableGroup } from 'react-simple-maps';
Quickstart
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ComposableMap, Geographies, Geography, Marker } from 'react-simple-maps';
const geoUrl = 'https://raw.githubusercontent.com/deldersveld/topojson/master/world-countries.json';
const markers = [
{ markerOffset: -15, name: 'Buenos Aires', coordinates: [-58.3816, -34.6037] },
{ markerOffset: -15, name: 'La Paz', coordinates: [-68.1193, -16.4897] },
{ markerOffset: 25, name: 'Brasília', coordinates: [-47.8825, -15.7942] },
{ markerOffset: 25, name: 'Santiago', coordinates: [-70.6693, -33.4489] },
{ markerOffset: -15, name: 'Bogotá', coordinates: [-74.0721, 4.7110] },
{ markerOffset: 25, name: 'Quito', coordinates: [-78.4678, -0.1807] }
];
const MapChart = () => {
return (
<ComposableMap
projection="geoEqualEarth"
projectionConfig={{
scale: 160
}}
style={{
width: '100%',
height: 'auto'
}}
>
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map((geo) => (
<Geography
key={geo.rsmKey}
geography={geo}
fill="#D6D6DA"
stroke="#FFFFFF"
strokeWidth={0.5}
/>
))
}
</Geographies>
{markers.map(({ name, coordinates, markerOffset }) => (
<Marker key={name} coordinates={coordinates}>
<circle r={8} fill="#F00" stroke="#fff" strokeWidth={2} />
<text
textAnchor="middle"
y={markerOffset}
style={{ fontFamily: 'system-ui', fill: '#5D5A6D', fontSize: '10px' }}
>
{name}
</text>
</Marker>
))}
</ComposableMap>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<MapChart />);