Skip to Content
All posts

How I Built an Arabic–Bengali Voice Translator

 — #ai#full-stack-development#building-in-public#product-development

When I arrived in Saudi Arabia, I discovered a problem that looked small until I had to face it in real conversations.

I speak Bengali and English. Many of the people around me speak Arabic. Translation apps existed, but opening an app, choosing languages, waiting for speech recognition, checking the text, and passing the phone back created too much friction. A conversation that should have felt natural became a sequence of technical steps.

So I built a simple product for the situation: a two-way voice translator that lets a Bengali speaker and an Arabic speaker share one device.

The result is a working Arabic–Bengali translator. It is still an MVP, but building it taught me more about AI product development than starting with a long feature list ever could.

Why did I build this instead of using an existing app?

The problem was not that translation technology did not exist. The problem was that the interaction did not fit the moment.

In a face-to-face conversation, every extra action matters. If I have to change a language, explain which button to press, wait for a result, start text-to-speech, and then repeat the setup for the reply, the technology becomes part of the conversation instead of disappearing behind it.

That changed how I defined the product.

I was not trying to build the most capable translator. I wanted to reduce the distance between one person speaking and the other person understanding. That meant the real product was not only the translation model. It was the complete conversational loop around the model.

This is the same lesson I described when writing about why AI tools do not fix messy workflows. A capable model cannot rescue a confusing sequence of actions. The workflow is part of the product.

What did the smallest useful product need?

My first question was not, “Which features can I add?” It was, “What must happen for two people to complete one exchange?”

The smallest useful loop needed to do six things:

  1. Let the first person choose a language and speak.
  2. Capture or receive the spoken input.
  3. Produce a transcript and translation.
  4. Show both in a clear conversation feed.
  5. Read the translation aloud when a device voice is available.
  6. Switch the active language so the other person can reply with one tap.

Everything else was optional.

There are no accounts, saved conversations, database, dashboard, or analytics. Messages live in React state and disappear when the page refreshes. That may sound incomplete, but persistence does not improve the core exchange. It would have added privacy questions, database work, and more ways for the MVP to fail.

The application defaults to Bengali and Arabic, while the language table supports about 48 languages. This gave the product a focused starting point without hard-coding the entire architecture around one pair.

How does the translation pipeline work?

A voice product is not one AI call. It is a pipeline, and the user experiences the total time and reliability of every stage.

For in-app recording, the browser captures audio and converts it to a 16 kHz mono WAV file. The server sends the audio through OpenRouter to Gemini 2.5 Flash, asking for both the transcript and the translation. The API returns a consistent response containing those two values.

The client then adds the message to the conversation and uses the browser's speech-synthesis capability to read the translated text. Finally, it switches the speaking direction for the reply.

The complete flow is:

record → normalize audio → transcribe → translate → display → speak → switch

Recordings are limited to 60 seconds. That constraint keeps requests bounded and matches the product's purpose: short, real-time exchanges rather than long-form transcription.

I also added a second input path. A user can dictate into the text box with the microphone built into the phone or system keyboard. In that flow, the operating system handles speech recognition and the app only translates the resulting text.

Both inputs feed the same translation experience. That makes the interface flexible without creating two separate products.

Why did one AI call matter?

It would have been easy to treat transcription and translation as separate model requests.

The first request could turn audio into text. The second could translate that text. It is a clean separation on paper, but each network round trip adds waiting, cost, and another failure point.

For this MVP, asking one model call to return both the transcript and translation made the path shorter. The server has one response shape to validate, and the user waits for one model operation rather than two.

That does not mean one-call architecture is always correct. Separate services may provide better control, observability, or accuracy at scale. But an MVP should optimize for learning. I needed to test whether people could complete a conversation comfortably, not design an enterprise translation platform before the first useful exchange.

This is one of the less glamorous realities of building products with language models: model capability matters, but system boundaries, response contracts, and error handling often determine whether the feature feels dependable.

The full-stack decisions that kept it small

The application uses Next.js, React, and TypeScript. The AI request lives in a server route, which keeps the OpenRouter key away from the browser. Users can inspect the client without receiving a secret that could be copied and abused.

A few other decisions kept the system understandable:

  • The browser records and prepares audio before sending it.
  • The server owns model access and returns a small response shape.
  • The client owns temporary conversation state.
  • The browser handles spoken output through speech synthesis.
  • Next-intl provides English, Bengali, and Arabic interface text.
  • Arabic mode switches the complete interface to right-to-left layout.

I deliberately treated interface language and conversation language as different concepts. Someone might use an English interface to translate Bengali into Arabic, or an Arabic interface to translate another supported pair. Combining those settings would have made the experience less flexible.

The full source is available in the translator's GitHub repository. It shows the useful shape of a small full-stack AI product: a focused client, a protected server boundary, and as little permanent infrastructure as the experiment requires.

What failed outside the happy path?

The easiest demo is one clear sentence, spoken in a quiet room, with every browser permission already granted. Real use is less cooperative.

A practical voice translator must expect several kinds of failure:

  • The user denies microphone permission.
  • The recording contains background noise.
  • The model returns a response that does not match the expected structure.
  • A request takes too long or fails.
  • The device does not have a voice for the translated language.
  • Right-to-left text breaks an interface designed only for English.
  • The two selected languages accidentally become the same.

Text-to-speech is a good example. The browser can request a Bengali or Arabic voice, but the available voices depend on the device. Pretending that spoken output always works would create a silent failure. The app still shows the translation and explains when a compatible voice is missing.

This changed how I think about AI reliability. A product does not become reliable because the model is usually correct. It becomes reliable when the surrounding interface makes uncertainty and failure understandable.

I explored the same principle in designing reliable AI workflows: define the expected output, validate it, make failure visible, and keep recovery simple.

What this project taught me about AI products

The biggest lesson is that AI is usually a component, not the complete product.

Users do not care which part was difficult to engineer. They experience one continuous outcome. If microphone permission is confusing, audio conversion is slow, the translation is unclear, or speech output is missing, the product feels broken even when the model performed perfectly.

I also learned that constraints create clarity.

Choosing one-device conversation removed account and synchronization work. Keeping conversations temporary removed database work. Limiting recordings reduced unpredictable requests. Supporting two ways to speak let me compare behavior without building a complex experiment system.

Most importantly, the project began with a problem I personally experienced. That made it easier to decide what mattered. I did not need to imagine the user, the setting, or the frustration. I had already been that user.

Building in public does not require pretending that an MVP is a finished company. It means sharing the problem, the decisions, the tradeoffs, and the lessons while the work is still honest. Shipping the small version is often more valuable than waiting for the imaginary perfect launch—a trap I wrote about in the myth of the perfect launch.

A practical checklist for your next MVP

If you want to build an AI product, start with the user loop before choosing the model.

Ask:

  1. What real moment creates the problem?
  2. What is the smallest outcome that would help?
  3. Which steps require AI, and which are ordinary software?
  4. What data or permissions does the workflow need?
  5. Which expensive features can remain temporary or manual?
  6. What happens when the model, network, or device fails?
  7. How will you know that a user completed the loop?

Then build one path from beginning to end.

Do not begin with dashboards, subscription plans, team workspaces, and a list of integrations. Begin with one person, one problem, and one finished result. Put the product in a real situation and watch where the conversation—or the workflow—slows down.

That is what this translator MVP gave me. It did not prove that I had built the final solution. It proved that a painful real-world interaction could be turned into a small, testable full-stack product.

And that is enough for the next iteration.