
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.
npm install @buoy-gg/locationLocation 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:
// 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/geolocationreact-native-geolocation-serviceYou don't change your app's code.
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.
37.3349, -122.0090 or a Google or Apple Maps link, and a list of places around the world.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.
Add the places your app cares about, like your stores, and routes that pass by them:
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
},
]);
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.
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.
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:
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.No. Only your app sees the new location.
Yes. It runs inside your app, so it works on a real phone, a simulator and an emulator.
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.