docs

Location

+
UniversalWorks with Expo & React Native CLI

This tool works with both Expo and React Native CLI projects. Just install and go.

Anything in your app that depends on where the phone is gets hard to test from a desk. Location tells your app it is somewhere else. Pin it to a store, drive it across town, walk it past a geofence, or turn the GPS off, and watch what your screens do. The phone's real location doesn't change.

Location is part of Buoy Pro.

Install

npm install @buoy-gg/location

Location shows up in your FloatingDevTools menu on its own. If your app asks for the location or starts a geofence while it starts up, import it first in your entry file:

js
// index.js
import "@buoy-gg/location";
import "expo-router/entry";
// index.js
import "@buoy-gg/location";
import "expo-router/entry";

It works with the location library your app already uses:

  • expo-location, including watchPositionAsync, heading, background location updates and geofencing (through expo-task-manager)
  • @react-native-community/geolocation
  • react-native-geolocation-service

You don't change your app's code.

How to use it

The top card always says where your app is: the place or route, whether it's moving, and the app's location permission. The small map under it shows your places, your geofences, the route and the simulated position.

  • Location. Tap one of your places to pin the app there. Other Location has a field for coordinates like 37.3349, -122.0090 or a Google or Apple Maps link, and a list of places around the world.
  • Movement. Pick a route: your own, or Walk, Run, City Drive, Highway, Tunnel or Block Loop, which start where the app is now. Each update carries the heading and speed of the road. Change the speed while it plays, pause it, or choose Stop Here to stay where it got to.
  • Conditions. Good gives precise fixes. Weak gives fixes that are about 65 m off and wander, like indoors. No Signal stops updates and makes requests for the position fail. Off tells your app location services are off for the whole phone. Accuracy & Drift sets exact numbers.
  • Tap Use Real Location to stop.

A small strip stays on screen while the location is changed, so you don't forget. The changed location stays after a reload. Activity lists what your app asked for and what its tasks did.

Your own places and routes

Add the places your app cares about, like your stores, and routes that pass by them:

js
import { registerLocationPlaces, registerLocationRoutes } from "@buoy-gg/location";

registerLocationPlaces([
  { label: "Downtown store", latitude: 40.7608, longitude: -111.891 },
]);

registerLocationRoutes([
  {
    id: "walk-past-downtown",
    name: "Walk past Downtown",
    points: [
      { latitude: 40.7608, longitude: -111.8960 },
      { latitude: 40.7608, longitude: -111.8860 },
    ],
    speed: 1.4, // meters per second
  },
]);
import { registerLocationPlaces, registerLocationRoutes } from "@buoy-gg/location";

registerLocationPlaces([
  { label: "Downtown store", latitude: 40.7608, longitude: -111.891 },
]);

registerLocationRoutes([
  {
    id: "walk-past-downtown",
    name: "Walk past Downtown",
    points: [
      { latitude: 40.7608, longitude: -111.8960 },
      { latitude: 40.7608, longitude: -111.8860 },
    ],
    speed: 1.4, // meters per second
  },
]);

Geofences

When your app starts geofencing with Location.startGeofencingAsync, the tool lists every region with how far away it is, or Inside. A region at one of your places takes that place's name. Tap a region to cross its edge, or tap its circle on the map. Your task from TaskManager.defineTask runs with the same data it gets from the phone, and the row shows when it ran. A route that passes through a region enters it and then leaves it.

While Location is on, your geofences and background updates run in the tool, not on the phone. When you go back to the real location, they start on the phone again with the options your app gave them.

Permission

Location doesn't change the location permission. If your app hasn't been allowed to use the location, its requests still fail, the same as on a real phone. To test "never asked", "denied", "blocked" or "approximate location only", use the Permissions tool. With approximate location, Location reports positions the way the phone does: rounded to a few kilometers.

What stays real

Location changes what your app's JavaScript gets from its location library. Some things read the location in native code and keep the real one:

  • The blue dot on a native map (react-native-maps, expo-maps, Mapbox). Draw your own marker from the location your app gets, or move the simulator itself: in the MCP server, sim_location sets the iOS Simulator's location.
  • Other native SDKs, like analytics or ads.
  • Geofence events the phone would deliver while your app is closed.

FAQ

Does this change the location on my phone?

No. Only your app sees the new location.

Does it work on a real phone?

Yes. It runs inside your app, so it works on a real phone, a simulator and an emulator.

Can AI agents use it?

Yes. The MCP server has get_location, location_action and sim_location, and Ask Buoy can do it when you ask, like "walk me past the downtown store and tell me if the check-in shows up". Buoy Desktop has a Location panel too.