Coding a Twitter Clone using ChatGPT.

Abdul Rehman Kalsekar
6 min readFeb 19, 2023

--

Recently, I was just trying out ChatGPT and got an idea to test the limits of ChatGPT by asking it to create a Twitter clone using HTML, CSS, and JavaScript.

Stay tuned till the end of this post to learn to create one for yourself as well. Do Like and Share this post with your fellow developers as well. We will be discussing the whole code using prompts and their responses.

First Prompt: “Create a Twitter Clone using HTML, CSS, and JS.”

Here is the response given to me by ChatGPT.

Then I asked it to “Create the basic structure of the website using HTML elements such as header, main, footer, etc for a Twitter Clone”

Here is what it generated.

<!DOCTYPE html>
<html>
<head>
<title>Twitter Clone</title>
</head>
<body>
<header>
<h1>Twitter Clone</h1>
</header>

<main>
<section class="input-section">
<form action="submit-tweet.php" method="post">
<textarea name="tweet"></textarea>
<input type="submit" value="Tweet">
</form>
</section>

<section class="tweets-section">
<h2>Tweets</h2>
<ul class="tweets-list">
<li class="tweet">
<p class="username">@username</p>
<p class="message">This is a sample tweet.</p>
</li>
<!-- Add more tweets here -->
</ul>
</section>
</main>

<footer>
<p>&copy; Twitter Clone 2023</p>
</footer>
</body>
</html>

Then I asked it to style the above page.

body {
font-family: Arial, sans-serif;
background-color: #eee;
}

header {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
}

main {
padding: 20px;
}

.input-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}

.input-section textarea {
width: 100%;
height: 150px;
padding: 10px;
font-size: 16px;
border: none;
border-radius: 10px;
resize: none;
}

.input-section input[type="submit"] {
background-color: #1DA1F2;
color: white;
padding: 10px 20px;
border: none;
border-radius: 10px;
font-size: 16px;
float: right;
}

.tweets-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.tweets-list {
list-style: none;
padding: 0;
margin: 0;
}

.tweet {
padding: 20px;
border-bottom: 1px solid #ddd;
}

.username {
font-weight: bold;
color: #1DA1F2;
}

footer {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
}

After a few more prompts here, I was a decently acceptable css.

body {
font-family: Arial, sans-serif;
background-color: #e6ecf0;
}

header {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
display: flex;
justify-content: space-between;
}

header h1 {
margin: 0;
}

header nav {
display: flex;
align-items: center;
}

header nav a {
color: white;
text-decoration: none;
margin-right: 20px;
}

main {
padding: 20px;
display: flex;
}

.input-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
width: 100%;
}

.input-section textarea {
width: 100%;
height: 150px;
padding: 10px;
font-size: 16px;
border: none;
border-radius: 10px;
resize: none;
}

.input-section input[type="submit"] {
background-color: #1DA1F2;
color: white;
padding: 10px 20px;
border: none;
border-radius: 10px;
font-size: 16px;
float: right;
margin-top: 20px;
}

.tweets-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 30%;
margin-left: 20px;
}

.tweets-section h2 {
margin: 0;
}

.tweets-list {
list-style: none;
padding: 0;
margin: 0;
}

.tweet {
padding: 20px;
border-bottom: 1px solid #ddd;
display: flex;
align-items: center;
}

.tweet img {
width: 50px;
height: 50px;
border-radius: 25px;
margin-right: 20px;
}

.username {
font-weight: bold;
color: #1DA1F2;
}

footer {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
}

Now It was time to give some life to our dead application. I asked ChatGPT to “Add JavaScript to save the tweets in localstorage and display them in tweet list section.”

I know, this isn't the best way to save such tweets, but I just needed to make the application work. Here is what it generated and to my surprise, it was way better than I could even imagine.

const form = document.querySelector('form');
const tweetList = document.querySelector('.tweet-list');

form.addEventListener('submit', saveTweet);

function saveTweet(e) {
e.preventDefault();
const tweetText = document.querySelector('#tweet-text').value;

let tweets = localStorage.getItem('tweets')
? JSON.parse(localStorage.getItem('tweets'))
: [];

const tweet = {
text: tweetText,
time: new Date().toLocaleString(),
};

tweets.unshift(tweet);
localStorage.setItem('tweets', JSON.stringify(tweets));
displayTweets();
}

