Skip to content

A framework-agnostic Google Maps toolkit with core utilities and framework wrappers (React, Vue, Angular).

License

Notifications You must be signed in to change notification settings

lineCode/gmaps-kit

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

gmaps-kit

An open-source toolkit around the Google Maps JavaScript SDK that simplifies usage for frontend teams by providing framework-agnostic utilities and optional framework-specific wrappers.

πŸš€ Live Demo

Try it out: https://demo-app-rouge-five.vercel.app/

The demo showcases all features including maps, geocoding, directions, and places functionality.

πŸš€ Features

  • Framework-agnostic core - Plain TypeScript functions & utilities
  • Script loader - Easy Google Maps SDK loading
  • Map initialization - Simple map creation with typed options
  • Markers & InfoWindows - Easy marker management
  • Places Autocomplete - Places API integration
  • Places API (New) - Enhanced Places API with better CORS support
  • Geocoding - Address ↔ coordinates conversion
  • Directions - Route planning and navigation
  • Distance Matrix - Calculate distances between multiple points
  • Street View - Create and manage Street View panoramas
  • Web services - Typed REST clients for Places & Geocoding APIs
  • Event handling - Map, marker, and Street View event utilities

πŸ“¦ Packages

  • @gmaps-kit/core - Framework-agnostic core utilities
  • @gmaps-kit/react - React hooks and components
  • @gmaps-kit/vue - Vue wrapper (coming soon)
  • @gmaps-kit/angular - Angular wrapper (coming soon)

πŸ› οΈ Installation

npm install @gmaps-kit/core

🎯 Quick Start

1. Load Google Maps SDK

import { loadGoogleMaps } from '@gmaps-kit/core';

// Load Google Maps with your API key
await loadGoogleMaps({
  apiKey: 'YOUR_API_KEY',
  libraries: ['places', 'geometry'],
});

2. Create a Map

import { createMap } from '@gmaps-kit/core';

const mapInstance = createMap('map-container', {
  center: { lat: 40.7128, lng: -74.006 },
  zoom: 10,
});

3. Add Markers

import { addMarker, createInfoWindow, openInfoWindow } from '@gmaps-kit/core';

// Add a marker
const marker = addMarker(mapInstance.map, {
  position: { lat: 40.7128, lng: -74.006 },
  title: 'New York City',
});

// Create and open an InfoWindow
const infoWindow = createInfoWindow({
  content: '<h3>New York City</h3><p>The Big Apple!</p>',
});

openInfoWindow(infoWindow, marker, mapInstance.map);

4. Places Autocomplete

import { bindAutocompleteToMap } from '@gmaps-kit/core';

const input = document.getElementById('search-input') as HTMLInputElement;

const autocomplete = bindAutocompleteToMap(mapInstance, {
  input,
  types: ['establishment'],
});

5. Geocoding

import { geocodeAsync, reverseGeocodeAsync } from '@gmaps-kit/core';

// Address to coordinates
const results = await geocodeAsync(
  '1600 Amphitheatre Parkway, Mountain View, CA'
);
console.log(results[0].location); // { lat: 37.4220656, lng: -122.0840897 }

// Coordinates to address
const address = await reverseGeocodeAsync({
  lat: 37.4220656,
  lng: -122.0840897,
});
console.log(address[0].address); // "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"

6. Directions

import { getDirectionsAsync, renderDirections } from '@gmaps-kit/core';

// Get directions
const directions = await getDirectionsAsync({
  origin: 'New York, NY',
  destination: 'Los Angeles, CA',
  travelMode: 'DRIVING',
});

// Render on map
const directionsRenderer = renderDirections(mapInstance.map, directions);

7. Places API (New) - Enhanced Features

import { PlacesNewClient } from '@gmaps-kit/core';

// Initialize the new Places API client
const placesNewClient = new PlacesNewClient({
  apiKey: 'YOUR_API_KEY',
  // No baseUrl needed - direct API calls with better CORS support!
});

// Text search with enhanced data
const textResults = await placesNewClient.textSearch({
  textQuery: 'restaurants in New York',
  locationBias: {
    circle: {
      center: { latitude: 40.7128, longitude: -74.006 },
      radius: 1000,
    },
  },
  maxResultCount: 10,
  minRating: 4.0,
});

