Scrimb Bot is the hands-on project you’ll build throughout the Build AI Apps with LangChain.js course.
It showcases how to use LangChain.js to create a working AI chatbot from scratch, with prompts, chains, and memory.
This project is developed as part of the Scrimba course Build AI Apps with LangChain.js.
The course guides you step by step through:
- Setting up LangChain.js in a Node.js environment
- Designing prompts and building chains
- Adding memory to conversations
- Extending bots with tools and external data sources
- Deploying and experimenting with AI apps
By the end of the course, you’ll have your own chatbot (Scrimb Bot) and the skills to extend it further.
- Console-based chatbot powered by LangChain.js
- Structured prompts with role separation
- Conversation memory for context-aware replies
- Supabase integration for storing and retrieving data
- OpenAI API for intelligent responses
- Modular design for extending with new chains/tools
- Built with modern JavaScript practices
- LangChain.js – framework for AI applications
- OpenAI – language model API
- Supabase – database and vector store
- Node.js – runtime
- npm – dependency management
- dotenv – environment variables
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import { createClient } from '@supabase/supabase-js';
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase';
import { OpenAIEmbeddings } from 'langchain/embeddings/openai';
// @supabase/supabase-js
try {
const result = await fetch('scrimba-info.txt');
const text = await result.text();
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 500,
chunkOverlap: 50,
separators: ['\n\n', '\n', ' ', ''], // default setting
});
const output = await splitter.createDocuments([text]);
const sbApiKey = process.env.SUPABASE_API_KEY;
const sbUrl = process.env.SUPABASE_URL_LC_CHATBOT;
const openAIApiKey = process.env.OPENAI_API_KEY;
const client = createClient(sbUrl, sbApiKey);
await SupabaseVectorStore.fromDocuments(
output,
new OpenAIEmbeddings({ openAIApiKey }),
{
client,
tableName: 'documents',
}
);
console.log('success');
} catch (err) {
console.log(err);
}When you first begin the course, your entry file (index.js, index.html, index.css) may look something like this:
document.addEventListener('submit', (e) => {
e.preventDefault();
progressConversation();
});
const openAIApiKey = process.env.OPENAI_API_KEY;
async function progressConversation() {
const userInput = document.getElementById('user-input');
const chatbotConversation = document.getElementById(
'chatbot-conversation-container'
);
const question = userInput.value;
userInput.value = '';
// add human message
const newHumanSpeechBubble = document.createElement('div');
newHumanSpeechBubble.classList.add('speech', 'speech-human');
chatbotConversation.appendChild(newHumanSpeechBubble);
newHumanSpeechBubble.textContent = question;
chatbotConversation.scrollTop = chatbotConversation.scrollHeight;
// add AI message
const newAiSpeechBubble = document.createElement('div');
newAiSpeechBubble.classList.add('speech', 'speech-ai');
chatbotConversation.appendChild(newAiSpeechBubble);
newAiSpeechBubble.textContent = result;
chatbotConversation.scrollTop = chatbotConversation.scrollHeight;
}<!DOCTYPE html>
<html>
<head>
<title>Scrimba Chatbot</title>
<link rel="stylesheet" href="index.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins&family=Roboto&display=swap"
rel="stylesheet"
/>
</head>
<body>
<main>
<section class="chatbot-container">
<div class="chatbot-header">
<img src="images/logo-scrimba.svg" class="logo" />
<p class="sub-heading">Knowledge Bank</p>
</div>
<div
class="chatbot-conversation-container"
id="chatbot-conversation-container"
></div>
<form id="form" class="chatbot-input-container">
<input name="user-input" type="text" id="user-input" required />
<button id="submit-btn" class="submit-btn">
<img src="images/send.svg" class="send-btn-icon" />
</button>
</form>
</section>
</main>
<script src="index.js" type="module"></script>
</body>
</html>:root {
--border-rad-lg: 15px;
--light-text: #fefefe;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
font-family: 'Poppins';
}
main {
background-color: slategrey;
background-image: url('images/scrimba-bg.jpeg');
background-size: cover;
background-repeat: no-repeat;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* chatbot elements */
.chatbot-container {
background-color: #171f26;
width: 360px;
min-height: 380px;
border-radius: var(--border-rad-lg);
padding: 1em;
}
.chatbot-container > * {
padding: 0.5em;
}
.chatbot-header {
display: flex;
flex-direction: column;
gap: 0.6em;
}
.logo {
width: 160px;
}
.chatbot-conversation-container {
height: 250px;
overflow-y: scroll;
margin: 1em 0;
}
/* stop ugly scroll bar on some browsers */
.chatbot-conversation-container::-webkit-scrollbar {
display: none;
}
.chatbot-conversation-container::-moz-scrollbar {
display: none;
}
.speech {
padding: 1em;
max-width: 240px;
color: var(--light-text);
min-width: 90%;
border-radius: var(--border-rad-lg);
font-size: 1.07em;
}
.speech:first-child {
margin-top: 0;
}
.speech-ai {
background: #334959;
border-top-left-radius: 0;
margin: 1.2em 1em 0 0;
}
.speech-human {
margin: 1.2em 0 0 1em;
background: #2f4f4f;
border-top-right-radius: 0;
}
.chatbot-input-container {
display: flex;
}
input[type='text'],
button {
background-color: transparent;
border: 1px solid #586e88;
border-radius: var(--border-rad-lg);
padding: 1em;
}
input[type='text'] {
color: var(--light-text);
width: 100%;
border-right: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
button {
border-left: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.send-btn-icon {
width: 20px;
display: block;
}
/* text */
.sub-heading {
color: #999999;
font-family: 'Roboto', sans-serif;
font-size: 12px;
text-transform: uppercase;
margin: 0;
}This simple starting point helps you verify your setup and gives you a base to build on. As you progress through the course, you’ll:
- Import and configure LangChain.js
- Add chains and prompt templates
- Connect memory and Supabase
- Integrate the OpenAI API
By completing this project, you’ll learn how to:
- Build AI apps with LangChain.js
- Structure prompts and conversations
- Add memory for contextual chatbots
- Store and retrieve data with Supabase
- Connect to the OpenAI API for responses
- Deploy and iterate on AI applications