function displayTweets() {
const tweets = localStorage.getItem('tweets')
? JSON.parse(localStorage.getItem('tweets'))
: [];

tweetList.innerHTML = '';

tweets.forEach((tweet) => {
const li = document.createElement('li');
li.classList.add('tweet');
li.innerHTML = `
<img src="https://picsum.photos/50" alt="avatar">
<div>
<span class="username">User:</span>
<p class="tweet-text">${tweet.text}</p>
<div class="tweet-actions">
<i class="fa fa-retweet"></i>
<span>0</span>
<i class="fa fa-heart"></i>
<span>0</span>
<i class="fa fa-ellipsis-h"></i>
</div>
<p class="tweet-time">${tweet.time}</p>
</div>
`;
tweetList.appendChild(li);
});
}

displayTweets();

Now, it's time for the final touches. I added All 3 sections ie HTML, CSS, and JS to see what it has created.

Index.html


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css">
<link rel="stylesheet" href="style.css">
<title>Twitter Clone</title>
</head>
<body>
<header>
<nav>
<h1 class="logo">Twitter</h1>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">Notifications</a></li>
<li><a href="#">Messages</a></li>
</ul>
<form>
<input type="text" placeholder="What's happening?" id="tweet-text">
<button type="submit">Tweet</button>
</form>
</nav>
</header>
<main>
<ul class="tweet-list"></ul>
</main>
<footer>
<p>&copy; Twitter 2023</p>
</footer>
<script src="app.js"></script>
</body>
</html>

Style.css

body {
font-family: Arial, sans-serif;
background-color: #e6ecf0;
}

header {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
display: flex;
justify-content: space-between;
}

header h1 {
margin: 0;
}

header nav {
display: flex;
align-items: center;
}

header nav a {
color: white;
text-decoration: none;
margin-right: 20px;
}

main {
padding: 20px;
display: flex;
}

.input-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
width: 100%;
}

.input-section textarea {
width: 100%;
height: 150px;
padding: 10px;
font-size: 16px;
border: none;
border-radius: 10px;
resize: none;
}

.input-section input[type="submit"] {
background-color: #1DA1F2;
color: white;
padding: 10px 20px;
border: none;
border-radius: 10px;
font-size: 16px;
float: right;
margin-top: 20px;
}

.tweets-section {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 30%;
margin-left: 20px;
}

.tweets-section h2 {
margin: 0;
}

.tweets-list {
list-style: none;
padding: 0;
margin: 0;
}

.tweet {
padding: 20px;
border-bottom: 1px solid #ddd;
display: flex;
align-items: center;
}

.tweet img {
width: 50px;
height: 50px;
border-radius: 25px;
margin-right: 20px;
}

.username {
font-weight: bold;
color: #1DA1F2;
}

footer {
background-color: #1DA1F2;
color: white;
padding: 20px;
text-align: center;
}

app.js

const form = document.querySelector('form');
const tweetList = document.querySelector('.tweet-list');

form.addEventListener('submit', saveTweet);

function saveTweet(e) {
e.preventDefault();
const tweetText = document.querySelector('#tweet-text').value;

let tweets = localStorage.getItem('tweets')
? JSON.parse(localStorage.getItem('tweets'))
: [];

const tweet = {
text: tweetText,
time: new Date().toLocaleString(),
};

tweets.unshift(tweet);
localStorage.setItem('tweets', JSON.stringify(tweets));
displayTweets();
}

function displayTweets() {
const tweets = localStorage.getItem('tweets')
? JSON.parse(localStorage.getItem('tweets'))
: [];

tweetList.innerHTML = '';

tweets.forEach((tweet) => {
const li = document.createElement('li');
li.classList.add('tweet');
li.innerHTML = `
<img src="https://picsum.photos/50" alt="avatar">
<div>
<span class="username">User:</span>
<p class="tweet-text">${tweet.text}</p>
<div class="tweet-actions">
<i class="fa fa-retweet"></i>
<span>0</span>
<i class="fa fa-heart"></i>
<span>0</span>
<i class="fa fa-ellipsis-h"></i>
</div>
<p class="tweet-time">${tweet.time}</p>
</div>
`;
tweetList.appendChild(li);
});
}

displayTweets();

Here is what it looks like when merged together.

This is really scary to see ChatGPT developing such complete applications. It is really a matter to think about and ponder. Let's see what AI and ML have instore for us in the future.

Do Like and Follow Abdul Rehman Kalsekar for more such amazing content.

--

--