Inspiration

Over 1 million immigrants arrive in the United States every year. The first 90 days are the most critical — and the most overwhelming. Getting a SIM card, finding a mailing address, applying for an SSN, enrolling children in school, understanding SNAP, Medicaid, ITIN — each step feels like navigating a bureaucratic maze in a language you may not speak fluently, with no one to guide you.

We were inspired by real stories from immigrant families who missed benefits they qualified for, filed taxes incorrectly, or lost jobs simply because they didn't know what to do first. We wanted to build the caseworker that every immigrant deserves but rarely gets — available 24/7, in their language, on their phone.

What it does

NewRoots is a multilingual, mobile-first navigator for newly arrived immigrant families. It provides:

90-Day Milestone Tracker — 29 step-by-step tasks spanning SIM card, address, I-94, local orientation, emergency contacts, SSN, bank account, health screening, health insurance, school enrollment, ESL classes, SNAP, RCA, Medicaid, WIC, selective service, driver's license, ITIN, AR-11 address change, EAD/work authorization, job readiness, job search, public transit, housing lease, credit building, VITA tax filing, legal aid, community network, and IOM travel loan repayment — grouped by urgency and week, with official government links

Benefits Discovery — personalized eligibility guidance for SNAP, Medicaid, WIC, housing, employment, and education programs

Tax Guidance — EITC, VITA free filing, ITIN, and deadline reminders tailored to the user's situation

Multilingual Voice Assistant — speak in your language, get answers spoken back; powered by ElevenLabs STT + TTS across 10 languages

AI Chat Agent — a conversational assistant that answers questions about milestones, benefits, and next steps

Supported languages: English, Spanish, Chinese, Hindi, Arabic, French, Portuguese, Vietnamese, Korean, Filipino.

How we built it

Frontend: React 18 + Vite 7 + TypeScript, styled with Tailwind CSS and shadcn/ui. Hash-based routing via Wouter for iframe compatibility.

Backend: Express 5 on Node.js with Turso (cloud SQLite / libSQL) via @libsql/client and Drizzle ORM for persistence. Auth0 for authentication, with stateless JWT verification via Auth0's /userinfo endpoint — a Bearer token is sent with every request, requiring no sessions or cookies.

Deployment: Vercel serverless, with api/index.ts as the serverless function handler.

Voice Pipeline:

Speech-to-Text: ElevenLabs Scribe v1 via MediaRecorder API — works across Chrome, Safari, Firefox, and iOS (unlike the browser-native Web Speech API)

Text-to-Speech: ElevenLabs eleven_multilingual_v2 model, proxied server-side to keep the API key secure

AI Agent: OpenAI API for the conversational assistant, with structured responses

Security: All external API keys (ElevenLabs, OpenAI, Auth0) are handled server-side. No secrets are ever shipped to the browser.

Challenges we ran into

Multilingual voice quality was the hardest problem. The browser-native Web Speech API has inconsistent or nonexistent support for Hindi, Arabic, Vietnamese, and Filipino — exactly the languages our target users speak. Switching to ElevenLabs Scribe for STT and eleven_multilingual_v2 for TTS solved quality across all 10 languages, but required building a secure server-side proxy and switching from webkitSpeechRecognition to MediaRecorder.

Authentication on serverless infrastructure was a critical hurdle. Our original session-based Auth0 integration worked locally but broke on Vercel because serverless function instances don't share memory — sessions created in one instance are invisible to the next. We fixed this by switching to fully stateless auth: every request carries a Bearer token, which the server verifies live against Auth0's /userinfo endpoint, with no session state required.

Database schema evolution mid-project required care. As the team added Auth0 integration and new user fields, the Turso cloud DB schema needed to stay in sync across environments. We established a clean initDb() migration pattern to handle schema changes without silent failures.

Mobile-first for low digital literacy meant rethinking every interaction. No search bars, no complex menus — everything is guided, spoken, and tappable. The voice-first design ensures the app is usable even for users with limited reading ability in English.

Accomplishments that we're proud of

Translating every UI string — not just labels, but dynamic strings with variables, fallback chains, and context-dependent copy — across 10 languages was the most unglamorous and most necessary part of the build. It works completely: switch the profile language to Arabic and the entire app flips to RTL; switch to Vietnamese and the AI responds in Vietnamese with accurate, state-specific information.

