<?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: Tarun yadav</title>
    <description>The latest articles on DEV Community by Tarun yadav (@tarunyadav1).</description>
    <link>https://dev.to/tarunyadav1</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%2F371584%2F3b97e0fc-2cbb-47f9-a33b-49f68822933e.png</url>
      <title>DEV Community: Tarun yadav</title>
      <link>https://dev.to/tarunyadav1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarunyadav1"/>
    <language>en</language>
    <item>
      <title>Best TTS Voices for Narration (2026 Picks)</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Thu, 23 Apr 2026 08:31:48 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/best-tts-voices-for-narration-2026-picks-146l</link>
      <guid>https://dev.to/tarunyadav1/best-tts-voices-for-narration-2026-picks-146l</guid>
      <description>&lt;p&gt;A curated guide to choosing AI voices for audiobooks, podcasts, courses, and corporate narration. What to look for and how to audition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a Voice Is the Hardest Part
&lt;/h2&gt;

&lt;p&gt;With 860+ voices available across Murmur's model library, the paradox of choice is real. Most people audition three or four voices, pick one that sounds decent, and move on. That approach works, but spending an extra ten minutes on voice selection pays off across every project that follows. The right voice elevates your content. The wrong one distracts from it.&lt;/p&gt;

&lt;p&gt;This guide breaks down voice selection by use case. For each category, we cover what makes a voice work, what to listen for during auditions, and practical tips for getting the best results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audiobook Narration
&lt;/h2&gt;

&lt;p&gt;Audiobook listeners spend hours with a single voice. The most important quality is sustainability: a voice that remains pleasant and clear across 50,000+ words without becoming monotonous or fatiguing. Look for warm tonal quality, steady pacing, and a natural rhythm that carries across long passages.&lt;/p&gt;

&lt;p&gt;Avoid voices with excessive expressiveness for audiobook work. What sounds engaging for a 30-second demo can become exhausting over 8 hours. The best audiobook voices have a subtle dynamic range: they shift naturally with the text without calling attention to themselves.&lt;/p&gt;

&lt;p&gt;Recommended models: Fish Audio S2 Pro for premium quality, Kokoro for reliable consistency. Test with a full page (300+ words) rather than a single sentence. Speed setting: 0.95x to 1.0x.&lt;/p&gt;

&lt;h2&gt;
  
  
  Educational and Explainer Content
&lt;/h2&gt;

&lt;p&gt;Educational narration needs clarity above all else. Students are trying to absorb information, so the voice should never compete with the content for attention. Choose voices with clear diction, a moderate pace, and an authoritative but approachable tone. Think "helpful instructor" rather than "dramatic storyteller."&lt;/p&gt;

&lt;p&gt;For technical content (programming tutorials, science courses, professional development), slightly slower speeds help. A 0.9x speed setting gives listeners time to process complex information without needing to constantly pause and rewind.&lt;/p&gt;

&lt;p&gt;Recommended models: Kokoro for its consistent pacing and clarity, Qwen3 for a warmer, more conversational instructional style. Speed setting: 0.9x to 1.0x.&lt;/p&gt;

&lt;h2&gt;
  
  
  Podcast and Conversational Content
&lt;/h2&gt;

&lt;p&gt;Podcast listeners expect a conversational tone. The voice should sound natural and slightly casual, as though someone is talking to you rather than reading to you. Good podcast voices have dynamic range: they speed up slightly during exciting points, slow down for emphasis, and vary their pitch naturally.&lt;/p&gt;

&lt;p&gt;Chatterbox Turbo and Qwen3 both excel at conversational delivery. They handle the natural rhythm of speech (pauses, emphasis, tonal shifts) better than models optimized for formal narration.&lt;/p&gt;

&lt;p&gt;Recommended models: Chatterbox Turbo for energy and personality, Qwen3 for balanced warmth. Speed setting: 1.0x to 1.1x.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dramatic and Fiction Narration
&lt;/h2&gt;

&lt;p&gt;Fiction demands the widest emotional range. The narrator needs to convey tension, humor, sadness, and excitement through voice alone. This is where expressive models shine and where simpler models fall short. Listen for how a voice handles dialogue, exclamations, and quiet, introspective passages.&lt;/p&gt;

&lt;p&gt;Fish Audio S2 Pro produces the most nuanced dramatic narration. Its prosody handles the shift between description and dialogue with genuine finesse. Chatterbox adds emotional energy that works particularly well for genre fiction (thriller, romance, fantasy).&lt;/p&gt;

&lt;p&gt;Recommended models: Fish Audio S2 Pro for literary fiction, Chatterbox for genre fiction. Speed setting: 0.95x to 1.05x (vary by scene).&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentary and Corporate Narration
&lt;/h2&gt;

&lt;p&gt;Corporate and documentary narration requires professionalism and neutrality. The voice should sound trustworthy and authoritative without being cold or impersonal. Avoid anything too casual or too dramatic. The content should do the work; the voice should deliver it cleanly.&lt;/p&gt;

&lt;p&gt;Kokoro voices are the natural fit here. The model's consistent, even delivery matches the expectations of business and documentary audiences. For investor presentations, training videos, and product documentation, Kokoro's reliability is exactly what you need.&lt;/p&gt;

&lt;p&gt;Recommended models: Kokoro for professional neutrality, Qwen3 for a slightly warmer corporate tone. Speed setting: 0.95x to 1.0x.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Audition Voices Effectively
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use real content, not placeholder text. "The quick brown fox" tells you nothing about how a voice handles your actual material.&lt;/li&gt;
&lt;li&gt;Test with at least 200 words. Short samples are misleading. A voice that sparkles for one sentence may drone for one paragraph.&lt;/li&gt;
&lt;li&gt;Listen on the device your audience will use. A voice that sounds great on studio monitors may sound different through earbuds or laptop speakers.&lt;/li&gt;
&lt;li&gt;Test edge cases: numbers, acronyms, technical terms, and proper nouns that appear frequently in your content.&lt;/li&gt;
&lt;li&gt;Compare no more than 3 to 4 voices at a time. Listening to 20 voices in a row creates decision fatigue and everything starts sounding the same.&lt;/li&gt;
&lt;li&gt;Take notes. After three voices, you will forget what the first one sounded like. Write down one word for each: "warm," "crisp," "too fast," etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Voice Cloning: The Ultimate Customization
&lt;/h2&gt;

