Skip to main content
Version: V2

Semaphore groups

Use Semaphore in your application or smart contract to create off-chain and on-chain groups.

A Semaphore group contains identity commitments of group members. Example uses of groups include the following:

  • Poll question that attendees join to rate an event.
  • Ballot that members join to vote on a proposal.
  • Whistleblowers who are verified employees of an organization.

A Semaphore group is an incremental Merkle tree, and group members (i.e., identity commitments) are tree leaves. Semaphore groups set the following two parameters:

  • Tree depth: the maximum number of members a group can contain (max size = 2 ^ tree depth).
  • Zero value: the value used to calculate the zero nodes of the incremental Merkle tree.

Learn how to work with groups.

Off-chain groups

Create a group

Use the @semaphore-protocol/group library Group class to create an off-chain group.


  • Tree depth: (default 20) the maximum number of members a group can contain (max size = 2 ^ tree depth).
  • Zero value: (default BigInt(0)) the value for a tree node that doesn't have a member assigned.

To create a group with default treeDepth and zeroValue, call the Group constructor without parameters--for example:

import { Group } from "@semaphore-protocol/group"

// Default parameters: treeDepth = 20, zeroValue = BigInt(0).
const group = new Group()

The following example code passes treeDepth to create a group for 2 ^ 30 = 1073741824 members:

import { Group } from "@semaphore-protocol/group"

const group = new Group(30)

The following example code creates a group with a zeroValue of BigInt(1):

import { Group } from "@semaphore-protocol/group"

const group = new Group(20, BigInt(1))

Add members

Use the Group addMember function to add a member (identity commitment) to a group--for example:


To add a batch of members to a group, pass an array to the Group addMembers function--for example:

group.addMembers([identityCommitment1, identityCommitment2])

Remove or update members

To remove members from a group, pass the member index to the Group removeMember function--for example:


To update members in a group, pass the member index and the new value to the Group updateMember function--for example:

group.updateMember(0, 2)

Removing a member from a group sets the node value to zeroValue. Given that the node isn't removed, and the length of the group.members array doesn't change.

On-chain groups

The SemaphoreGroups contract uses the IncrementalBinaryTree library and provides methods to create and manage groups.


You can import SemaphoreGroups and other Semaphore contracts from the @semaphore-protocol/contracts NPM module.

Alternatively, you can use an already deployed Semaphore contract and use its group external functions.