// Nearby search with better filtering
const nearbyResults = await placesNewClient.nearbySearch({
  includedTypes: ['restaurant', 'cafe'],
  locationRestriction: {
    circle: {
      center: { latitude: 40.7128, longitude: -74.006 },
      radius: 1000,
    },
  },
  maxResultCount: 10,
  minRating: 4.0,
});

// Get detailed place information
const placeDetails = await placesNewClient.placeDetails({
  placeId: 'ChIJN1t_tDeuEmsRUsoyG83frY4',
});

// Place autocomplete
const autocompleteResults = await placesNewClient.autocomplete({
  input: 'restaurants in',
  locationBias: {
    circle: {
      center: { latitude: 40.7128, longitude: -74.006 },
      radius: 1000,
    },
  },
});

// Build photo URL
const photoUrl = placesNewClient.buildPhotoUrl('photos/123', {
  maxWidthPx: 400,
  maxHeightPx: 300,
});

Key Advantages of Places API (New)

Feature Legacy API New API (New)
CORS Support ❌ Requires proxy βœ… Direct browser requests
Request Format Query parameters JSON body
Authentication API key in URL API key in header
Data Quality Basic Enhanced with more fields
Error Handling Limited Comprehensive
Rate Limiting Basic Advanced

7. Street View

import { createStreetViewPanorama } from '@gmaps-kit/core';

const streetView = createStreetViewPanorama('street-view-container', {
  position: { lat: 40.6892, lng: -74.0445 },
  pov: { heading: 90, pitch: 0 },
  zoom: 1,
});

streetView.panorama.addListener('pov_changed', () => {
  console.log(streetView.panorama.getPov());
});

8. REST Web Services

import { PlacesClient, GeocodingClient } from '@gmaps-kit/core';

const places = new PlacesClient({ apiKey: 'YOUR_API_KEY' });
const geocode = new GeocodingClient({ apiKey: 'YOUR_API_KEY' });

const coffeeShops = await places.textSearch({ query: 'coffee in Seattle' });
const geocodeResult = await geocode.geocode({
  address: '221B Baker Street, London',
});

πŸ“š API Reference

Script Loader

// Load Google Maps SDK
await loadGoogleMaps({
  apiKey: string;
  libraries?: string[];
  language?: string;
  region?: string;
  version?: string;
  callback?: string;
});

// Check if Google Maps is loaded
const isLoaded = isGoogleMapsLoaded();

// Wait for Google Maps to load
await waitForGoogleMaps(timeout?: number);

Map Utilities

// Create a map
const mapInstance = createMap(container, options, eventHandlers?);

// Map controls
getMapCenter(map);
setMapCenter(map, center);
getMapZoom(map);
setMapZoom(map, zoom);
panTo(map, center, zoom?);
fitMapToMarkers(map, markers, padding?);

Street View Utilities

const streetView = createStreetViewPanorama(container, options, handlers?);
setStreetViewPosition(streetView.panorama, position);
setStreetViewPov(streetView.panorama, pov);
setStreetViewVisibility(streetView.panorama, visible);
isStreetViewVisible(streetView.panorama);

Marker Utilities

// Add marker
const marker = addMarker(map, {
  position: { lat: number, lng: number };
  title?: string;
  label?: string;
  icon?: string | Icon | Symbol;
  animation?: Animation;
  draggable?: boolean;
  clickable?: boolean;
  zIndex?: number;
});

// InfoWindow
const infoWindow = createInfoWindow({
  content: string;
  position?: LatLngLiteral;
  maxWidth?: number;
  pixelOffset?: Size;
  disableAutoPan?: boolean;
});

openInfoWindow(infoWindow, marker, map);
closeInfoWindow(infoWindow);

Autocomplete

// Create autocomplete
const autocomplete = createAutocomplete({
  input: HTMLInputElement;
  bounds?: LatLngBounds;
  componentRestrictions?: ComponentRestrictions;
  fields?: string[];
  strictBounds?: boolean;
  types?: string[];
});