&lt;p&gt;If none of the 860+ voices quite match what you want, Murmur's voice cloning creates a voice from a 10-second recording. This is useful for authors who want their audiobook in their own voice, companies that want a branded voice, or creators who have an existing audience attached to their voice identity. The clone captures your fundamental voice characteristics and applies them to any text you generate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Will the same voice sound identical across different sessions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. TTS models are deterministic given the same input, voice, and settings. A voice that works on Monday will produce the same output on Friday. This consistency is actually an advantage over human narration, where voice quality can vary by day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do male or female voices perform better?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neither is inherently better. The quality depends on the specific voice model, not gender. Both male and female voices in Murmur's library include high-quality options. Choose based on what fits your content and audience, not assumptions about quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I find younger or older-sounding voices?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur's 860+ voice library includes voices across a range of apparent ages, from youthful and energetic to mature and authoritative. You can filter and preview to find the age quality that matches your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I maintain voice consistency across a large project?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Save your voice selection and speed settings. In Murmur, once you select a voice, it persists across generations. Use the same model, same voice, and same speed for every section of a multi-chapter or multi-episode project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I pick the most natural-sounding voice?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not always. The most natural voice might not be the most appropriate. A documentary needs authority, not just naturalness. An audiobook needs warmth and stamina. A tutorial needs clarity. Start with your use case requirements, then find the most natural voice within those constraints.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/best-tts-voices-for-narration-2026" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/best-tts-voices-for-narration-2026" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>voices</category>
      <category>narration</category>
      <category>audiobook</category>
      <category>podcast</category>
    </item>
    <item>
      <title>Japanese Text to Speech for Content Creators</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Wed, 22 Apr 2026 08:30:35 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/japanese-text-to-speech-for-content-creators-1dcn</link>
      <guid>https://dev.to/tarunyadav1/japanese-text-to-speech-for-content-creators-1dcn</guid>
      <description>&lt;p&gt;How to generate natural Japanese audio with AI. Kanji handling, pitch accent, model comparisons, and use cases from anime to business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Japanese TTS Is Uniquely Challenging
&lt;/h2&gt;

&lt;p&gt;Japanese presents challenges that most languages do not. Kanji characters can have multiple readings depending on context. The word 日 alone can be read as "hi," "nichi," "jitsu," or "ka" depending on its usage. Pitch accent (where the tone rises and falls within a word) changes meaning: 雨 (ame, rain) and 飴 (ame, candy) differ only in pitch pattern. And the distinction between formal (丁寧語), casual, and honorific (敬語) registers changes not just vocabulary but cadence and delivery.&lt;/p&gt;

&lt;p&gt;These nuances make Japanese one of the hardest languages for TTS engines to handle well. A model that sounds natural in English may produce stilted, robotic Japanese. Getting it right requires training data that captures the full range of Japanese speech patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Murmur Model Handles Japanese Best
&lt;/h2&gt;

&lt;p&gt;Kokoro has the strongest Japanese support among Murmur's models. It was trained with substantial Japanese data and handles kanji reading, pitch accent, and sentence-level intonation well. For most Japanese content creation tasks, Kokoro is the recommended choice.&lt;/p&gt;

&lt;p&gt;Qwen3 TTS also supports Japanese with good quality, and its multilingual architecture makes it the better option when you need to mix Japanese with English or other languages. The code-switching is smoother, though pure Japanese output may be slightly less natural than Kokoro's.&lt;/p&gt;

&lt;p&gt;Fish Audio S2 Pro supports Japanese but is not its primary strength. The prosody is good, but kanji reading accuracy is slightly lower than Kokoro's for complex or unusual readings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality Assessment
&lt;/h2&gt;

&lt;p&gt;We tested all three models with standard Japanese text across several registers: formal business Japanese (ビジネス日本語), casual conversational Japanese, educational content, and narrative fiction. Here is what we found:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Kokoro&lt;/th&gt;
&lt;th&gt;Qwen3 TTS&lt;/th&gt;
&lt;th&gt;Fish Audio S2 Pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Use Cases for Japanese TTS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Educational Content and Language Learning
&lt;/h3&gt;

&lt;p&gt;Language educators and app developers use Japanese TTS to generate example sentences, vocabulary pronunciations, and listening comprehension exercises. Kokoro's accurate pitch accent makes it particularly valuable here, since pitch accent is one of the hardest aspects of Japanese for learners to acquire. Generating audio for hundreds of example sentences would take hours to record manually but minutes with TTS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Business and Corporate Presentations
&lt;/h3&gt;

&lt;p&gt;Japanese business content often contains sensitive corporate information: earnings reports, strategy documents, internal training materials. The privacy angle is especially relevant here. Sending confidential Japanese business text to a cloud TTS service means that data passes through external servers, potentially in jurisdictions with different data protection laws. Murmur processes everything locally, keeping your corporate content on your machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anime-Style Content and Creative Projects
&lt;/h3&gt;

&lt;p&gt;Creators producing anime-inspired content, visual novels, manga narration, or Japanese-language YouTube videos use TTS to generate dialogue and narration. Chatterbox's emotional range works well for dramatic or character-driven content. For more neutral narration (documentary style, explainers), Kokoro's consistent delivery is the better fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for Better Japanese TTS Output
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use furigana or hiragana for unusual kanji readings. If a kanji has a rare or name-specific reading, spell it out in hiragana to ensure correct pronunciation.&lt;/li&gt;
&lt;li&gt;Include proper punctuation (。、「」) in your Japanese text. TTS models use these marks to determine pausing and intonation patterns.&lt;/li&gt;
&lt;li&gt;For mixed Japanese/English content, use Qwen3 TTS. Write English words in katakana only if you want them pronounced with Japanese phonology. Leave them in English for natural English pronunciation.&lt;/li&gt;
&lt;li&gt;Test with sentences that contain homophone kanji (like 橋/箸, hashi) to verify the model handles context-dependent readings correctly.&lt;/li&gt;
&lt;li&gt;For formal content, use polite form (です/ます) consistently. Mixing registers within a passage can confuse the model's delivery style.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How accurate is the kanji pronunciation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kokoro handles common and moderately complex kanji readings well. Very rare readings, name-specific kanji, or highly context-dependent characters may occasionally be misread. For critical content, test-generate and listen. You can always add furigana (hiragana readings) to guide pronunciation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I generate both formal and casual Japanese?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The register is primarily determined by the text you input. Write in polite form (です/ます) for formal output, plain form (だ/である) for casual. The TTS model adjusts its delivery style based on the text's register.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does this compare to Google Cloud TTS for Japanese?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Google Cloud TTS for Japanese is solid, with good kanji reading and natural prosody. Kokoro in Murmur is comparable in quality for most use cases. The key difference is privacy (local vs cloud) and pricing (one-time vs per-character). For high-volume Japanese content, Murmur's unlimited generation is a significant cost advantage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I mix Japanese with English naturally?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Qwen3 TTS handles Japanese/English code-switching best. It maintains natural pronunciation in both languages within the same passage. Kokoro handles it adequately but with slightly more noticeable transitions between languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the quality good enough for professional Japanese content?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For educational materials, corporate presentations, and narrative content, yes. For broadcast or entertainment where the highest possible naturalness is required, you may want to compare output with a native speaker recording. The gap is smaller than you might expect.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/japanese-text-to-speech" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/japanese-text-to-speech" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>japanese</category>
      <category>language</category>
      <category>multilingual</category>
      <category>kokoro</category>
    </item>
    <item>
      <title>Spanish Text to Speech: Best Voices and Models</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Tue, 21 Apr 2026 08:32:01 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/spanish-text-to-speech-best-voices-and-models-204b</link>
      <guid>https://dev.to/tarunyadav1/spanish-text-to-speech-best-voices-and-models-204b</guid>
      <description>&lt;p&gt;A guide to generating natural Spanish audio with AI. Model comparisons, accent options, and tips for mixed English/Spanish content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spanish TTS in 2026
&lt;/h2&gt;

&lt;p&gt;Spanish is the fourth most spoken language in the world, with over 500 million native speakers. For content creators, marketers, and educators producing Spanish-language material, quality text-to-speech is essential. But until recently, most TTS engines treated Spanish as an afterthought, offering a handful of robotic voices that sounded nothing like natural speech.&lt;/p&gt;

