Simultaneous Real-Time Voting Tool Everyone votes at once, results revealed together. Ideal for Planning Poker, Health Checks, Retrospectives and more.
- Simultaneous Voting: Everyone votes at the same time without influencing each other
- Multiple Rooms: Support for multiple simultaneous sessions
- Pre-defined Voting Templates: Fibonacci, 1-5/1-10 scales, traffic light, trends, yes/no, t-shirt sizes, MoSCoW prioritization, starfish retrospectives
- Multiple Questions: Vote on multiple templates in a single round
- Optional Timer: Set time limit with sound alert (client-side controlled)
- Progress Visibility: Everyone sees who has voted during the round
- Statistics: Average, distribution and results visualization
- No Persistence: In-memory state, ie, ephemeral sessions
- Template: Fibonacci
- Topic: "Estimate complexity of task #123"
- Team votes simultaneously
- Results reveal consensus or need for discussion
- Template: Traffic Light and Trend
- Topic: "How fun is it working together?"
- Quick visualization of general status
- Template: Trend
- Topic: "The team velocity is..."
- Identifies perceptions about evolution
- Node.js (v14+)
- npm or yarn
- Access main page
- Click on
Create Room - Share the room code with participants (or let them scan the QR code)
- Wait for participants to join
- Enter the voting topic
- Choose one or more templates (Fibonacci, 1-5, Traffic Light, etc)
- (Optional) Set a timer in seconds
- Start the voting
- When ready, reveal the results
- End the round to start a new one
Tip: Click on the QR code in the header to show a large version that participants can scan from across the room.
- Access main page
- Click on
Join Room - Enter the room code and your name (or scan the QR code from admin's screen to auto-fill the room code)
- Click
Join - Wait for admin to start the voting round
- Vote (you can change your vote before reveal)
- See the results when admin reveals them
| Template | Description | Options |
|---|---|---|
| Fibonacci | Classic Planning Poker | 0, 0.5, 1, 2, 3, 5, 8, 13, 20, 40, 100, ?, β |
| Scale 1-5 | Simple assessment | 1, 2, 3, 4, 5 |
| Scale 1-10 | Detailed assessment | 1 to 10 |
| Traffic Light | Visual status | π’ Green, π‘ Yellow, π΄ Red |
| Trend | Temporal evolution | |
| Yes/No | Binary decision | π Yes, π No |
| T-Shirt Sizes | Size estimation | XS, S, M, L, XL, XXL |
| MoSCoW Priority | Prioritization method | Must have, Should have, Could have, Won't have |
| Starfish | Retrospective feedback |
# Clone the repository
git clone <repo>
cd susensus
# Install dependencies
npm install
# Start the server
npm startThe server will be available at: http://localhost:3000
By default, the server runs on port 3000. To change:
PORT=8080 npm startOr edit bin/www:
var port = normalizePort(process.env.PORT || '3000');Empty rooms older than 2 hours are automatically removed. Can be adjusted in utils/rooms.js:
cleanupOldRooms() {
const TWO_HOURS = 2 * 60 * 60 * 1000; // Change here
...
}- Set up Node.js on the server
- Clone the repository
- Install dependencies:
npm install - Configure
PORTenvironment variable if needed - Use PM2 or similar to keep the process alive:
npm install -g pm2
pm2 start bin/www --name susensus
pm2 save
pm2 startupCreate a Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]Build and run:
docker build -t susensus .
docker run -d --name susensus-app -p 3000:3000 susensus
| Event | Parameters | Description |
|---|---|---|
createRoom |
adminName |
Creates new room |
startVoting |
{templateId, topic, timerSeconds} |
Starts voting round |
revealResults |
- | Reveals the results |
endRound |
- | Ends current round |
kickParticipant |
socketId |
Kicks participant |
getTemplates |
- | Gets list of templates |
| Event | Parameters | Description |
|---|---|---|
joinRoom |
{code, name} |
Join a room |
vote |
{templateId, vote} |
Submit a vote |
| Event | Description |
|---|---|
roomUpdate |
Room state update |
participantJoined |
New participant joined |
participantLeft |
Participant left |
votingStarted |
Voting started |
resultsRevealed |
Results revealed |
roundEnded |
Round ended |
kicked |
Participant was kicked |
roomClosed |
Room closed |
- In-Memory State: Restarting the server loses all active rooms
- No Persistent History: No information is persisted
Pull requests are welcome! For major changes, please open an issue first.
- GitHub: rjpmestre
- Email: ricardo.mestre@suse.com
- Developed as part of SUSE Hack Week 25