<?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: Sakshi</title>
    <description>The latest articles on DEV Community by Sakshi (@sakshi_895a68fb71ade30e7c).</description>
    <link>https://dev.to/sakshi_895a68fb71ade30e7c</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3784766%2F9aac431c-bc44-482d-95be-2a93025eded5.png</url>
      <title>DEV Community: Sakshi</title>
      <link>https://dev.to/sakshi_895a68fb71ade30e7c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sakshi_895a68fb71ade30e7c"/>
    <language>en</language>
    <item>
      <title>TONETWIST</title>
      <dc:creator>Sakshi</dc:creator>
      <pubDate>Mon, 16 Mar 2026 19:07:59 +0000</pubDate>
      <link>https://dev.to/sakshi_895a68fb71ade30e7c/tonetwist-5f6g</link>
      <guid>https://dev.to/sakshi_895a68fb71ade30e7c/tonetwist-5f6g</guid>
      <description>&lt;p&gt;TONE TWIST&lt;br&gt;
I Built a Personality Rewriter — Here's What Broke (And What Didn't)&lt;br&gt;
The problem&lt;br&gt;
Translation tools are really good at translating words, but terrifying at translating personality.&lt;br&gt;
If you write a  joke in English and run it through a normal translator, the result usually sounds robotic or awkward. The meaning is actually present, but the vibe disappears.&lt;br&gt;
Most translation tools solve language. Most tone tools solve style. Nobody solves both at same time.&lt;br&gt;
That's the problem I wanted to solve.&lt;/p&gt;



&lt;p&gt;Introducing ToneTwist&lt;br&gt;
ToneTwist is a personality rewriter.&lt;br&gt;
You give it any text — an email, caption, rant, or quote — and it rewrites it through a chosen vibe:&lt;br&gt;
• Gen Z&lt;br&gt;
• Pirate&lt;br&gt;
• Shakespeare&lt;br&gt;
• Corporate&lt;br&gt;
• Boomer&lt;br&gt;
• Aussie&lt;br&gt;
Then it can translate that personality into another language without changing the vibe.&lt;br&gt;
Most tools solve translation.&lt;br&gt;
Some tools solve vibe.&lt;br&gt;
ToneTwist solves both at once.&lt;br&gt;
Live demo:&lt;br&gt;
&lt;a href="https://tonetwist-eight.vercel.app" rel="noopener noreferrer"&gt;https://tonetwist-eight.vercel.app&lt;/a&gt;&lt;br&gt;
GitHub:&lt;br&gt;
&lt;a href="https://github.com/sakshhii95/Tonetwist" rel="noopener noreferrer"&gt;https://github.com/sakshhii95/Tonetwist&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Tech Stack&lt;br&gt;
• Lingo.dev — multilingual localisation&lt;br&gt;
• Groq — LLM inference&lt;br&gt;
• Next.js 16 — framework&lt;br&gt;
• Vercel — deployment&lt;br&gt;
• Pure CSS — styling&lt;br&gt;
Responses typically return in 1–2 seconds, which makes the typing animation feel real-time. architecture&lt;br&gt;
The pipeline is intentionally simple.&lt;br&gt;
User Input&lt;br&gt;
           │&lt;br&gt;
       ▼&lt;br&gt;
 Auto Tone Detection (Groq)&lt;br&gt;
            │&lt;br&gt;
           ▼&lt;br&gt;
Personality Rewrite &lt;br&gt;
             │&lt;br&gt;
         ▼&lt;br&gt;
Translation (Lingo.dev)&lt;br&gt;
             │&lt;br&gt;
         ▼&lt;br&gt;
 Output with typing animation&lt;br&gt;
What problem does this solve?&lt;br&gt;
 I typed in sarcasm. The translator spits out a formal complaint."&lt;br&gt;
A message written in corporate English might feel cold or rude in another language.&lt;br&gt;
A joke written in Gen Z slang loses everything when translated.&lt;br&gt;
ToneTwist combines both:&lt;br&gt;
Language + Personality&lt;br&gt;
So you don't need to be:&lt;br&gt;
• a native speaker&lt;br&gt;
• a copywriter&lt;br&gt;
• a cultural translator&lt;br&gt;
all at the same time.&lt;/p&gt;



&lt;p&gt;Why Lingo.dev specifically&lt;br&gt;
Most translation APIs are based on a bag of words. They translate meaning but ignore context, tone, and vibe.&lt;br&gt;
Lingo.dev is different. The localizeText() function understands context. When I pass it a pirate-rewritten text, it doesn't just swap English words for Spanish ones — it carries the energy of the text into the translation.&lt;br&gt;
That's the key insight behind ToneTwist.&lt;br&gt;
Without Lingo.dev, the pipeline would be:&lt;br&gt;
Groq rewrites personality     →        Google Translate kills it           →         flat output&lt;br&gt;
With Lingo.dev, it becomes:&lt;br&gt;
Groq rewrites personality          →            Lingo.dev carries it     →                  personality intact&lt;/p&gt;