&lt;p&gt;That has changed. Several open-source models now produce Spanish audio that sounds genuinely natural, with proper intonation, rhythm, and pronunciation. Murmur bundles three models that support Spanish: Kokoro, Qwen3 TTS, and Fish Audio S2 Pro. Each handles the language differently, and the best choice depends on your specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Models Support Spanish
&lt;/h2&gt;

&lt;p&gt;Kokoro supports Spanish as one of its 9 languages. The output is clean, consistent, and well-paced. It handles both Latin American and Castilian pronunciation patterns depending on the voice selected. For straightforward narration (blogs, documentation, educational content), Kokoro is the reliable default.&lt;/p&gt;

&lt;p&gt;Qwen3 TTS brings the strongest multilingual capability. Its code-switching ability is particularly valuable for Spanish content that includes English terms (common in tech, business, and marketing). A sentence that mixes "el nuevo framework de machine learning" flows naturally without the jarring accent shifts you hear from single-language models.&lt;/p&gt;

&lt;p&gt;Fish Audio S2 Pro produces the most natural-sounding Spanish speech overall. The prosody is excellent, with pauses and emphasis that match how native speakers actually talk. The tradeoff is generation speed: Fish Audio takes 2 to 3 minutes per 1,500 words compared to Kokoro's 30 to 45 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regional Accent Considerations
&lt;/h2&gt;

&lt;p&gt;Spanish varies significantly by region. Castilian Spanish (Spain) features the distinctive "theta" sound for c/z, different vocabulary choices, and particular rhythmic patterns. Latin American Spanish encompasses its own regional variations, from Mexican Spanish to Argentine Spanish to Caribbean dialects.&lt;/p&gt;

&lt;p&gt;In Murmur, the accent is primarily determined by the voice you select. Voices trained on Latin American Spanish data will produce Latin American pronunciation. Castilian voices will produce Castilian pronunciation. When selecting a voice, listen to a sample that includes words with c, z, and ll to quickly identify the regional accent.&lt;/p&gt;

&lt;p&gt;For international audiences, neutral Latin American Spanish (similar to Mexican broadcast Spanish) is generally the safest choice. It is understood across all Spanish-speaking regions and avoids strongly regional features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison: Murmur vs Cloud Services for Spanish
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Murmur&lt;/th&gt;
&lt;th&gt;Google Cloud TTS&lt;/th&gt;
&lt;th&gt;ElevenLabs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Privacy for Business Spanish Content
&lt;/h2&gt;

&lt;p&gt;One often-overlooked advantage of local TTS: privacy for sensitive content. Business documents, legal contracts, financial reports, and internal communications in Spanish often contain confidential information. With cloud TTS services, every word is sent to external servers for processing.&lt;/p&gt;

&lt;p&gt;Murmur processes everything locally on your Mac. For legal firms handling Spanish-language contracts, healthcare providers creating patient materials, or businesses producing internal training in Spanish, this is not just a convenience. It is a compliance requirement in many jurisdictions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for Better Spanish TTS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Include proper accent marks (tildes, acute accents) in your text. TTS models use these to determine correct pronunciation. "ano" and "año" are very different words.&lt;/li&gt;
&lt;li&gt;For mixed English/Spanish content, use Qwen3 TTS. Its code-switching capability handles language transitions more naturally than other models.&lt;/li&gt;
&lt;li&gt;Test inverted question marks and exclamation marks (¿ ¡). Some models use these as intonation cues to adjust pitch at the beginning of a sentence.&lt;/li&gt;
&lt;li&gt;For numbers and dates, write them out in Spanish. "15 de abril de 2026" rather than "4/15/2026" to avoid ambiguous formatting.&lt;/li&gt;
&lt;li&gt;Slow the speed slightly (0.95x) for educational or formal content. Spanish has a naturally faster syllable rate than English, and slowing down improves clarity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I choose between Latin American and Castilian Spanish?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The accent depends on the voice you select. Murmur's voice library includes both Latin American and Castilian Spanish voices. Preview a voice with a test sentence that includes distinguishing sounds (like "cerveza" or "Barcelona") to identify the accent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does Murmur handle accented characters?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur's models read accented characters (á, é, í, ó, ú, ñ, ü) correctly and use them for pronunciation. Always include proper diacritics in your text for the best results. Missing accents can cause mispronunciation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the Spanish quality as good as the English?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;English is the primary training language for most models, so English output tends to be slightly more natural. That said, Spanish quality from Fish Audio and Qwen3 is very good and suitable for professional use. The gap has narrowed significantly in 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I mix Spanish and English in the same passage?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, and Qwen3 TTS handles this best. It was specifically designed for multilingual and code-switching scenarios. Kokoro and Fish Audio also handle mixed content, though transitions between languages may be slightly less smooth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about other Spanish-related languages like Catalan or Galician?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur does not officially support Catalan or Galician as separate languages. Some models may produce reasonable output for text in these languages due to their similarity to Spanish, but results will be inconsistent. For dedicated Catalan or Galician TTS, specialized tools are a better choice.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/spanish-text-to-speech" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/spanish-text-to-speech" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>language</category>
      <category>multilingual</category>
      <category>tts</category>
    </item>
    <item>
      <title>How to Create an AI Audiobook (Full Workflow)</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Mon, 20 Apr 2026 08:40:44 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/how-to-create-an-ai-audiobook-full-workflow-4eh0</link>
      <guid>https://dev.to/tarunyadav1/how-to-create-an-ai-audiobook-full-workflow-4eh0</guid>
      <description>&lt;p&gt;From manuscript to finished audiobook: a complete guide to producing audiobooks with AI text-to-speech, including ACX/Audible specs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Traditional Audiobook Problem
&lt;/h2&gt;

&lt;p&gt;Producing an audiobook the traditional way is a significant investment. A 10-hour audiobook (roughly 80,000 words) requires 40+ hours of studio time for recording and editing. Professional narrators charge $200 to $400 per finished hour, putting the total cost between $2,000 and $4,000 for a typical novel. Add studio rental, mastering, and quality control, and you can easily reach $5,000+.&lt;/p&gt;

&lt;p&gt;For indie authors who have already spent months writing their book, that cost is often prohibitive. Many books never become audiobooks simply because the economics do not work for titles that might sell a few hundred copies.&lt;/p&gt;

&lt;p&gt;AI text-to-speech changes the math. With Murmur, you can generate a full audiobook on your Mac for the cost of the software ($49). The process takes hours instead of weeks, and you can iterate, re-generate, and update chapters at will.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Prepare Your Manuscript
&lt;/h2&gt;

&lt;p&gt;Good audiobook production starts with good source text. Your manuscript needs specific preparation before TTS generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove all formatting. Bold, italic, headers, and footnotes should be stripped. The TTS engine reads plain text.&lt;/li&gt;
&lt;li&gt;Split into chapter files. One text file per chapter keeps your project organized and makes regeneration easier.&lt;/li&gt;
&lt;li&gt;Handle dialogue tags explicitly. Instead of relying on quotation marks alone, ensure "said" tags are present so the voice engine can adjust delivery.&lt;/li&gt;
&lt;li&gt;Spell out numbers, abbreviations, and special characters. "$2.5M" should become "two and a half million dollars." "Dr." should become "Doctor."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Choose Your Narrator Voice
&lt;/h2&gt;