The AI agent is genuinely personalized. It isn't a generic chatbot with a system prompt that says "be helpful to immigrants." It knows the user's state, family size, arrival date, employment status, insurance coverage, language, and which milestone card they're currently looking at. Ask it about SNAP in California versus Texas and you get different answers, because the answers are different.

The voice pipeline works across all 10 languages — including Hindi, Arabic, Vietnamese, and Filipino, where Web Speech API support is unreliable or nonexistent. ElevenLabs Scribe handles STT and eleven_multilingual_v2 handles TTS, all routed through a server-side proxy. We also solved a structural problem in how LLMs respond to voice interfaces: the agent returns two separate fields — a clean spoken field for TTS and a display field with rich markdown for the UI — so the audio doesn't read out asterisks and bullet points.

Getting Auth0 session-based auth to work on Vercel serverless required scrapping sessions entirely and moving to stateless Bearer token verification via /userinfo. It's not the obvious path but it's the right one for this architecture. Persistent state is handled by Turso cloud SQLite with Drizzle ORM, which survives across serverless instances without connection pooling headaches.

The 29-milestone tracker covers the full first-90-days arc — from buying a SIM card at the airport to making the first IOM loan repayment — in a single, navigable journey. Nothing is left implied.

What we learned

Stateless auth is non-negotiable for serverless. Session-based auth assumes a persistent server. Vercel doesn't have one. We burned time on this before accepting that the architecture had to change, not the platform.

Translating an app is harder than translating text. String keys need to be exhaustive, fallbacks need to degrade gracefully, and dynamic strings with injected variables have different word-order rules across languages. A translation key that works in English and Spanish can silently break in Arabic or Vietnamese if the variable interpolation isn't built correctly.

Web Speech API is not a multilingual voice solution. It's adequate for English. For Hindi, Arabic, Vietnamese, and Filipino it ranges from inconsistent to broken depending on the browser and device. ElevenLabs Scribe was the right call; we just wish we'd made it earlier.

Structured LLM output isn't optional when you have two rendering targets. The moment you add TTS, you need to decide at generation time what the voice should say versus what the screen should show. Trying to strip markdown after the fact produces bad audio.

Designing for stressed users in their second language forces clarity. When the person reading your UI may be jet-lagged, financially anxious, and navigating a government system they've never encountered before — in a language they're still learning — every ambiguous label and every unnecessary step costs something real.

What's next for NewRoots

Offline mode / PWA. Many newly arrived refugees are managing data on prepaid SIM cards. The app should work — at least for milestone viewing and document access — without a reliable connection.

Push notifications. Tax filing deadlines, SNAP recertification windows, and 90-day milestone reminders are genuinely time-sensitive. Passive information isn't enough.

Caseworker dashboard. Resettlement agencies like IRC and USCRI are already tracking client milestones manually. A simple dashboard that shows caseworkers where each client is in the journey — and flags overdue steps — fits directly into existing workflows.

More languages. Somali, Amharic, Burmese, and Dari represent some of the largest underserved refugee populations arriving in the US. They are notably absent from most immigrant-facing digital tools and are the obvious next additions.

State-specific milestone variants. SNAP is called different names, processed through different offices, and has different income thresholds by state. Medicaid enrollment rules vary. School enrollment requirements vary. The milestone content needs to branch by state, not just the AI answers.

Government portal integrations. CBP's I-94 lookup and USCIS case status are publicly accessible. Surfacing them in-context — at the milestone where they're relevant — removes a significant navigation burden.

Community connections. Connecting users with others from their home country who are already established in the same city addresses something no checklist can: the need to talk to someone who has been through it.

Built With

  • auth0
  • claude-api-(anthropic)
  • dotenv
  • drizzle-orm
  • elevenlabs-(tts-+-stt)
  • express-5
  • mediarecorder-api
  • node.js
  • openai
  • radix-ui
  • react-18
  • shadcn/ui
  • sqlite-(libsql)
  • tailwind-css
  • tanstack-query
  • turso
  • typescript
  • vite
  • wouter
Share this project:

Updates