This library is not production-ready yet. Developers should use it with caution and expect breaking changes.

Installation

How to install and set up Terrae in your project.

Prerequisites

A project with Tailwind CSS and shadcn/ui already configured.

Using Mapbox GL

To use Mapbox GL JS, you need an access token. Get one from Mapbox Account. Create a new token with default public scopes.

Add it to your .env.local file:

NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=your_mapbox_token_here

Using MapLibre GL

To use MapLibre GL JS instead of Mapbox, install the MapLibre variant of the base map component:

npx shadcn@latest add https://www.terrae.dev/maplibre.json

This installs the same core map files but with map-library.ts pre-configured for MapLibre GL, including the correct imports and default styles.

If you already installed the Mapbox variant and want to switch manually, first install the MapLibre package:

npm install maplibre-gl
npm install -D @types/mapbox-gl

Then update map-library.ts with these 3 lines:

// map-library.ts — change these 3 lines:
import mapboxgl from "maplibre-gl"
import "maplibre-gl/dist/maplibre-gl.css"
const detectedLibrary: MapLibraryName = "maplibre"
Note: No access token is needed when using MapLibre GL. Some features like the Rain Effect and Standard styles are Mapbox-only and will not work with MapLibre.

Add Components

Start with the base map component:

npx shadcn@latest add https://www.terrae.dev/map.json

Then add the specific components you need. For example, to add markers:

npx shadcn@latest add https://www.terrae.dev/marker.json

Visit the components page to see all available components and their installation commands.

Tip: Dependencies are automatically resolved! Just install the components you need.
Heads up: A simpler command is coming soon! Once this pull request is approved, you'll be able to install components with: npx shadcn@latest add terrae/map

Usage

Import and use the map component in your application:

import { Map, MapMarker, MarkerContent } from "@/registry/map";
import { Card } from "@/components/ui/card";

export function MyMap() {
  return (
    <Card className="h-[500px] p-0 overflow-hidden">
      <Map
        accessToken={process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN!}
        center={[-74.006, 40.7128]}
        zoom={11}
      >
        <MapMarker coordinates={[-74.006, 40.7128]}>
          <MarkerContent>
            <div className="bg-white/90 backdrop-blur-sm px-3 py-1.5 rounded-md">
              <span className="bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent font-semibold">
                New York
              </span>
            </div>
          </MarkerContent>
        </MapMarker>
      </Map>
    </Card>
  );
}