&lt;p&gt;For an audiobook, voice consistency is everything. Listeners will spend 6 to 12 hours with this voice. It needs to be pleasant, clear, and sustainable across long passages. In Murmur, audition voices with a full page of text, not just a sentence. A voice that sounds great for 10 seconds might become fatiguing after 10 minutes.&lt;/p&gt;

&lt;p&gt;For non-fiction, choose a voice with authority and clarity. Kokoro voices excel here because they maintain consistent pacing and tone. For fiction, you want more expressiveness. Fish Audio S2 Pro produces the most natural prosody, handling dialogue and description shifts with genuine nuance. Chatterbox adds emotional range that works well for dramatic fiction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Voice Cloning Option
&lt;/h3&gt;

&lt;p&gt;If you want the audiobook in your own voice (author-narrated books sell well), Murmur's voice cloning feature lets you create a voice profile from a 10-second recording. The clone captures your pitch, timbre, and speaking rhythm. It will not be an exact replica, but it will be recognizably you. This gives you the personal touch of self-narration without the 40+ hours of recording.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Generate Chapter by Chapter
&lt;/h2&gt;

&lt;p&gt;Work through your book one chapter at a time. For each chapter: paste the text, verify the voice and speed settings match your previous chapters, generate, and listen to the first minute. If it sounds right, export and move to the next chapter. If a section sounds off (mispronunciation, odd pacing), edit that portion of the script and regenerate just that chapter.&lt;/p&gt;

&lt;p&gt;For a 10-hour audiobook, expect the generation process to take a few hours on Apple Silicon hardware. Kokoro generates fastest (30 to 45 seconds per 1,500 words). Fish Audio S2 Pro takes longer (2 to 3 minutes per 1,500 words) but produces more polished output. Choose based on your quality requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Review and Polish
&lt;/h2&gt;

&lt;p&gt;Listen to each chapter fully. Mark timestamps where you hear issues: mispronunciations, awkward pauses, unnatural emphasis. For most chapters, the output will be clean. For problem sections, adjust the script text (rephrase a sentence, add a comma for a pause, spell out a tricky word) and regenerate that chapter.&lt;/p&gt;

&lt;p&gt;After all chapters pass review, normalize the volume across all files. Audio editing tools like Audacity (free) can batch-process volume normalization. This ensures chapter 1 is not noticeably louder or quieter than chapter 20.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Meet ACX/Audible Technical Specs
&lt;/h2&gt;

