<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aman singh </title>
    <description>The latest articles on DEV Community by Aman singh  (@officialasforge).</description>
    <link>https://dev.to/officialasforge</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4113655%2Ffc6a4b19-4561-4cfe-9c5b-e0fbfc5bf71a.png</url>
      <title>DEV Community: Aman singh </title>
      <link>https://dev.to/officialasforge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/officialasforge"/>
    <language>en</language>
    <item>
      <title>How I Built an AI Fitness Coach with Gemini, React and Three.js</title>
      <dc:creator>Aman singh </dc:creator>
      <pubDate>Mon, 07 Sep 2026 10:43:39 +0000</pubDate>
      <link>https://dev.to/officialasforge/how-i-built-an-ai-fitness-coach-with-gemini-react-and-threejs-2kp</link>
      <guid>https://dev.to/officialasforge/how-i-built-an-ai-fitness-coach-with-gemini-react-and-threejs-2kp</guid>
      <description>&lt;p&gt;How I Built an AI Fitness Coach with Gemini, React and Three.js&lt;/p&gt;

&lt;p&gt;Building a website is one thing. Building a website that can actually interact with users is something completely different.&lt;/p&gt;

&lt;p&gt;While working on my fitness project under ASForge, I wanted to create more than a traditional fitness website. I wanted to build an AI fitness coach that could communicate with users, answer questions, and feel like an actual character inside the website.&lt;/p&gt;

&lt;p&gt;That's how Titan was created — an AI-powered fitness coach built with React, Three.js and Gemini.&lt;/p&gt;

&lt;p&gt;The Idea Behind Titan&lt;/p&gt;

&lt;p&gt;The goal was simple:&lt;/p&gt;

&lt;p&gt;Create a fitness website where the AI coach is not just a chatbot sitting inside a box, but a 3D character that interacts with the user.&lt;/p&gt;

&lt;p&gt;Titan was designed to provide an interactive experience where users can:&lt;/p&gt;

&lt;p&gt;Ask fitness-related questions&lt;br&gt;
Chat with the AI&lt;br&gt;
Use voice interaction&lt;br&gt;
Receive spoken responses&lt;br&gt;
Switch between different languages&lt;br&gt;
Interact with a 3D AI character&lt;/p&gt;

&lt;p&gt;The project also gave me an opportunity to combine frontend development, 3D graphics and generative AI in one application.&lt;/p&gt;

&lt;p&gt;Technologies I Used&lt;/p&gt;

&lt;p&gt;The main technologies behind the project are:&lt;/p&gt;

&lt;p&gt;React — User interface and application logic&lt;br&gt;
Vite — Development environment and build tool&lt;br&gt;
Three.js — 3D graphics&lt;br&gt;
React Three Fiber — Using Three.js inside React&lt;br&gt;
@react-three/drei — Useful Three.js helpers&lt;br&gt;
Gemini API — AI responses&lt;br&gt;
Web Speech API — Voice recognition and text-to-speech&lt;br&gt;
JavaScript — Application logic and interactions&lt;/p&gt;

&lt;p&gt;The combination of these technologies made it possible to create both the visual and conversational parts of Titan.&lt;/p&gt;

&lt;p&gt;Creating the 3D AI Coach&lt;/p&gt;

&lt;p&gt;The first challenge was getting a 3D character into the React application.&lt;/p&gt;

&lt;p&gt;I used a GLB model for Titan and loaded it using useGLTF.&lt;/p&gt;

&lt;p&gt;A simplified version looks like this:&lt;/p&gt;

&lt;p&gt;import { useGLTF } from "@react-three/drei";&lt;/p&gt;

&lt;p&gt;function Robot() {&lt;br&gt;
  const { scene } = useGLTF("/models/ai-coach.glb");&lt;/p&gt;

&lt;p&gt;return (&lt;br&gt;
    
      object={scene}&lt;br&gt;
      scale={1.35}&lt;br&gt;
      position={[0.15, -0.85, 0]}&lt;br&gt;
    /&amp;gt;&lt;br&gt;
  );&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;I then placed the model inside a React Three Fiber Canvas.&lt;/p&gt;

&lt;p&gt;&amp;lt;Canvas&lt;br&gt;
  camera={{&lt;br&gt;
    position: [0, 0.1, 3.8],&lt;br&gt;
    fov: 40,&lt;br&gt;
  }}&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;br&gt;
  
    position={[5, 5, 5]}&lt;br&gt;
    intensity={2}&lt;br&gt;
  /&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;Getting the correct camera position, model scale and character placement took quite a bit of experimentation.&lt;/p&gt;

&lt;p&gt;A model can look perfect in a 3D viewer but appear too small, too large or partially outside the screen when placed inside a real webpage.&lt;/p&gt;

&lt;p&gt;Adding Animation&lt;/p&gt;

&lt;p&gt;The character should not feel like a static image.&lt;/p&gt;

&lt;p&gt;The GLB model contains animations, so I used useAnimations to play them.&lt;/p&gt;

&lt;p&gt;const { scene, animations } =&lt;br&gt;
  useGLTF("/models/ai-coach.glb");&lt;/p&gt;

&lt;p&gt;const { actions } =&lt;br&gt;
  useAnimations(animations, group);&lt;/p&gt;

&lt;p&gt;useEffect(() =&amp;gt; {&lt;br&gt;
  if (!actions) return;&lt;/p&gt;

&lt;p&gt;Object.values(actions).forEach((action) =&amp;gt; {&lt;br&gt;
    action.reset().fadeIn(0.5).play();&lt;br&gt;
  });&lt;br&gt;
}, [actions]);&lt;/p&gt;

&lt;p&gt;This made Titan feel much more alive inside the website.&lt;/p&gt;

&lt;p&gt;Connecting Titan to Gemini&lt;/p&gt;

&lt;p&gt;The next part was giving Titan a brain.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding responses, I connected the application to the Gemini API.&lt;/p&gt;

&lt;p&gt;The basic flow is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
  ↓&lt;br&gt;
Titan UI&lt;br&gt;
  ↓&lt;br&gt;
React&lt;br&gt;
  ↓&lt;br&gt;
Backend API&lt;br&gt;
  ↓&lt;br&gt;
Gemini&lt;br&gt;
  ↓&lt;br&gt;
AI Response&lt;br&gt;
  ↓&lt;br&gt;
Titan&lt;/p&gt;

&lt;p&gt;I kept the Gemini API key on the server side instead of exposing it directly in the React frontend.&lt;/p&gt;

&lt;p&gt;The frontend sends the user's message to my backend:&lt;/p&gt;

&lt;p&gt;const response = await fetch("/api/chat", {&lt;br&gt;
  method: "POST",&lt;br&gt;
  headers: {&lt;br&gt;
    "Content-Type": "application/json",&lt;br&gt;
  },&lt;br&gt;
  body: JSON.stringify({&lt;br&gt;
    message: text,&lt;br&gt;
    language: language.name,&lt;br&gt;
  }),&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;The backend then communicates with Gemini and returns the generated response.&lt;/p&gt;

&lt;p&gt;This separation is important because API keys should not be placed directly inside frontend code.&lt;/p&gt;

&lt;p&gt;Giving Titan a Voice&lt;/p&gt;

&lt;p&gt;A normal chatbot only shows text.&lt;/p&gt;

&lt;p&gt;I wanted Titan to actually speak.&lt;/p&gt;

&lt;p&gt;For that, I used browser speech capabilities.&lt;/p&gt;

&lt;p&gt;The browser's speech synthesis API can convert text into spoken audio:&lt;/p&gt;

&lt;p&gt;const utterance = new SpeechSynthesisUtterance(text);&lt;/p&gt;

&lt;p&gt;utterance.rate = 0.88;&lt;br&gt;
utterance.pitch = 0.55;&lt;br&gt;
utterance.volume = 1;&lt;/p&gt;

&lt;p&gt;speechSynthesis.speak(utterance);&lt;/p&gt;

&lt;p&gt;Now the interaction becomes:&lt;/p&gt;

&lt;p&gt;User asks a question&lt;br&gt;
        ↓&lt;br&gt;
Gemini generates the answer&lt;br&gt;
        ↓&lt;br&gt;
Titan receives the answer&lt;br&gt;
        ↓&lt;br&gt;
Speech Synthesis speaks it&lt;/p&gt;

&lt;p&gt;The exact available voices depend on the user's browser and operating system, so voice characteristics can vary between devices.&lt;/p&gt;

&lt;p&gt;Voice Input&lt;/p&gt;

&lt;p&gt;I also wanted users to be able to talk to Titan instead of typing everything.&lt;/p&gt;

&lt;p&gt;The browser's Speech Recognition API can convert speech into text.&lt;/p&gt;

&lt;p&gt;The basic concept is:&lt;/p&gt;

&lt;p&gt;const recognition =&lt;br&gt;
  new SpeechRecognition();&lt;/p&gt;

&lt;p&gt;recognition.lang = "en-IN";&lt;/p&gt;

&lt;p&gt;recognition.onresult = (event) =&amp;gt; {&lt;br&gt;
  const transcript =&lt;br&gt;
    event.results[0][0].transcript;&lt;/p&gt;

&lt;p&gt;console.log(transcript);&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;recognition.start();&lt;/p&gt;

&lt;p&gt;The recognized text can then be sent to Gemini just like a normal typed message.&lt;/p&gt;

&lt;p&gt;Handling Multiple Languages&lt;/p&gt;

&lt;p&gt;Another goal of Titan was making the experience more accessible to users who are more comfortable communicating in Indian languages.&lt;/p&gt;

&lt;p&gt;The interface includes language selection for languages such as:&lt;/p&gt;

&lt;p&gt;Hindi&lt;br&gt;
English&lt;br&gt;
Bengali&lt;br&gt;
Telugu&lt;br&gt;
Tamil&lt;br&gt;
Marathi&lt;br&gt;
Gujarati&lt;br&gt;
Kannada&lt;br&gt;
Malayalam&lt;br&gt;
Punjabi&lt;br&gt;
Odia&lt;br&gt;
Assamese&lt;br&gt;
Urdu&lt;br&gt;
Nepali&lt;br&gt;
Konkani&lt;br&gt;
Maithili&lt;br&gt;
Sanskrit&lt;br&gt;
Kashmiri&lt;br&gt;
Sindhi&lt;br&gt;
Dogri&lt;br&gt;
Manipuri&lt;br&gt;
Santali&lt;/p&gt;

&lt;p&gt;The selected language is passed along with the user's request so Titan can respond in the selected language.&lt;/p&gt;

&lt;p&gt;However, speech recognition and available voices are dependent on browser and device support, so multilingual voice behavior can vary.&lt;/p&gt;

&lt;p&gt;Making Titan Feel Like an Assistant&lt;/p&gt;

&lt;p&gt;One of the most interesting parts of the project was designing the interaction.&lt;/p&gt;

&lt;p&gt;I didn't want the AI to behave like a simple form:&lt;/p&gt;

&lt;p&gt;Question → Answer&lt;/p&gt;

&lt;p&gt;Instead, I wanted the experience to feel more like talking to an assistant.&lt;/p&gt;

&lt;p&gt;The interaction became:&lt;/p&gt;

&lt;p&gt;Speak&lt;br&gt;
  ↓&lt;br&gt;
Speech Recognition&lt;br&gt;
  ↓&lt;br&gt;
Gemini&lt;br&gt;
  ↓&lt;br&gt;
Titan Response&lt;br&gt;
  ↓&lt;br&gt;
Text-to-Speech&lt;br&gt;
  ↓&lt;br&gt;
User&lt;/p&gt;

&lt;p&gt;I also worked on interruption handling so that when the user genuinely starts another question while Titan is speaking, the current speech can be stopped and the new request can be processed.&lt;/p&gt;

&lt;p&gt;This part was more difficult than I initially expected because the microphone can sometimes pick up the computer's own speaker output.&lt;/p&gt;

&lt;p&gt;Using microphone echo cancellation and noise suppression helped, but the behavior can still depend on the hardware and environment.&lt;/p&gt;

&lt;p&gt;Designing the AI Interface&lt;/p&gt;

&lt;p&gt;I wanted the AI controls to stay separate from the 3D character.&lt;/p&gt;

&lt;p&gt;The basic structure became:&lt;/p&gt;

&lt;p&gt;┌─────────────────────────────┐&lt;br&gt;
│        Titan AI Coach       │&lt;br&gt;
│                             │&lt;br&gt;
│   Chat / Talk / Language    │&lt;br&gt;
│                             │&lt;br&gt;
│          Messages           │&lt;br&gt;
│                             │&lt;br&gt;
│              3D Titan       │&lt;br&gt;
│                  🤖         │&lt;br&gt;
└─────────────────────────────┘&lt;/p&gt;

&lt;p&gt;The 3D character is rendered in its own layer while the chat and controls are placed above or behind it using CSS positioning and z-index.&lt;/p&gt;

&lt;p&gt;This creates the impression that Titan is actually standing inside the interface rather than being another ordinary HTML element.&lt;/p&gt;

&lt;p&gt;Problems I Faced&lt;/p&gt;

&lt;p&gt;The project wasn't straightforward.&lt;/p&gt;

&lt;p&gt;Some of the biggest challenges were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;3D Model Positioning&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The character was sometimes too small or moved outside the visible area.&lt;/p&gt;

&lt;p&gt;I had to adjust:&lt;/p&gt;

&lt;p&gt;Camera position&lt;br&gt;
Field of view&lt;br&gt;
Model scale&lt;br&gt;
Model position&lt;br&gt;
Canvas dimensions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Voice Interruption&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Speech recognition could sometimes detect audio coming from Titan itself.&lt;/p&gt;

&lt;p&gt;This created unexpected interruptions.&lt;/p&gt;

&lt;p&gt;I experimented with:&lt;/p&gt;

&lt;p&gt;Echo cancellation&lt;br&gt;
Noise suppression&lt;br&gt;
Automatic gain control&lt;br&gt;
Microphone monitoring&lt;br&gt;
Speech recognition confirmation&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;API Availability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI APIs can occasionally return temporary errors or become unavailable during periods of high demand.&lt;/p&gt;

&lt;p&gt;This made retry handling and proper error messages important.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keeping API Keys Secure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I initially focused on making the AI work, but quickly realized that API credentials should never be exposed in frontend code.&lt;/p&gt;

&lt;p&gt;Moving the API call to a backend was an important architectural improvement.&lt;/p&gt;

&lt;p&gt;What I Learned&lt;/p&gt;

&lt;p&gt;This project taught me that building an AI application isn't only about calling an AI API.&lt;/p&gt;

&lt;p&gt;There are several layers involved:&lt;/p&gt;

&lt;p&gt;UI/UX&lt;br&gt;
  +&lt;br&gt;
3D Graphics&lt;br&gt;
  +&lt;br&gt;
AI&lt;br&gt;
  +&lt;br&gt;
Voice&lt;br&gt;
  +&lt;br&gt;
Backend&lt;br&gt;
  +&lt;br&gt;
Browser APIs&lt;/p&gt;

&lt;p&gt;Each layer has its own challenges.&lt;/p&gt;

&lt;p&gt;Three.js taught me about cameras, lighting, models and 3D positioning.&lt;/p&gt;

&lt;p&gt;React taught me how to manage application state and UI.&lt;/p&gt;

&lt;p&gt;Gemini introduced me to integrating generative AI into an actual application.&lt;/p&gt;

&lt;p&gt;The Web Speech API showed me how powerful browser capabilities can be for voice interfaces.&lt;/p&gt;

&lt;p&gt;And debugging all of these systems together taught me perhaps the most important lesson:&lt;/p&gt;

&lt;p&gt;Building real products involves solving problems that don't appear in tutorials.&lt;/p&gt;

&lt;p&gt;What's Next for Titan?&lt;/p&gt;

&lt;p&gt;Titan is still a work in progress.&lt;/p&gt;

&lt;p&gt;Some of the things I want to explore next include:&lt;/p&gt;

&lt;p&gt;Better conversational memory&lt;br&gt;
More personalized workout guidance&lt;br&gt;
Improved voice interaction&lt;br&gt;
Better multilingual support&lt;br&gt;
Fitness progress tracking&lt;br&gt;
More natural AI conversations&lt;br&gt;
More advanced 3D character interactions&lt;br&gt;
Better mobile experience&lt;/p&gt;

&lt;p&gt;The long-term goal is to turn Titan from an AI feature into a complete AI fitness experience.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;What started as a fitness website became an experiment in combining AI, 3D graphics, voice interaction and modern web development.&lt;/p&gt;

&lt;p&gt;I'm building these projects under ASForge, where my goal is to explore and create practical AI-powered technology.&lt;/p&gt;

&lt;p&gt;Titan is just one step in that journey.&lt;/p&gt;

&lt;p&gt;If you're also building something with React, AI or Three.js, I'd love to hear about it.&lt;/p&gt;

&lt;p&gt;Keep building. Keep learning. Keep experimenting. 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>javascript</category>
      <category>threejs</category>
    </item>
  </channel>
</rss>