// Bind to map
const autocomplete = bindAutocompleteToMap(mapInstance, options);

Geocoding

// Geocode address
const results = await geocodeAsync(address);
const firstResult = await geocodeFirst(address);

// Reverse geocode coordinates
const results = await reverseGeocodeAsync(location);
const firstResult = await reverseGeocodeFirst(location);

Places Web Service Client

const places = new PlacesClient({
  apiKey: 'YOUR_API_KEY',
  retryConfig: { retries: 2, delayMs: 500 },
});

const restaurants = await places.textSearch({
  query: 'restaurants near Portland',
  type: 'restaurant',
});

if (restaurants.next_page_token) {
  const more = await places.textSearchNextPage(restaurants.next_page_token);
}

Geocoding Web Service Client

const geocodeClient = new GeocodingClient({ apiKey: 'YOUR_API_KEY' });

const forward = await geocodeClient.geocode({
  address: '10 Downing Street, London',
  components: { country: 'UK' },
});

const reverse = await geocodeClient.reverseGeocode({
  latlng: { lat: 51.5034, lng: -0.1276 },
  resultType: ['street_address'],
});

Tip: Use the web service clients when you need typed access to Google Maps REST endpoints (for example SSR, background jobs, or prefetching data). For interactive map experiences, continue to use the on-map utilities that operate directly on the JavaScript SDK.

Directions

// Get directions
const directions = await getDirectionsAsync({
  origin: string | LatLngLiteral;
  destination: string | LatLngLiteral;
  travelMode?: TravelMode;
  waypoints?: DirectionsWaypoint[];
  optimizeWaypoints?: boolean;
  avoidHighways?: boolean;
  avoidTolls?: boolean;
});

// Render directions
const renderer = renderDirections(map, directions);
clearDirections(renderer);

πŸ§ͺ Testing

npm test

πŸ—οΈ Development

# Install dependencies
npm install

# Build packages
npm run build

# Run tests
npm run test

# Lint code
npm run lint

# Format code
npm run format

πŸ“„ License

MIT License - see LICENSE file for details.

🀝 Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

πŸ“ž Support

For questions and support, please open an issue on our GitHub repository.


βš›οΈ React Package

The React package provides 20 specialized hooks and components for Google Maps integration:

Installation

npm install @gmaps-kit/react @gmaps-kit/core

Quick Start

import { useGoogleMaps, useMap, Map } from '@gmaps-kit/react';

function App() {
  const { isLoaded } = useGoogleMaps({
    apiKey: 'YOUR_API_KEY',
    libraries: ['places'],
  });

  const { map } = useMap({
    center: { lat: 40.7128, lng: -74.006 },
    zoom: 12,
  });

  if (!isLoaded) return <div>Loading...</div>;

  return <Map mapInstance={map} />;
}

Available Hooks (20 Total)

Core Hooks:

  • useGoogleMaps - Load Google Maps SDK
  • useMap - Map management
  • useMarkers - Marker management
  • useMapEvents - Map event handling

Geocoding Hooks:

  • useGeocoding - Client-side geocoding
  • useGeocodingService - Server-side geocoding

Places Hooks:

  • usePlaces - Legacy Places API
  • usePlacesNew - New Places API (New) πŸš€

Directions & Routing:

  • useDirections - Route calculations
  • useBicycling - Bicycling layer
  • useTraffic - Traffic layer
  • useTransit - Transit layer

Advanced Features:

  • useClustering - Marker clustering
  • useDistanceMatrix - Distance calculations
  • useElevation - Elevation data
  • useGeometry - Geometric calculations
  • useHeatmap - Heatmap visualization
  • useInfoWindows - InfoWindow management
  • useMaxZoom - Zoom management
  • useStreetView - Street View functionality

Components

  • Map - Google Maps component
  • Marker - Marker component
  • InfoWindow - InfoWindow component

Note: Vue and Angular wrappers will be added in future phases.

About

A framework-agnostic Google Maps toolkit with core utilities and framework wrappers (React, Vue, Angular).

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 97.8%
  • CSS 1.1%
  • Other 1.1%