&lt;p&gt;Where the magic begins:&lt;br&gt;
The core pipeline lives in:&lt;br&gt;
app/api/transform/route.ts&lt;br&gt;
This function chains Groq + Lingo.dev together.&lt;br&gt;
const vibePrompt = VIBE_PROMPTS[vibe] || VIBE_PROMPTS.genz;&lt;/p&gt;

&lt;p&gt;const completion = await groq.chat.completions.create({&lt;br&gt;
  model: "llama-3.3-70b-versatile",&lt;br&gt;
  messages: [{&lt;br&gt;
    role: "user",&lt;br&gt;
    content: `${vibePrompt}&lt;/p&gt;

&lt;p&gt;Original text: "${text}"&lt;/p&gt;

&lt;p&gt;Respond with ONLY the rewritten text.`&lt;br&gt;
  }]&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;let result = completion.choices[0]?.message?.content || "Something went wrong!";&lt;/p&gt;

&lt;p&gt;if (language &amp;amp;&amp;amp; language !== "en") {&lt;br&gt;
  const lingo = new LingoDotDevEngine({&lt;br&gt;
    apiKey: process.env.LINGODOTDEV_API_KEY&lt;br&gt;
  });&lt;/p&gt;

&lt;p&gt;const translated = await lingo.localizeText(result, {&lt;br&gt;
    sourceLocale: "en",&lt;br&gt;
    targetLocale: language,&lt;br&gt;
  });&lt;/p&gt;

&lt;p&gt;result = translated || result;&lt;br&gt;
}&lt;br&gt;
Groq handles the personality rewrite.&lt;br&gt;
Lingo.dev then preserves that personality across languages.&lt;br&gt;
Neither step needs to know about the other — they're simply chained.&lt;/p&gt;



&lt;p&gt;Auto tone detection&lt;br&gt;
ToneTwist also detects the tone of your writing automatically.&lt;br&gt;
A debounced request runs 1 second after typing stops:&lt;br&gt;
useEffect(() =&amp;gt; {&lt;br&gt;
  detectTimeout.current = setTimeout(async () =&amp;gt; {&lt;br&gt;
    const res = await fetch("/api/detect", {&lt;br&gt;
      method: "POST",&lt;br&gt;
      body: JSON.stringify({ text: input })&lt;br&gt;
    });&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = await res.json();
setDetectedTone(data.tone);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}, 1000);&lt;br&gt;
}, [input]);&lt;br&gt;
If your message is sarcastic, serious, or enthusiastic, the system detects it and preserves it during the rewrite&lt;/p&gt;



&lt;p&gt;The most frustrating bug&lt;br&gt;
Vercel builds kept failing with:&lt;br&gt;
Parsing ecmascript source code failed&lt;br&gt;
Expected '&amp;lt;/', got 'ident'&lt;br&gt;
The cause?&lt;br&gt;
A nested template literal inside JSX:&lt;br&gt;
const content = &lt;code&gt;Hello\n${"─".repeat(30)}\n${output}&lt;/code&gt;;&lt;br&gt;
Turbopack couldn't parse it.&lt;br&gt;
The fix was replacing it with a simple array join:&lt;br&gt;
const divider = Array(30).fill("─").join("");&lt;br&gt;
const content = ["Hello", divider, output].join("\n");&lt;br&gt;
It took 3 hours to isolate.&lt;/p&gt;



&lt;p&gt;A feature I deleted&lt;br&gt;
The original design included a Tone Sampler:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Generate 5 tone examples&lt;/li&gt;
&lt;li&gt; Pick one&lt;/li&gt;
&lt;li&gt; Use it as input for transformation
It technically worked.
But everyone who tried it was confused.
So I removed it and replaced it with automatic tone detection.
The UX became dramatically simpler.
________________________________________
Trade-offs I accepted
Some shortcuts were intentional.
No streaming
Groq supports streaming responses, but integrating it with the typing animation would have required major refactoring.
Instead, the app fetches the full response and animates it client-side.
No persistence
Session history was removed to reduce UI clutter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run it yourself&lt;br&gt;
bash&lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/sakshhii95/Tonetwist.git" rel="noopener noreferrer"&gt;https://github.com/sakshhii95/Tonetwist.git&lt;/a&gt;&lt;br&gt;
cd Tonetwist&lt;br&gt;
npm install&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Create `.env.local`:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GROQ_API_KEY=your_groq_key&lt;br&gt;
LINGODOTDEV_API_KEY=your_lingo_key&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
npm run dev&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/h1&gt;

</description>
      <category>hackathon</category>
      <category>linodehackathon</category>
      <category>multilingual</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
