Skip to content

Instantly share code, notes, and snippets.

@FarisHijazi
Created November 23, 2025 05:58
Show Gist options
  • Select an option

  • Save FarisHijazi/1c7c13b0e15e2f8a5dfdfc7741ec3fc9 to your computer and use it in GitHub Desktop.

Select an option

Save FarisHijazi/1c7c13b0e15e2f8a5dfdfc7741ec3fc9 to your computer and use it in GitHub Desktop.
LLM text OpenAI with pure HTML+JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Streams Demo</title>
<link rel="stylesheet" href="https://unpkg.com/mvp.css" />
</head>
<body>
<main>
<section>
<aside>
<h3>Tell me a joke</h3>
<button id="stop">STOP</button>
<p id="content"></p>
</aside>
</section>
</main>
<script type="module">
const url = "https://api.openai.com/v1/chat/completions";
const apiKey = `your_api_key_here`;
const controller = new AbortController();
document.querySelector("#stop").addEventListener("click", () => {
controller.abort();
});
async function run() {
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
messages: [{ role: "user", content: "Tell me a joke" }],
temperature: 0.6,
model: "gpt-4o",
max_tokens: 30,
stream: true,
}),
signal: controller.signal,
});
const decoder = new TextDecoder();
for await (const chunk of response.body) {
const decoded = decoder.decode(chunk);
const lines = decoded
.split("\n")
.map((l) => l.replace("data: ", ""))
.filter((l) => l.length > 0)
.filter((l) => l !== "[DONE]")
.map((l) => JSON.parse(l));
for (const line of lines) {
const {
choices: [
{
delta: { content },
},
],
} = line;
if (content) {
document.querySelector("#content").textContent += content;
}
}
}
} catch (err) {
console.log("Stopped or failed:", err);
}
}
run();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment