HireSpark
Employers call candidates from the web; candidates answer, message, and interview from an Expo app
HireSpark starts an interview the same way a phone starts a call. An employer rings a candidate, the candidate accepts on mobile, and both join the same video room.
Why skip the calendar
Scheduling adds email, reminders, and another chance for either person to disappear. HireSpark tests a more direct flow for early screening calls: see who is available, call them, and move on if they do not answer.
The product has two interfaces because the two sides use it differently.
Employer dashboard
Employers can:
- Post a role and limit it by location
- Generate screening questions from the job description with Cerebras
- Rank candidates by weighted requirements and proximity
- Message a candidate
- Start a video call from the candidate record
Candidate app
Candidates use an Expo app to:
- Sign in with Google through Clerk
- Complete the location and eligibility questionnaire
- Message employers
- Answer an incoming call from a full-screen overlay
- Join a video interview with the other person full screen and their own camera in the corner
One backend for both apps
hirespark/
├── apps/
│ ├── native/ # Expo candidate app
│ └── web/ # React employer dashboard
├── packages/
│ ├── backend/ # Convex functions and data
│ └── config/ # Shared configuration
└── turbo.json
Convex holds the shared data and server functions. Its generated types are used by both the React 19 web app and the Expo 54 mobile app. The monorepo keeps the call, message, job, and candidate contracts in one place.
Stream handles the WebRTC connection. Clerk owns sign-in, then the backend validates the Clerk session and returns a Stream token for that user. The client never creates its own video credentials.
Where the work went
The call had to feel native on both sides
Stream supplies the connection, not the product interface. The web dashboard and mobile app each needed their own call controls, participant layout, and leave states while sharing the same room logic.
Screening needed a score, not just generated text
Cerebras turns a job description into questions. Candidate answers are then scored against weighted requirements so the ranking has a reason behind it instead of being a loose model judgment.
Ringing is a state problem
The incoming overlay has to appear quickly, disappear when the caller leaves, and avoid opening a stale room. Convex carries the call state between devices, while the mobile interface responds to each transition.