How to create typewriter effect with JavaScript
In this blog, I will show you how to create a typewriter effect with JavaScript.
Typewriter Effect Demo
Basic Idea
We will have an h1 tag. It will contain the text I am a. Then we will have a word with the typewriter effect.
We will take each of the characters and put them in a span tag. Then we will put that span tag inside the h1 tag.
We will do this for each character. After completing the word, we will wait for a while and then start removing the character.
After removing the whole word, we will wait for a while and then start adding the next word.
This is how we will create the typewriter effect.
Html
<body><h1 class="text">I am a </h1></body>
a is an HTML entity for non-breaking space.
Css
@import url('https://fonts.googleapis.com/css2?family=Cousine:wght@700&display=swap');* {padding: 0;margin: 0;box-sizing: border-box;}html {font-size: 62.5%;}body {font-family: 'Cousine', monospace;min-height: 100vh;display: grid;place-items: center;background-color: black;}:root {--text-color: white;}.text {font-size: 4rem;display: inline-block;letter-spacing: 0.2rem;color: var(--text-color);border-right: 1rem solid var(--text-color);animation: blink 0.5s step-end infinite alternate;}.char {color: orange;}@keyframes blink {50% {border-color: transparent;}}@media (min-width: 600px) {.text {font-size: 6rem;}}@media (min-width: 900px) {.text {font-size: 8rem;}}@media (min-width: 1200px) {.text {font-size: 11rem;}}@media (min-width: 1600px) {.text {font-size: 14rem;}}
Basic css for the website.

Javascript
const textEl = document.querySelector('.text')const words = ['Developer', 'Youtuber', 'Blogger'].map(word => word + '.')let wordIndex = 0let charIndex = 0let addingChars = truelet shouldWait = falselet currentWord = words[wordIndex]
Explanation:
textElis theh1tag.wordsis an array of words that will have the typewriter effect.wordIndexis the index of the current word.charIndexis the index of the current character.addingCharsis a boolean that tells us if we are adding characters or removing them.shouldWaitis a boolean that tells us if we should wait for a while.currentWordis the current word that we are working on.
const addChar = () => {let currChar = currentWord[charIndex]const char = document.createElement('span')char.innerText = currCharchar.classList.add('char')textEl.appendChild(char)charIndex++if (charIndex === currentWord.length) {charIndex--addingChars = falseshouldWait = true}}
Explanation:
currCharis the current character. We put them in a span tag and them inside thetextElelement.- We increase the
charIndexby 1. - If the
charIndexis equal to the length of the current word, we decrementcharIndexby 1. Because we have to start removing from the last character. - We set
addingCharsto false andshouldWaitto true. Because we have to wait for a while.
const removeChar = () => {const char = textEl.lastElementChildtextEl.removeChild(char)charIndex--if (charIndex < 0) {charIndex++addingChars = trueupdateCurrWord()}}
Explanation :
- We remove the last child of the
textElelement and decrease thecharIndexby 1. - If the
charIndexis less than 0, we increase it by 1. Because we have to start adding from the first character to the next word. - We set
addingCharsto true andshouldWaitto false. Because we have to add the next word. - And we call the
updateCurrWordfunction. Let's implement theupdateCurrWordfunction.
const updateCurrWord = () => {wordIndex++if (wordIndex === words.length) wordIndex = 0currentWord = words[wordIndex]}
Explanation:
- We increase the
wordIndexby 1. - If the
wordIndexis equal to the length of the words array, we setwordIndexto 0. Because we have to start from the first word. - Finally, we update the
currentWordto the current index.
const runTypewriter = () => {const operation = addingChars ? addChar : removeCharoperation()let timeout = addingChars ? 200 : 100if (shouldWait) {timeout = 1000shouldWait = false}setTimeout(runTypewriter, timeout)}setTimeout(runTypewriter, 1500)
Explanation:
- We create an
operationvariable. It will store the function that we want to call. It will be eitheraddCharorremoveChardepending on theaddingCharsvariable. - We create a
timeoutvariable. It will store the time that we want to wait. It will be either200or1000depending on theshouldWaitvariable. - If
shouldWaitis true, we settimeoutto 1000 andshouldWaitto false. - We call the
runTypewriterfunction inside thetypewriterfunction. This is what we callrecursion. But don't worry about it. It will create a loop that will create the typewriter effect. - Finally, we call the
runTypewriterfunction globally after 1500 milliseconds.
Final Result
That's it! You can check out the GitHub repository for the code. Feel free to Star it, fork it, and make your own version.
Shameless Plug
Want to create your own blog? Well, I am creating a video series where you will learn about how to create a JAMstack blog with Nextjs and Chakra-UI.
Lessons
- Intro & Setup
- Build Homepage UI
- How our app will work
- MDX, MongoDB, Static Homepage
- Generate Static Blog Page
- Style Blog page with Chakra-UI and MDX-embed
- Build a real-time view counter
- Autocomplete search form with MongoDB Atlas Search Index
- Deploy application to Vercel
Demo
You can demo the website from here
Features
- Static Blog pages will make the website load faster.
- Blogs will have code blocks with syntax highlighting and many embed components like youtube videos, GitHub gist, Tweets, and so many other things.
- Autocomplete search feature for the blog posts.
- Real-time view counter and so on.
Please like and subscribe to Cules Coding. It motivates me to create more content like this.
That's it for this blog. I have tried to explain things simply. If you get stuck, you can ask me questions.
By the way, I am looking for a new opportunity in a company where I can provide great value with my skills. If you are a recruiter, looking for someone skilled in full-stack web development and passionate about revolutionizing the world, feel free to contact me. Also, I am open to talking about any freelance project. I am available on Upwork
Contacts
- Email: thatanjan@gmail.com
- LinkedIn: @thatanjan
- Portfolio: anjan
- Github: @thatanjan
- Instagram (personal): @thatanjan
- Twitter: @thatanjan
- Upwork: @thatanjan
Blogs you might want to read:
- Eslint, prettier setup with TypeScript and react
- What is Client-Side Rendering?
- What is Server Side Rendering?
- Everything you need to know about tree data structure
- 13 reasons why you should use Nextjs
- Beginners guide to quantum computers
Videos might you might want to watch:
