I tried to develop a NodeJS application using only ChatGPT — I failed

Benoit Lamouche
10 min readMar 19, 2023

--

Photo by Josh Applegate on Unsplash

My daughter loves to be told stories. But since our library is not infinite, and a little tired of reading the same stories over and over again, last weekend I decided to create stories with ChatGPT.

The principle was simple: I asked my daughter which characters should appear in her story, what the setting should be, and what could happen to them.

The result? A children’s story that took these elements and turned them into something fun. And overall, the result was decent.

I found my use case for another experiment.

💡 This test has been made with the version GPT-3.5

Are you enjoying this article ? 👉 Subscribe to my new publications

Developing an app entirely with ChatGPT.

I have already mentioned it, ChatGPT is capable of many things, including producing code of varying quality. My only tests so far have been on “pieces” of code, and functions, but never on a complete app.

So I embarked on this experiment: developing a children’s story generator.

Methodology and approach

Given the nature of ChatGPT and its ability to learn context and memorize the discussion history, I have decided to take a progressive iterative approach: start small, then add functions as we go through the iterations.

Technical stack

I chose NodeJS for this app because I love this technology and because it is suited for what I want to do: make API requests.

Developing the app

I won’t transcribe the entire discussion because it’s not very interesting. I’ll just share a few examples of my interactions with ChatGPT.

Here are the rest of my queries to ChatGPT:

1 — Create a new NodeJS app.

> write a hello world nodejs application
// Load the http module from Node.js
const http = require('http');

// Define the port number that the server will listen on
const port = 3000;

// Create the server using the http module
const server = http.createServer((req, res) => {
// Set the response header to indicate that we're sending plain text
res.setHeader('Content-Type', 'text/plain');

// Write the "Hello, world!" message to the response
res.write('Hello, world!');

// End the response
res.end();
});

// Start the server listening on the specified port
server.listen(port, () => {
console.log(`Server running at <http://localhost>:${port}/`);
});

✅ Success

2 — Display an html page

