Google Maps Platform Awards 2025 Winner - A flexible, accessible, and secure vanilla JavaScript library that brings the power of Google's address search to your application in minutes.
npm install places-autocomplete-js


A flexible and customisable vanilla JavaScript library for frontend web applications, leveraging the Google Maps Places (New) Autocomplete API. Winner of the Google Maps Platform Awards 2025, recognising excellence in Google Maps Platform development. This library provides a user-friendly way to search for and retrieve detailed address and location information in any web application.
It handles API loading, session tokens for cost-effective usage, fetching suggestions with debouncing, keyboard navigation, highlighting matched text, and requesting place details, allowing you to focus on integrating the results into your application.
Explore interactive examples of the Google Places Autocomplete JS library:
A quick, editable sandbox to experiment with the core functionality:
See a more comprehensive live demo of the library in action: pacservice.uk

- Seamless Google Places Integration: Directly connects with the modern Google Places (New) Autocomplete API for accurate and up-to-date address suggestions.
- Cost-Effective API Usage: Automatically handles session tokens to optimise your Google Maps API costs per Google's guidelines.
- Optimised User Experience: Implements Debounced Input to limit API calls while the user is typing, ensuring a smooth and responsive search experience.
- Enhanced Readability: Provides Suggestion Highlighting to automatically bold the portion of text matching the user's input, making suggestions easier to scan.
- Visual Categorisation: Includes Place Type Icons (🏪 Shopping, 🍽️ Dining, 🏨 Lodging, etc.) to help users quickly identify the type of place in suggestions.
- Flexible Styling: Offers Customisable Styling allowing you to easily override default styles or apply your own using CSS classes. Built with sensible defaults.
- Robust Event Handling: Provides onResponse and onError callbacks for comprehensive control over successful place selections and error scenarios.
- Imperative API: Programmatically control the component with methods like clear(), focus(), setInputValue(), getRequestParams(), and more.
- Highly Configurable: Allows you to control API parameters (requestParams) and component behavior/appearance (options) to fit your specific application needs.
- Efficient API Loading: Dynamically loads the Google Maps API script on demand, reducing initial page load times.
- Accelerate Development: Quickly integrate powerful address autocomplete functionality into your web application with minimal setup.
- Improve User Experience: Provide a fast, intuitive, and accurate address entry experience for your users.
- Reduce API Costs: Leverage automatic session token management to optimise your Google Maps API billing.
- Maintain Brand Consistency: Easily customise the look and feel of the autocomplete component to match your application's design system.
- Future-Proof: Built on the latest Google Places (New) Autocomplete API, ensuring compatibility and access to new features.
This library has been recognised as a winner of the Google Maps Platform Awards 2025 by the Google Developer Program. This award celebrates outstanding projects that demonstrate exceptional use of Google Maps Platform APIs, innovation, and contribution to the developer community.
Learn more about the Google Maps Platform Awards
- Google Maps API Key with the Places API (New) enabled. Refer to Use API Keys for detailed instructions.
- Geocoding API enabled if you plan to use setInputValue(latitude, longitude).
This library can be used in two primary ways: by installing it as an npm package for use with a bundler (like Vite or Webpack), or by linking to it directly from a CDN in a static HTML file.
This is the recommended approach for modern web applications.
Step 1: Install the package
``bash`
npm install places-autocomplete-jsor
yarn add places-autocomplete-js
Step 2: Import and initialise the component
In your main JavaScript or TypeScript file, import both the library and its stylesheet.
`javascript
import { PlacesAutocomplete } from 'places-autocomplete-js';
import 'places-autocomplete-js/places-autocomplete.css'; // Import the default stylesheet
document.addEventListener('DOMContentLoaded', () => {
try {
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_GOOGLE_MAPS_API_KEY', // Replace with your key
onResponse: (placeDetails) => {
console.log('Place Selected:', placeDetails);
// Your code to handle the selected place...
},
onError: (error) => {
console.error('Autocomplete Error:', error.message || error);
}
});
} catch (error) {
console.error("Failed to initialise PlacesAutocomplete:", error.message);
}
});
`
Then, add the container element to your HTML:
`html`
For quick prototyping or use in projects without a build step, you can use a CDN like jsDelivr.
Step 1: Add the stylesheet and script to your HTML
Add the following lines to your HTML file. The stylesheet goes in the
and the script goes at the end of the .`html
Places Autocomplete Demo
`
> Note for Production: For stability, it's recommended to pin the CDN links to a specific version instead of using @latest. For example: .../places-autocomplete-js@1.1.8/...$3
The
PlacesAutocomplete class is initialised with a configuration object.| Parameter | Type | Required | Description |
| ---------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
containerId | string | Yes | The ID of the HTML element where the autocomplete widget will be rendered. |
| googleMapsApiKey | string | Yes | Your Google Maps API Key with the Places API (New) enabled. |
| googleMapsApiVersion | string | No | The version of the Google Maps API to load (e.g., "weekly", "quarterly", "beta"). Defaults to "weekly". |
| onResponse | function | No | Callback for selected place details. Receives JSON by default (options.response_type: 'json') or a Google Place instance when options.response_type: 'place'. |
| onError | function | No | Callback function triggered when an error occurs. Receives an Error object or string. Default logs to console. |
| options | object | No | Object to customise UI behavior and appearance. See "UI & Behavior Options" below. |
| requestParams | object | No | Object to customise the parameters sent to the Google Places Autocomplete API. See "API Request Parameters" below. |
| fetchFields | array | No | Array of Place Data Fields to request when a place is selected. Affects API cost. Default ['formattedAddress', 'addressComponents'] |$3
Passed within the main configuration object under the
options key.| Option | Type | Default | Description |
| ---------------- | ----------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
placeholder | string | "Start typing your address ..." | Placeholder text for the input field. |
| debounce | number | 100 | Delay in milliseconds before triggering an API request after user stops typing. Set to 0 to disable. |
| distance | boolean | false | Whether to attempt to show distance in suggestions (requires origin in requestParams). |
| distance_units | 'km' \| 'miles' | 'km' | Units to display distance in if distance is true. |
| label | string | "" | Optional label text displayed above the input field. |
| autofocus | boolean | false | If true, automatically focuses the input field on initialisation. |
| autocomplete | string | 'off' | Standard HTML autocomplete attribute for the input field. |
| classes | object | _(See default classes below)_ | Object to override default CSS classes for styling. See "Styling" section. |
| clear_input | boolean | false | If true, clears the input field after a suggestion is selected. If false (default), the input field retains the formattedAddress of the selected place. |
| response_type | 'json' \| 'place' | 'json' | Return format: 'json' for plain JSON object (default), 'place' for full Google Maps Place instance with method access. |
| show_place_type | boolean | false | Whether to display icons representing the place type (🏪, 🍽️, etc.). Mutually exclusive with distance. |$3
The component is built with flexibility in mind and can be styled in two ways. The default appearance is based on Tailwind CSS, but you are not required to use Tailwind in your project.
#### 1. Using the Pre-built CSS File (Recommended)
A standalone CSS file is included in the package and contains all necessary styles for the component to work correctly out-of-the-box.
For bundler-based projects:
`javascript
import 'places-autocomplete-js/style.css';
`For CDN usage:
`html
`#### 2. Custom CSS Classes (
options.classes)You can customise the appearance by providing your own CSS classes via the
options.classes object. This allows you to override default styles or integrate with your own design system.Available Class Keys:
| Class Key | Default CSS Class | Description |
|-----------|-------------------|-------------|
|
section | pac-section | Main container section |
| container | pac-container | Div containing the input and suggestions list |
| label | N/A | Label element (if options.label is provided) |
| input | pac-input | Main text input element |
| icon_container | pac-icon-container | Container for the search icon |
| icon | N/A | SVG string for the search icon |
| ul | pac-ul | Suggestions list ( element) |
| li | pac-li | Individual suggestion item |
| li_current | pac-li-current | Class for the currently highlighted suggestion |
| li_button | pac-li-button | Button element within each suggestion |
| li_button_current | pac-li-button-current | Class for the button in the highlighted suggestion |
| li_div_container | pac-li-div-container | Container div within the button |
| li_div_one | pac-li-div-one | First inner div (contains place name and icon) |
| li_div_one_p | pac-li-div-one-p | Paragraph containing the main suggestion text |
| li_div_two | pac-li-div-two | Second inner div (contains distance) |
| li_div_two_p | pac-li-div-two-p | Paragraph containing the distance text |
| kbd_container | pac-kbd-container | Container for keyboard hint keys |
| kbd_escape | pac-kbd-escape | Escape key hint |
| kbd_up | pac-kbd-up | Up arrow key hint |
| kbd_down | pac-kbd-down | Down arrow key hint |
| kbd_active | pac-kbd-active | Class applied when a keyboard key is pressed |
| li_div_two_p_place_type | pac-li-div-two-p-place_type | Container for place type display |
| li_div_two_p_place_type_icon | pac-li-div-two-p-place_type-icon | The place type icon element |
| li_div_two_p_place_type_label | pac-li-div-two-p-place_type-label | The place type label text |
| highlight | pac-highlight | Class for matched text highlighting |Example:
`javascript
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
options: {
classes: {
input: 'my-custom-input',
ul: 'my-dropdown',
li_current: 'active',
highlight: 'text-highlight',
},
},
});
`Then define these classes in your stylesheet:
`css
.my-custom-input {
padding: 0.75rem;
border: 1px solid #d1d5db;
border-radius: 0.375rem;
}.my-dropdown {
max-height: 20rem;
overflow-y: auto;
}
.active {
background-color: #4f46e5;
color: white;
}
.text-highlight {
font-weight: 600;
color: #4f46e5;
}
`$3
Passed within the main configuration object under the
requestParams key. These parameters are sent to the Google Places Autocomplete API. Refer to the AutocompleteRequest documentation for all available options.Common Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
|
input | string | Automatically handled by the library (user's typed value) |
| language | string | Language code for returned results (e.g., "en", "fr", "de") |
| region | string | Region code as ccTLD two-character value (e.g., "GB", "US") |
| includedRegionCodes | string[] | Array of up to 5 CLDR region codes to restrict results |
| locationBias | google.maps.places.LocationBias | Area to bias results towards |
| locationRestriction | google.maps.places.LocationRestriction | Area to strictly restrict results to |
| origin | google.maps.LatLngLiteral | Origin point for distance calculations (requires options.distance: true) |
| sessionToken | AutocompleteSessionToken | Automatically managed by the library |Example:
`javascript
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
requestParams: {
language: 'en-GB',
region: 'GB',
includedRegionCodes: ['GB'],
origin: { lat: 51.5074, lng: -0.1278 }, // London
},
});
`$3
The
fetchFields option specifies which place data fields to retrieve when a user selects a suggestion. This helps optimise API costs by only fetching necessary information.Default fields:
['formattedAddress', 'addressComponents']See Place Class Data Fields for all available fields and their billing impact.
Example:
`javascript
// In constructor
const autocomplete = new PlacesAutocomplete({
containerId: 'autocomplete-container',
googleMapsApiKey: 'YOUR_API_KEY',
fetchFields: ['formattedAddress', 'addressComponents', 'displayName', 'types'],
});// Or update dynamically
autocomplete.setFetchFields(['formattedAddress', 'location', 'viewport']);
``Public Methods
The
PlacesAutocomplete instance provides the following methods for dynamic control:$3
Clears the input field, removes visible suggestions, and refreshes the session token.
`javascript
autocomplete.clear();
`$3
Removes event listeners and cleans up DOM elements. Use this when the component is no longer needed (e.g., when unmounting a view in SPAs).
`javascript
autocomplete.destroy();
`$3
Sets focus on the autocomplete text input field.
`javascript
autocomplete.focus();
`$3
Sets the input by finding and selecting a place for the given coordinates. Performs reverse geocoding to convert lat/lng to a place, then triggers
onResponse using the configured options.response_type. Requires Geocoding API to be enabled.`javascript
// Set location to Eiffel Tower
await autocomplete.setInputValue(48.8584, 2.2945);
`$3
Dynamically updates the Place Data Fields to fetch on selection. The provided fields are merged with the library's default fields (
formattedAddress, addressComponents).Parameters:
-
fields (Array): Field names to fetch`javascript
autocomplete.setFetchFields(['displayName', 'types', 'location']);
`$3
Retrieves the current array of Place Data Fields that will be requested.
Returns:
Array`javascript
const fields = autocomplete.getFetchFields();
console.log('Current fields:', fields);
// Output: ['formattedAddress', 'addressComponents', 'displayName', 'types', 'location']
`$3
Dynamically updates the Google Places API request parameters. Useful for changing search criteria after initialisation.
Parameters:
-
params (object): Request parameters to update (merged with existing parameters)`javascript
// Change region and language
autocomplete.setRequestParams({
region: 'FR',
language: 'fr',
includedRegionCodes: ['FR'],
});// Set origin for distance calculations
autocomplete.setRequestParams({
origin: { lat: 48.8566, lng: 2.3522 }, // Paris
});
`$3
Retrieves the current API request parameters.
Returns:
object`javascript
const params = autocomplete.getRequestParams();
console.log('Current request params:', params);
`$3
Dynamically updates UI behaviour and appearance options.
Parameters:
-
options (object): Options to update (merged with existing options)`javascript
// Update placeholder and debounce
autocomplete.setOptions({
placeholder: 'Enter your postcode...',
debounce: 250,
});// Update CSS classes
autocomplete.setOptions({
classes: {
input: 'custom-input',
ul: 'custom-dropdown',
},
});
`$3
Retrieves the current UI and behaviour options.
Returns:
object`javascript
const options = autocomplete.getOptions();
console.log('Current options:', options);
`Google Places API & Billing
This library uses the Google Maps JavaScript API (Places library). Usage is subject to Google's terms and pricing.
$3
- An API key with "Places API" and "Maps JavaScript API" enabled
- Active Google Cloud billing account
$3
The library automatically implements several cost-saving measures:
1. Session Tokens: Autocomplete requests are grouped using session tokens, significantly reducing costs compared to per-request billing. See Session Token Pricing.
2. Minimal Default Fields: By default, only
formattedAddress and addressComponents are fetched, minimising costs. Additional fields can be requested via fetchFields, but be mindful of Place Data Fields Pricing.3. Debounced Requests: Input is debounced by default (100ms) to reduce unnecessary API calls while typing.
Testing
This project includes both unit tests (using Vitest) and end-to-end tests (using Playwright).
$3
Unit tests are located in the
tests/ directory and are run using Vitest. To execute the unit tests, use the following command:`bash
npm run test:vitest
`$3
End-to-end tests are located in the
e2e/ directory and are run using Playwright. The Playwright config starts the Vite dev server automatically via webServer, so you can run:`bash
npm run test:e2e
``Contributions are welcome! Please feel free to open an issue or submit a pull request.