&lt;p&gt;If you plan to distribute through ACX (Amazon's audiobook platform for Audible), your files must meet specific technical requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Format: MP3 at 192kbps CBR (constant bit rate) or WAV at 44.1kHz.&lt;/li&gt;
&lt;li&gt;Each chapter must be a separate file, named sequentially.&lt;/li&gt;
&lt;li&gt;Peak volume: must not exceed -3dB.&lt;/li&gt;
&lt;li&gt;RMS (average volume): between -23dB and -18dB.&lt;/li&gt;
&lt;li&gt;Noise floor: below -60dB.&lt;/li&gt;
&lt;li&gt;Each file must have 0.5 to 1 second of room tone (silence) at the beginning and 1 to 5 seconds at the end.&lt;/li&gt;
&lt;li&gt;Opening credits file: must include the book title, author name, and narrator credit.&lt;/li&gt;
&lt;li&gt;Closing credits file: must include an end-of-book announcement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Murmur exports clean WAV files that meet the sample rate and format requirements. Volume normalization and room tone can be added in Audacity using its built-in tools. The ACX Check plugin for Audacity can verify all technical specs before submission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timeline Comparison
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Traditional audiobook recording: 40+ hours for a 10-hour book. AI generation with Murmur: a few hours of generation plus review time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The timeline difference is dramatic. A traditional 10-hour audiobook requires 40+ hours of recording, 20+ hours of editing, and weeks of back-and-forth with narrators and engineers. With AI generation, you can go from manuscript to finished audiobook in a weekend. The actual generation takes a few hours. The bulk of your time goes to review and quality checking, which is the part that should take time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does ACX accept AI-narrated audiobooks?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ACX updated its policies in 2024 to require disclosure of AI-generated narration. AI-narrated books are accepted but must be labeled accordingly. The technical quality standards (audio specs, consistency, clarity) still apply regardless of how the narration was produced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is AI narration good enough for fiction?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For single-narrator fiction (most novels), modern TTS handles the job well. Models like Fish Audio S2 Pro and Chatterbox deliver natural prosody and emotional range. Multi-character fiction with distinct character voices is more challenging. You can use different voices for dialogue sections, but this requires more editing work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I handle character dialogue in fiction?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The simplest approach is single-narrator style, where one voice reads everything including dialogue. This is how most human-narrated audiobooks work. For distinct character voices, you can generate dialogue sections with different Murmur voices and splice them together in an audio editor. This takes more effort but creates a more immersive experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about non-fiction vs fiction quality?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI narration works exceptionally well for non-fiction: memoirs, self-help, business books, guides. The consistent, clear delivery suits informational content. Fiction requires more emotional range, which models like Chatterbox and Fish Audio provide, but the quality ceiling is slightly lower than for non-fiction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I sell the audiobook commercially?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Murmur's license covers commercial use of generated audio. You retain full rights to your audiobook. Distribute on ACX/Audible, sell directly, or use any other distribution channel.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/how-to-create-ai-audiobook" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/how-to-create-ai-audiobook" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>audiobook</category>
      <category>tutorial</category>
      <category>acx</category>
      <category>audible</category>
    </item>
    <item>
      <title>Murmur vs Speechify: Which TTS Is Better for Creators?</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Tue, 14 Apr 2026 08:29:40 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/murmur-vs-speechify-which-tts-is-better-for-creators-clj</link>
      <guid>https://dev.to/tarunyadav1/murmur-vs-speechify-which-tts-is-better-for-creators-clj</guid>
      <description>&lt;p&gt;A practical comparison of Murmur and Speechify for content creators who need text-to-speech on Mac.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Different Tools for Two Different Jobs
&lt;/h2&gt;

&lt;p&gt;Murmur and Speechify both convert text to speech, but they solve different problems. Comparing them directly is a bit like comparing a camera to a projector: both involve images, but the workflows point in opposite directions. Understanding this distinction will save you from buying the wrong tool.&lt;/p&gt;

&lt;p&gt;Speechify is primarily a reading and listening tool. It reads web pages, PDFs, emails, and documents aloud so you can consume content by ear instead of by eye. It is built for people who want to listen to existing content while commuting, exercising, or multitasking. The output is real-time audio playback, not exported files.&lt;/p&gt;

&lt;p&gt;Murmur is a production tool. It takes text and generates audio files that you save, edit, and publish. It is built for creators who need to produce voiceovers, narrations, and audio content that other people will listen to. The output is WAV files you import into video editors, audiobook platforms, and podcast feeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Speechify Wins
&lt;/h2&gt;

&lt;p&gt;Speechify is excellent at what it does. The browser extension lets you highlight any web page and hear it read aloud instantly. The Chrome integration is smooth. The mobile app works on iOS and Android, meaning you can listen to articles on your phone during a commute. Speed reading features let you consume content at 2x, 3x, or even 4x normal pace.&lt;/p&gt;

&lt;p&gt;If your primary need is consuming content by ear (reading articles, reviewing documents, studying), Speechify is the better choice. Murmur is not designed for that use case. It does not have a browser extension, does not work on mobile, and is not optimized for real-time playback of web content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Murmur Wins
&lt;/h2&gt;

&lt;p&gt;For content creation, the comparison tilts heavily toward Murmur. Speechify's audio export options are limited and locked behind its highest tier. Murmur is built entirely around generating and exporting audio. You get multiple AI models (Kokoro, Qwen3, Fish Audio, Chatterbox), 860+ voices, voice cloning from a 10-second sample, speed control, and batch processing for long documents.&lt;/p&gt;

&lt;p&gt;Privacy is another differentiator. Murmur runs entirely on your Mac. Your text never leaves your machine. Speechify processes everything through its cloud servers. For creators working with unpublished manuscripts, client content, or sensitive material, local processing matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-Side Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Murmur&lt;/th&gt;
&lt;th&gt;Speechify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Pricing Difference
&lt;/h2&gt;

&lt;p&gt;Speechify charges $139 per year for its Premium plan. That is $11.58 per month. Over two years, you will have paid $278. Over three years, $417. The free tier is severely limited, capping you at a few minutes of standard-quality voice playback per day.&lt;/p&gt;

&lt;p&gt;Murmur is $49 once. No renewal, no tiers, no usage caps. After roughly four months of Speechify Premium, you have already spent more than Murmur's lifetime price. If your need is audio production rather than content consumption, the value proposition is straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Should Choose What
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Primarily want to listen to web articles, PDFs, and documents&lt;/li&gt;
&lt;li&gt;Need a mobile app for on-the-go listening&lt;/li&gt;
&lt;li&gt;Value browser integration for instant read-aloud&lt;/li&gt;
&lt;li&gt;Use speed reading features to consume content faster&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work across multiple platforms (Windows, iOS, Android)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Need to produce and export audio files (voiceovers, narrations, audiobooks)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Want multiple AI voice models to choose from&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Need voice cloning for a personal or brand voice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle sensitive or unpublished content that should not go to the cloud&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Want to pay once instead of subscribing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work primarily on a Mac with Apple Silicon&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can Speechify export audio files like Murmur?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Speechify has limited audio export on its highest-tier plan. It is not designed as a production tool. If you need to regularly export audio files for videos, podcasts, or audiobooks, Murmur is the better fit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Murmur read web pages aloud like Speechify?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Murmur does not have a browser extension or real-time web reading feature. You paste or import text into the app, generate audio, and export. It is a production workflow, not a reading assistant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need both tools?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some creators use both. Speechify for consuming research material by ear, Murmur for producing the final audio content. They serve different parts of the content workflow and do not overlap much.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Speechify's voice quality better than Murmur's?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Speechify's voices are optimized for real-time playback at high speeds. Murmur's models are optimized for natural-sounding generated audio. For production quality, Murmur has the edge with multiple specialized models. For quick read-aloud, Speechify is smooth and responsive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Murmur work on iPad or iPhone?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Murmur is a native macOS app that requires Apple Silicon (M1 or later). It relies on MLX for local model inference, which is not available on iOS. Speechify is the better option if you need mobile access.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/murmur-vs-speechify" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/murmur-vs-speechify" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>speechify</category>
      <category>comparison</category>
      <category>tts</category>
      <category>creators</category>
    </item>
    <item>
      <title>AI Voiceover for YouTube: No Subscription Required</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Mon, 13 Apr 2026 08:37:47 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/ai-voiceover-for-youtube-no-subscription-required-43jh</link>
      <guid>https://dev.to/tarunyadav1/ai-voiceover-for-youtube-no-subscription-required-43jh</guid>
      <description>&lt;p&gt;How YouTube creators generate voiceovers locally on their Mac without paying monthly fees or uploading scripts to the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Voiceover Problem for YouTube Creators
&lt;/h2&gt;

&lt;p&gt;Faceless YouTube channels are everywhere. Finance explainers, tech tutorials, true crime compilations, history deep dives. They pull millions of views without ever showing a face. What they all need is a consistent, engaging voice. And for most creators, the voice question is the biggest production bottleneck.&lt;/p&gt;

&lt;p&gt;Recording your own voiceover works, but it demands a quiet room, decent microphone, and the willingness to re-record when you stumble over a line. Hiring voice talent costs $50 to $200 per video and adds days to your production timeline. Cloud TTS services like ElevenLabs or Play.ht solve the quality problem but introduce monthly bills that eat into ad revenue, especially when you are publishing 8 to 12 videos per month.&lt;/p&gt;

&lt;p&gt;There is a better approach for Mac users: generate voiceovers locally, with no subscription, no upload, and no per-minute billing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Script to Voiceover in Minutes
&lt;/h2&gt;

&lt;p&gt;The workflow is simple. Write your script (or paste it from your doc), choose a voice, adjust the speed, and hit generate. Murmur produces a WAV file that you drag directly into your video editor. The entire process takes a few minutes for a typical 10-minute video script.&lt;/p&gt;

&lt;p&gt;Speed control matters for YouTube. Educational content works best at 1.0x to 1.1x, giving viewers time to absorb information. Dramatic or storytelling content benefits from 0.9x, where pauses feel intentional. Fast-paced commentary or list videos can push to 1.2x without sounding rushed. You can preview different speeds before committing to a full generation.&lt;/p&gt;

&lt;p&gt;Choosing the right voice for your channel is an underrated decision. Your voice becomes your brand. Viewers associate it with your content, and switching voices mid-series is jarring. Murmur's 860+ voice library lets you audition options before committing. Once you pick one, every video sounds consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will Viewers Notice It Is AI?
&lt;/h2&gt;

&lt;p&gt;This is the question everyone asks. The honest answer: some will, most will not. YouTube audiences have grown accustomed to AI voices. Channels with millions of subscribers use them openly. The threshold is not "does it sound perfectly human" but "does it sound good enough that viewers stay and watch." In 2026, local TTS models clear that bar comfortably for most content categories.&lt;/p&gt;

&lt;p&gt;Context matters too. A tech tutorial with screen recordings and a clear AI voice is perfectly fine. A personal vlog where emotional authenticity matters, less so. Know your genre. Faceless educational, financial, and informational channels are the sweet spot for AI voiceover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free Cloud Tools vs. Paid Cloud vs. Murmur
&lt;/h2&gt;

&lt;p&gt;Free cloud TTS tools exist, but they come with strings. Most add watermarks, limit generation length, or restrict commercial use. Google's TTS API is technically free at low volumes but sounds robotic. Free tiers from ElevenLabs and Play.ht cap you at a few thousand characters per month, not enough for even one video script.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Free Cloud TTS&lt;/th&gt;
&lt;th&gt;Paid Cloud (ElevenLabs)&lt;/th&gt;
&lt;th&gt;Murmur&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are publishing regularly, the math favors a one-time purchase. Even the cheapest ElevenLabs plan ($5/month) costs $60/year. Their Starter plan at $5/month limits you to 30,000 characters, roughly one or two video scripts. Serious creators need the $22/month Creator plan at minimum, which totals $264/year. Murmur pays for itself in 2 to 3 months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch Export and Workflow Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Write your full script first, then generate audio in one pass. Generating paragraph by paragraph creates inconsistent pacing.&lt;/li&gt;
&lt;li&gt;Use voice cloning to create a unique channel voice that no other creator has. Record 10 seconds in a quiet room and let Murmur build a voice model from it.&lt;/li&gt;
&lt;li&gt;Export as WAV for maximum quality in your editor. Convert to MP3 only for final distribution if needed.&lt;/li&gt;
&lt;li&gt;Generate at 1.0x speed, then adjust playback speed in your video editor for finer control.&lt;/li&gt;
&lt;li&gt;Keep a consistent voice across your entire channel. Switching voices between videos confuses returning viewers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I use AI-generated voiceovers commercially on YouTube?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Murmur's license permits commercial use of all generated audio. You own the output. There are no royalty fees or attribution requirements for the audio you generate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use different voices for different characters in one video?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Generate each character's lines separately with a different voice, then layer them in your video editor. This works well for explainer videos with a narrator and quoted sources, or for storytelling channels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does the quality compare to hiring a voice actor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A skilled voice actor still delivers more nuanced performance, especially for emotional content. But for informational, educational, and list-style videos, AI voiceover is comparable in quality and dramatically faster and cheaper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What file format does Murmur export?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur exports WAV files at 24kHz. WAV is lossless and works with every major video editor including Final Cut Pro, DaVinci Resolve, Premiere Pro, and CapCut.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to disclose that I use AI voiceover?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;YouTube's policies require disclosure of synthetic media in some contexts. Check YouTube's current creator guidelines for AI-generated content. Many successful channels disclose AI use in their descriptions without any negative impact on views.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/ai-voiceover-youtube-no-subscription" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/ai-voiceover-youtube-no-subscription" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>youtube</category>
      <category>voiceover</category>
      <category>creators</category>
      <category>tts</category>
    </item>
    <item>
      <title>Murmur vs ElevenLabs: Why Creators Are Switching to Local TTS</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Fri, 10 Apr 2026 07:22:56 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/murmur-vs-elevenlabs-why-creators-are-switching-to-local-tts-3enl</link>
      <guid>https://dev.to/tarunyadav1/murmur-vs-elevenlabs-why-creators-are-switching-to-local-tts-3enl</guid>
      <description>&lt;p&gt;A detailed comparison of Murmur and ElevenLabs for text-to-speech. Price, privacy, quality, and offline support: everything creators need to know before choosing a TTS tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cloud TTS Problem
&lt;/h2&gt;

&lt;p&gt;ElevenLabs built an impressive product. Their voice quality set a new standard for AI-generated speech, and they deserve credit for pushing the field forward. But their business model has a fundamental tension with how most creators actually use text-to-speech.&lt;/p&gt;

&lt;p&gt;The pricing starts at $5/month for a limited hobby tier and scales to $99/month for the Pro plan most serious creators need. That's $1,188 per year. And if you're on a team or need higher limits, you're looking at $330/month, nearly $4,000 annually. Every character you generate counts against your quota. Run out mid-project, and you're either waiting until next month or upgrading your plan.&lt;/p&gt;

&lt;p&gt;Then there's the privacy question. Every word you type gets sent to ElevenLabs' servers for processing. For published blog posts, that might not matter. But creators also generate audio for unpublished drafts, client work, legal documents, medical content, and personal projects. All of that text passes through a third-party cloud before you hear a single word.&lt;/p&gt;

&lt;p&gt;Cloud TTS also means cloud dependencies. No internet, no audio. Spotty cafe Wi-Fi, degraded experience. API outage, dead in the water. For creators who travel, work remotely, or simply value reliability, this is a real constraint.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Murmur Is Different
&lt;/h2&gt;

&lt;p&gt;Murmur takes a fundamentally different approach. Instead of renting access to a cloud model, you run the model on your own hardware. The Kokoro TTS engine (82 million parameters) runs directly on Apple Silicon using MLX, Apple's machine learning framework. Your text never leaves your Mac.&lt;/p&gt;

&lt;p&gt;You pay $49 once. That's it. No monthly fees, no per-character billing, no usage caps. Generate ten narrations or ten thousand, the price doesn't change. There's no account dashboard tracking your remaining credits, no surprise overage charges, no annual renewal.&lt;/p&gt;

&lt;p&gt;Because everything runs locally, Murmur works offline. On a plane, in a cabin, at a conference with overloaded Wi-Fi. It doesn't matter. Once the app is set up, you don't need the internet at all. Your text stays on your machine, your audio stays on your machine, and there's no third party in the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-Side Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Murmur&lt;/th&gt;
&lt;th&gt;ElevenLabs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;ElevenLabs has clear advantages in generation speed, language coverage, and cross-platform availability. If you need 30+ languages, work primarily on Windows or Linux, or require the fastest possible generation times, ElevenLabs is the better fit.&lt;/p&gt;

&lt;p&gt;But if you're a creator on a Mac who values privacy, wants predictable costs, and generates audio regularly, Murmur's model makes more sense. You're trading some speed and language breadth for permanent ownership and zero recurring costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio Quality Comparison
&lt;/h2&gt;

&lt;p&gt;The most common question we get: does Murmur actually sound good? Rather than making claims, here are samples generated with Murmur so you can judge for yourself. These are unedited outputs, no post-processing, no cherry-picking.&lt;/p&gt;

&lt;p&gt;Each sample above was generated by a different AI model, all running locally inside Murmur. No cloud processing, no post-production. Qwen3 excels at natural narration, Fish Audio delivers studio-quality expressiveness, and Chatterbox adds emotional depth. You get all of them for $49.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Math
&lt;/h2&gt;

&lt;p&gt;Drag the slider to see how costs compare over 12 months based on your usage. ElevenLabs charges per character, so more audio means higher tiers. Murmur stays at $49 no matter what.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Should Switch?
&lt;/h2&gt;

&lt;p&gt;Not everyone should switch. If you need 30+ languages, work on Windows, or depend on ElevenLabs' API for production workflows, stay where you are. The right tool depends on your specific needs.&lt;/p&gt;

&lt;p&gt;But if the following sounds like you, Murmur is worth a serious look:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audiobook authors and narrators who generate high volumes of audio and are tired of per-character billing eating into margins.&lt;/li&gt;
&lt;li&gt;YouTubers and video creators who need voiceovers for explainers, tutorials, or channel content and want a faster workflow than cloud round-trips.&lt;/li&gt;
&lt;li&gt;Podcasters who want to convert written content into spoken episodes without recording themselves or hiring voice talent.&lt;/li&gt;
&lt;li&gt;Course creators and educators who turn lesson scripts, study guides, and documentation into audio modules for students.&lt;/li&gt;
&lt;li&gt;Newsletter writers and bloggers who want to add audio versions of their posts without a monthly subscription.&lt;/li&gt;
&lt;li&gt;Anyone who handles sensitive content (legal, medical, financial, or confidential client work) and can't afford to send text through third-party servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can Murmur match ElevenLabs' voice quality?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For most creator use cases like blog narration, video voiceovers, and course content, the quality is comparable. ElevenLabs has an edge in voice cloning fidelity and emotional range at the extremes, but Kokoro's 82M parameter model produces natural, expressive speech that works well for long-form content. Listen to the samples above and decide for yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Murmur work completely offline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. After the initial setup (which downloads the Kokoro TTS model), Murmur runs entirely on your Mac with no internet connection required. Your text never touches a server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many voices does Murmur have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur ships with 860+ community voices spanning different genders, ages, accents, and styles. You can also clone your own voice from a 10-second recording.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What languages does Murmur support?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Murmur currently supports 9 languages: English, Spanish, French, German, Italian, Portuguese, Japanese, Chinese, and Korean. ElevenLabs supports 30+, so if you need broad multilingual coverage, that's a consideration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use Murmur on Windows or Linux?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not currently. Murmur is a native macOS app that requires Apple Silicon (M1 or later). It uses Apple's MLX framework for hardware-accelerated inference, which is Mac-only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a money-back guarantee?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Murmur comes with a 7-day refund policy. If it doesn't work for your use case, you get your money back.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.murmurtts.com/blog/murmur-vs-elevenlabs" rel="noopener noreferrer"&gt;Try Murmur&lt;/a&gt;&lt;/strong&gt; - $49 one-time. No subscriptions, no cloud, no per-character fees.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://www.murmurtts.com/blog/murmur-vs-elevenlabs" rel="noopener noreferrer"&gt;murmurtts.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>elevenlabs</category>
      <category>comparison</category>
      <category>tts</category>
      <category>local</category>
    </item>
    <item>
      <title>Step-By-Step Guide to Stripe Payments in React</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Sun, 28 Jun 2020 02:24:04 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/step-by-step-guide-to-stripe-payments-in-react-577h</link>
      <guid>https://dev.to/tarunyadav1/step-by-step-guide-to-stripe-payments-in-react-577h</guid>
      <description>&lt;h2&gt;
  
  
  What We’ll Cover
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Replace Checkout.js with Stripe.js&lt;/li&gt;
&lt;li&gt;  Removing the Checkout.js button&lt;/li&gt;
&lt;li&gt;  Adding required Stripe fields&lt;/li&gt;
&lt;li&gt;  Integration the form action with Stripe.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you first build a Stripe integration, the advantage of Checkout.js over Stripe.js is its ease of integration and speed to a working app. However, it does not allow adding any additional input fields. In many situations, you'll want to collect other values such as Quantity, a drop down of products, shipping address, etc, and submit it with the same form that collects payment details. Or perhaps, you really just want a uniform style with the rest of your app that doesn't require a modal dialog to popup. Stripe’s smaller frontend library, called Stripe.js, does not include any UI elements but has all of the client side API functionality of generating payment tokens. Customizing the payment form will require no changes to the backend functionality of your Node.js app, because the front end will still be generating the same payment token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Brief Overview of Checkout.js Functionality
&lt;/h2&gt;

&lt;p&gt;If you've never integrated Stripe before, or it's been a while since you've done it, let's review just what the purpose is of the front end portion of Stripe! Stripe is an API as a Service, so your first question may be, "Why on earth does an API require the use of a front-end JavaScript library?" Great question! As you can imagine, handling your users' credit card information online is a potentially risky business - which is exactly why there is a security standard that you must adhere to in order to accept payments online. The Payment Card Industry Digital Security Standards (or PCI DSS, commonly just referred to as PCI for short), explicitly prohibits direct storing of credit card numbers by merchants - unless you are up to the task of "protecting stored cardholder data." Stripe's ingenuity was to build a simple front end mechanism that collects the cardholder payment data on your behalf so that it never even touches your server - &lt;strong&gt;making PCI-DSS compliance much easier&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Checkout.js bundles the cardholder data collection mechanism with a beautiful and easy to integrate modal popup form that collects that payment details from the user. This is a fantastic option for putting together a very quick Stripe integration, but will not seamlessly flow with the rest of your user interface. This is where Stripe.js come into play. The API still offers JavaScript methods for sending the payment details directly to Stripe, and receiving a payment token to represent the payment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Stripe.js
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://stripe.com/docs/custom-form"&gt;Stripe documentation lists&lt;/a&gt; provides a Script tag that loads Stripe.js with the latest version. It may be tempting to install the Script with Bower by running &lt;code&gt;bower install --save stripe.js=https://js.stripe.com/v2/&lt;/code&gt;, but keep in mind doing this is not officially endorsed by Stripe. There is no mention as to how often they update the client side libraries, so something may break on you unexpectedly. So your first option is to simply load the library by placing the Stripe provided script tag in the HTML file that your React app is mounted in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
               &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://js.stripe.com/v2/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin: 0px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"react-bundle.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;em&gt;much&lt;/em&gt; better option would be to dynamically load this script with ReactScriptLoader! Considering a React app is a Single Page App, there are likely huge chunks of your app that do not have a payment form. Why load Stripe.js for the entire page when we can simply load it for just the payment form component? Let's make an empty React component for our payment form and dynamically load Stripe.js (note, this method would work just as well for Checkout.js!):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-script-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;PaymentForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createClass&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;mixins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="na"&gt;getInitialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;getScriptURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://js.stripe.com/v2/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;onScriptLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;PaymentForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStripeToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// Put your publishable key here&lt;/span&gt;
      &lt;span class="nx"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setPublishableKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pk_test_xxxx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;onScriptError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loaded&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PaymentForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ReactScriptLoaderMixin begins loading the remote script, and upon successfully loading it, or reaching an error, will invoke one of two event listeners. Once the script is successfully loaded, we can set the public key for Stripe.js. This in turn, gives us a conditional in the render function for three states of loading, errored, or loaded! Note that this method can also be used to load Checkout.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Form
&lt;/h2&gt;

&lt;p&gt;Now we have a React component with Stripe.js loaded, let's start building the custom payment form. At minimum, we need to collect four values for Stripe to generate a payment token for us: credit card number, expiration month, expiration year, and the cvc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-script-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;PaymentForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createClass&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;mixins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;ReactScriptLoaderMixin&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="na"&gt;getInitialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;submitDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;paymentError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;paymentComplete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;getScriptURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://js.stripe.com/v2/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;onScriptLoaded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;PaymentForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getStripeToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Put your publishable key here&lt;/span&gt;
      &lt;span class="nx"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setPublishableKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pk_test_xxxx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;onScriptError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;submitDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;paymentError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// send form here&lt;/span&gt;
    &lt;span class="nx"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;paymentError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;submitDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;paymentComplete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;submitDisabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="c1"&gt;// make request to your server here!&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripeLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripeLoadingError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentComplete&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Payment&lt;/span&gt; &lt;span class="nx"&gt;Complete&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&amp;lt;br /&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;credit card number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exp-month&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expiration month&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exp-year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expiration year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cvc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cvc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submitDisabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Purchase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PaymentForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Stripe.js is loaded, our payment form component returns a form with the required input fields. We’ve added the required data-stripe attributes per the Stripe documentation. The form onSubmit event invokes a handler on our component which calls Stripe.createToken(). If an error is returned, we display that to our users by setting state.paymentError equal to the error message. Otherwise, we set the payment is complete with this.paymentComplete, and that is also the point where we would pass the token and required purchasing information to our server with a module such as superagent.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Beginners Guide To React Hooks : Getting Started With React Hooks🔥🔥</title>
      <dc:creator>Tarun yadav</dc:creator>
      <pubDate>Sat, 23 May 2020 16:24:57 +0000</pubDate>
      <link>https://dev.to/tarunyadav1/beginners-guide-to-react-hooks-getting-started-with-react-hooks-4lnd</link>
      <guid>https://dev.to/tarunyadav1/beginners-guide-to-react-hooks-getting-started-with-react-hooks-4lnd</guid>
      <description>&lt;p&gt;This is a beginners guide to react hooks. It will take time to go through this guide, so grab a cup of coffee or whatever you like. &lt;/p&gt;

&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
  What are Hooks? 
&lt;/li&gt;
&lt;li&gt;
What's wrong with classes? 
&lt;/li&gt;
&lt;li&gt;React's State Hooks&lt;/li&gt;
&lt;li&gt;What is this useState() syntax?&lt;/li&gt;
&lt;li&gt;What does useState() give us?&lt;/li&gt;
&lt;li&gt;Using Multiple State Hooks&lt;/li&gt;
&lt;li&gt;React's Effect Hook&lt;/li&gt;
&lt;li&gt;Running an Effect Hook only when something changes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  1. What are Hooks?
&lt;/h2&gt;

&lt;p&gt;Hooks are the new feature introduced in the React 16.8 version. It allows you to use state and other React features without writing a class. Hooks are the functions which "hook into" React state and lifecycle features from function components. &lt;strong&gt;It does not work inside classes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't worry though, &lt;strong&gt;classes aren't being removed or discouraged&lt;/strong&gt;. React's Developers being given more ways to code!&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  2. What's wrong with classes?
&lt;/h2&gt;

&lt;p&gt;The React Hooks intro gives a good section on this: &lt;a href="https://reactjs.org/docs/hooks-intro.html#its-hard-to-reuse-stateful-logic-between-components"&gt;Check Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are couple of problem with Classes &lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  It’s hard to reuse stateful logic between components.
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;React doesn’t offer a way to “attach” reusable behavior to a component. With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. &lt;br&gt;
&lt;strong&gt;Hooks allow you to reuse stateful logic without changing your component hierarchy.&lt;/strong&gt; This makes it easy to share Hooks among many components or with the community.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Classes confuse both people and machines
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gist is classes can sometimes be confusing and can be written any number of ways. Dive into somebody else's project and you could be in for a world of different syntax and style choices.&lt;br&gt;
 By allowing classes to be converted into smaller functional components, we can even further break out parts of our application into &lt;strong&gt;smaller and more focused components&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;h2&gt;
  
  
  3. React's State Hooks
&lt;/h2&gt;

&lt;p&gt;Hook state is the new way of declaring a state in React app. Hook uses &lt;code&gt;useState()&lt;/code&gt; functional component for setting and retrieving state.&lt;/p&gt;

&lt;p&gt;Let's say we have a component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;clicked&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;times&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component will count the click on button.&lt;/p&gt;

&lt;p&gt;With React Hooks, we are able to condense that class into this functional component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;clicked&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;times&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how much easier the functional component would be for beginners just learning React.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  4. What is this useState() syntax
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Declare a new state variable, which we'll call "count"  &lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What does calling &lt;code&gt;useState&lt;/code&gt; do?&lt;/strong&gt;&lt;br&gt;
 It declares a “state variable”. Our variable is called &lt;code&gt;count&lt;/code&gt; but we could call it anything else, like &lt;code&gt;state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do we pass to &lt;code&gt;useState&lt;/code&gt; as an argument?&lt;/strong&gt; &lt;br&gt;
 The only argument to the &lt;code&gt;useState()&lt;/code&gt; Hook is the initial state. In Classes the state should be Object, but in Hooks it does not need to be Object. We can keep a number or a string if that’s all we need. In our example,&lt;code&gt;0&lt;/code&gt; is the initial state.&lt;/p&gt;
&lt;h3&gt;
  
  
  What Do Square Brackets Mean?
&lt;/h3&gt;

&lt;p&gt;You might have noticed the square brackets when we declare a state variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JavaScript syntax is called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring"&gt;“array destructuring”&lt;/a&gt;. It means that we’re making two new variables &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;setCount&lt;/code&gt;, where &lt;code&gt;count&lt;/code&gt; is set to the first value returned by &lt;code&gt;useState&lt;/code&gt;, and &lt;code&gt;setCount&lt;/code&gt; is the second.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  5. What does useState() give us?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useState&lt;/code&gt; gives us two variables and we can name our two variables whatever we want. Just know that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The first variable is the &lt;strong&gt;value&lt;/strong&gt;. Similar to &lt;code&gt;this.state&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; The second variable is a &lt;strong&gt;function to update&lt;/strong&gt; that value. Similar to &lt;code&gt;this.setState&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final part to useState is the argument that we pass to it. &lt;strong&gt;The useState argument is the initial state value.&lt;/strong&gt; In the case of our counter, we started at 0.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  6. Using Multiple State Hooks
&lt;/h2&gt;

&lt;p&gt;We can even use &lt;code&gt;useState()&lt;/code&gt; multiple times in the same function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ExampleWithManyStates&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAge&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFruit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn Hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  7. React's Effect Hook
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Effect Hook&lt;/em&gt; lets you perform side effects in function components. It does not use components lifecycle methods which are available in class components. In other words, Effects Hooks are equivalent to &lt;code&gt;componentDidMount()&lt;/code&gt;, &lt;code&gt;componentDidUpdate()&lt;/code&gt; and &lt;code&gt;componentWillUnmount()&lt;/code&gt; lifecycle methods.&lt;/p&gt;

&lt;p&gt;Side-effects are things you want your application to make like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Fetching data&lt;/li&gt;
&lt;li&gt;  Manually changing the DOM (document title)&lt;/li&gt;
&lt;li&gt;  Setting up a subscription&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Effects will run after every render, including the first render.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's compare a class to a functional component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this is componentDidMount!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;changeTitle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;stuff&lt;/span&gt; &lt;span class="nx"&gt;goes&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using the the Effect Hook, we use &lt;code&gt;useEffect()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this is useEffect &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;changeTitle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;stuff&lt;/span&gt; &lt;span class="nx"&gt;goes&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  8. Running an Effect Hook only when something changes
&lt;/h2&gt;

&lt;p&gt;Since &lt;code&gt;useEffect()&lt;/code&gt; runs every time a component renders, how do we get it to only run once, on mount? The Effect Hook can &lt;strong&gt;take a second argument&lt;/strong&gt;, an array. It will look through the array and &lt;strong&gt;only run the effect if one of those values has changed&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  componentDidMount: Runs once
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// only run on mount. pass an empty array&lt;/span&gt;
&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// only runs once&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  componentDidUpdate: Runs on changes
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// only run if count changes&lt;/span&gt;
&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// run here if count changes&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you have some understanding of hooks and how they work. If you want to learn hooks in-depth, you should check the official docs by React's Developers. &lt;/p&gt;

&lt;h4&gt;
  
  
  If it helps you to understand Hooks, please give &lt;em&gt;like&lt;/em&gt;
&lt;/h4&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>reactnative</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
