Hand tracking microgestures OpenXR extension
Updated: Mar 14, 2025
This topic provides:
- A usage guide for the Hand Tracking Microgestures OpenXR extension and links to related topics.
Microgestures expand the capabilities of hand tracking by recognizing low-calorie thumb tap and thumb swipe motions performed on the side of the index finger. These gestures trigger discrete D-pad-like directional commands.
The hand pose and motion of the thumb is as follows: initially, the thumb must be raised above the index finger (not touching the index finger). The other fingers should be slightly curled as in the picture below for best performance: i.e. not too extended, nor completely curled into a fist.
A tap is performed by touching the middle segment of the index finger with the thumb, and then lifting the thumb.
The four directional thumb swipes performed on the surface of the index finger are:
- Left swipe: a swipe towards the index fingertip on the right hand, and away from the index fingertip on the left hand. On the right hand for example, the motion is as follows: the thumb starts raised above the index finger, touches the middle segment of the index finger, slides towards the index fingertip, and lifts.
- Right swipe: the same motion as the left swipe, but in the opposite direction. On the right hand for example, the thumb starts raised above the index finger, touches the middle segment of the index finger, slides away from the index fingertip, and lifts.
- Forward swipe: the thumb starts raised above the index finger, touches the middle segment of the index finger, slides forward, and lifts.
- Backward swipe: the thumb starts raised above the index finger, touches the middle segment of the index finger, slides backward/downward, and lifts.
Note that the motions can be performed at moderate to quick speeds, and should be performed in one smooth motion. The detection of the gesture happens at the end of the motion.

- Quest 2, Quest Pro, and the Quest 3 family of devices.
- Unity version 2021 LTS and above
- Integration SDK version 74 and above
The XR_META_hand_tracking_microgestures
 extension is introducing 5 more action paths for the XR_EXT_hand_interaction
profile, per hand:
Top-level paths:
- pathname:
/user/hand/left
- pathname:
/user/hand/right
Additional supported component paths:
- subpathname:
/input/swipe_left_meta/click
- subpathname:
/input/swipe_right_meta/click
- subpathname:
/input/swipe_forward_meta/click
- subpathname:
/input/swipe_backward_meta/click
- subpathname:
/input/tap_thumb_meta/click
All these paths are boolean paths, which become True
(for a very short duration) once the
corresponding gesture has been completed and recognized.
Initializing a microgesture action for the right hand:
XrPath extHandInteractionProfile{XR_NULL_PATH};
std::vector<XrActionSuggestedBinding>> suggestedBindings{};
// EXT_hand_interaction profile
OXR(xrStringToPath(
instance,
"/interaction_profiles/ext/hand_interaction_ext",
&extHandInteractionProfile));
// Create an action set for microgestures on the right hand
XrActionSet actionRightHandSetMicrogestures{XR_NULL_HANDLE};
XrActionSetCreateInfo asci = {XR_TYPE_ACTION_SET_CREATE_INFO};
strcpy(asci.actionSetName, "right_hand_microgesture_action_set");
strcpy(asci.localizedActionSetName, "Right hand microgestures");
OXR(xrCreateActionSet(instance, &asci, &actionRightHandSetMicrogestures));
// Create an action for "swipe left" and add it to the action set
XrAction actionRightHandSwipeLeft{XR_NULL_HANDLE};
XrActionCreateInfo aci = {XR_TYPE_ACTION_CREATE_INFO};
aci.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(aci.actionName, "action_right_hand_swipe_left");
strcpy(aci.localizedActionName, "Right Hand Swipe Left");
OXR(xrCreateAction(actionRightHandSetMicrogestures, &aci, &actionRightHandSwipeLeft));
// Bind the action to the path
XrActionSuggestedBinding asb;
asb.action = actionRightHandSwipeLeft;
XrPath bindingPath;
OXR(xrStringToPath(instance, "/user/hand/right/input/swipe_left_meta/click", &bindingPath));
asb.binding = bindingPath;
suggestedBindings[extHandInteractionProfile].emplace_back(asb);
Syncing the action on update and getting the action state:
// sync actions
std::vector<XrActiveActionSet> activeActionSets = ;
XrActionsSyncInfo syncInfo = {XR_TYPE_ACTIONS_SYNC_INFO};
syncInfo.countActiveActionSets = activeActionSets.size();
syncInfo.activeActionSets = activeActionSets.data();
OXR(xrSyncActions(session, &syncInfo));
// get state of the action
XrActionStateGetInfo getInfo{XR_TYPE_ACTION_STATE_GET_INFO};
getInfo.action = actionRightHandSwipeLeft;
getInfo.subactionPath = XR_NULL_PATH;
XrActionStateBoolean state{XR_TYPE_ACTION_STATE_BOOLEAN};
OXR(xrGetActionStateBoolean(session, &getInfo, &state));
The following software is required:
- Meta Quest build v74.0 or later
- Oculus PC app with version v74.0 or later, which you can download from the Meta Quest website