> it must render an html page
// Load the http and fs modules from Node.js
const http = require('http');
const fs = require('fs');
// Define the port number that the server will listen on
const port = 3000;
// Create the server using the http module
const server = http.createServer((req, res) => {
// Set the response header to indicate that we're sending HTML
res.setHeader('Content-Type', 'text/html');
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Write the contents of the file to the response
res.writeHead(200);
res.write(data);
res.end();
});
});
// Start the server listening on the specified port
server.listen(port, () => {
console.log(`Server running at <http://localhost>:${port}/`);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>This is a simple HTML page rendered by a Node.js server.</p>
</body>
</html>

✅ Success

3 — Update the html file with dynamic data

> can you update it with some dynamic data coming from nodejs ?
// Load the http and fs modules from Node.js
const http = require('http');
const fs = require('fs');
// Define the port number that the server will listen on
const port = 3000;
// Create the server using the http module
const server = http.createServer((req, res) => {
// Set the response header to indicate that we're sending HTML
res.setHeader('Content-Type', 'text/html');
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Generate some dynamic content
const name = 'Alice';
const age = 30;
const dynamicContent = `My name is ${name} and I am ${age} years old.`;
// Replace the placeholder in the HTML file with the dynamic content
const html = data.toString().replace('{dynamic_content}', dynamicContent);
// Write the HTML to the response
res.writeHead(200);
res.write(html);
res.end();
});
});
// Start the server listening on the specified port
server.listen(port, () => {
console.log(`Server running at <http://localhost>:${port}/`);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>{dynamic_content}</p>
</body>
</html>

✅ Success

4 — Add interactions with a form

> add a dynamic field for 'name' that will update the name as per the content
// Load the http and fs modules from Node.js
const http = require('http');
const fs = require('fs');
// Define the port number that the server will listen on
const port = 3000;
// Create the server using the http module
const server = http.createServer((req, res) => {
// Set the response header to indicate that we're sending HTML
res.setHeader('Content-Type', 'text/html');
if (req.method === 'POST') {
// Handle POST requests to the server
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
const name = body.split('=')[1];
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Replace the placeholder in the HTML file with the user's name
const html = data.toString().replace('{name}', name);
// Write the HTML to the response
res.writeHead(200);
res.write(html);
res.end();
});
});
} else {
// Handle GET requests to the server
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Replace the placeholder in the HTML file with an empty string
const html = data.toString().replace('{name}', '');
// Write the HTML to the response
res.writeHead(200);
res.write(html);
res.end();
});
}
});
// Start the server listening on the specified port
server.listen(port, () => {
console.log(`Server running at <http://localhost>:${port}/`);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<form method="POST" action="/">
<label for="name">Enter your name:</label>
<input type="text" id="name" name="name">
<button type="submit">Submit</button>
</form>
{name}
</body>
</html>

✅ Success

5 — Update one field of the app

> replace "name" with "animal”
// Load the http and fs modules from Node.js
const http = require('http');
const fs = require('fs');
// Define the port number that the server will listen on
const port = 3000;
// Create the server using the http module
const server = http.createServer((req, res) => {
// Set the response header to indicate that we're sending HTML
res.setHeader('Content-Type', 'text/html');
if (req.method === 'POST') {
// Handle POST requests to the server
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
const animal = body.split('=')[1];
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Replace the placeholder in the HTML file with the user's name
const html = data.toString().replace('{animal}', animal);
// Write the HTML to the response
res.writeHead(200);
res.write(html);
res.end();
});
});
} else {
// Handle GET requests to the server
// Read the contents of the index.html file
fs.readFile('index.html', (err, data) => {
if (err) {
// If there was an error reading the file, send a 500 error
res.writeHead(500);
return res.end(`Error loading index.html: ${err}`);
}
// Replace the placeholder in the HTML file with an empty string
const html = data.toString().replace('{animal}', '');
// Write the HTML to the response
res.writeHead(200);
res.write(html);
res.end();
});
}
});
// Start the server listening on the specified port
server.listen(port, () => {
console.log(`Server running at <http://localhost>:${port}/`);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<form method="POST" action="/">
<label for="animal">Enter your favorite animal:</label>
<input type="text" id="animal" name="animal">
<button type="submit">Submit</button>
</form>
{animal}
</body>
</html>

✅ Success

6 — Add interactions with OpeAI API

> update this app with a call to OpenAI API when we submit an animal name, it must display the answer from the API with a text generated by OpenAI

❌ Fail

This is the moment when ChatGPT lost track of the application as it only returned an update of the app.js file. Technically, this could work, there is no need to necessarily change the index.html file. However, ChatGPT decided to change the name of the dynamic variable in my HTML page. It transformed animal into text. Naturally, this doesn't work anymore.

So, I had to ask ChatGPT to update the HTML file.

> can you update the html file too ?

✅ Success

He succeeded in updating my index.html file with the correct dynamic field.

❌ Fail

On the other hand, he forgot to import fetch into my NodeJS app. As it stands, my app generates an error.

7 — Fine-tunning

I then added some small improvements, notably the number of parameters to generate my story, and a call to the Dall-E API to generate a custom image to illustrate my story.

The big mess

If the experience has been good so far, from this point on everything became more complicated.

I had to start working on specific sub-parts of my code in order to continue my development.

Below are my few observations and comments.

ChatGPT forgets (alzheimer?)

Several times I had to give my code again to ChatGPT without which it couldn’t respond to me.

ChatGPT can’t handle big pieces of code

At one point, my app became too big for ChatGPT. My app.js was 150 lines, which is not really big for an app...

I asked him to split the code into several files to make reading and comprehension simpler:

> Can we split it into several smaller files ?
Yes, it is possible to split the app.js file into smaller files. This can help with organization and maintainability of the codebase. Here's an example of how we could refactor the code:

❌ Fail

He never managed to produce the new file architecture. He starts… then stops in the middle of a file. Worse, if I ask him to resume his work, he will use a new naming convention that will make the previously generated files obsolete and unusable.

I should take more time to test and understand this limitation.

💡 It is highly likely that this limitation comes from the token system of ChatGPT. Indeed, each interaction is governed by a maximum number of tokens defined by the developer during API calls. However, the maximum that ChatGPT can currently support with 3.5 was 4000 tokens.

Spending more time explaining to ChatGPT what to do rather than doing it directly

Extreme frustration alert!

Several times, I found myself in a situation where the result of my prompt did not exactly match my needs.

In most cases, it would have been faster for me to produce the code myself rather than asking ChatGPT to do it.

I admit that I bypassed ChatGPT several times out of “laziness” to spend more time explaining than doing it myself.

Are you enjoying this article ? 👉 Subscribe to my new publications

ChatGPT is good for…

Bootstrap a project

This is frankly very pleasant to be able to have the basic work that every project entails done. These are generally repetitive, uninteresting tasks, yet they are structuring to get started working.

The AI is of great use to me here, and I will undoubtedly reuse it in this sense quite often.

Resolve bugs

This is not 100% accurate, sometimes the solution is incomplete, but based on my tests, in the majority of cases, the AI has either found the solution or put me on the path to resolution.

My feelings are mixed about this capability, because it seems to me that searching for and fixing bugs is an integral part of the developer’s job, and it is often on this criterion that “good” developers will distinguish themselves: their ability to analyse and understand a problem in a piece of code.

Searching for and fixing bugs directly call on the developer’s analytical abilities, which are very useful for a developer, but also in everyday life for other tasks.

Generate dummy data

Do you need a table with fake data? Do you need data sets to make app testing more realistic?

It is extremely easy to generate a list of fake identities (name, surname, address, email, phone…) or fake content on various topics, in order to do away with the “lorem ipsum”.

Repetitive & boring work

The capabilities in terms of code completion are interesting. This is actually what can be found in Copilot, a powerful engine for code auto-completion and suggestion.

Explain a function and share documentation

If the tool is not officially described as a search tool, it is still powerful for searching for documentation. “Explain to me this or that function of language X, explain to me this piece of code…”

Next steps

Next step will be to create a UI with JS & CSS. I plan to start with basic CSS, and increase complexity by adding libraries & frameworks.

I will have to upgrade the API call with the new ChatGPT api which may actually give me better results compared to Da-vinci.

Github repository : https://github.com/blamouche/Story-machine

my app

a generated story

--

--

Benoit Lamouche
Benoit Lamouche

Written by Benoit Lamouche

Digital Factory Director & Tech culture addict https://lamouche.fr/ - Creator of The Hidden Leader https://thehiddenleader.substack.com/

No responses yet