AI Course for Developers – Build AI-Powered Apps with React
Skills:
LLM Foundations80%Prompting Basics80%Prompt Craft70%Advanced Prompting70%Fine-tuning LLMs60%
Key Takeaways
This video course teaches developers how to build AI-powered apps with React and Express, covering topics such as LLMs, prompt engineering, and full-stack AI integration using tools like Bun, Tailwind, and OpenAI API.
Full Transcript
[Music] AI is everywhere, but have you actually built something with it? In this course, you will learn how to build real AI powered features like the ones you see in apps from Google, Amazon, and beyond. We'll start by building a solid foundation, understanding language models, tokens, context windows, choosing the right models, model settings, and prompt engineering. Then we'll build projects starting with a chatbot that can answer questions about an imaginary theme park, helping visitors find what they need faster. Next, we'll create a tool that analyzes customer feedback and delivers clear, actionable insights so users can make shorter decisions in seconds. And finally, we'll wrap up with powerful open-source integrations you can run anywhere. Along the way, you will learn clean architecture principles, follow best practices, and work with modern tools like Bun, Tailwind, Shatsen, Prisma, and Olama. By the end, you will have the skills and confidence to build AI powered apps people actually want to use. I'm Mash Hamadani, a software engineer with over 20 years of experience, and I've taught millions how to code and become professional software engineers through my YouTube channel and online school, codewithmarsh.com. If you're new here, make sure to subscribe as I upload new videos all the time. Now, let's jump in and get started. [Music] Before we dive in, let's talk about what you'll need to know to get the most out of this course. The ideal student is someone who already knows the basics of front-end development and wants to bring AI into their applications to make them more engaging and smarter. That means you should be comfortable with modern JavaScript and TypeScript things like arrow functions, destructuring, promises, and async and await. You should also know how to build simple React applications. You should know how to create components, work with JSX, and use the state and effect hooks. Just the basics. You don't need to be a React expert. If you know a bit of backend development and databases, that's great, but not required. The same goes with AI. You don't need any prior experience. I will walk you through everything step by step. If that sounds like you, you're ready to get started. [Music] Assuming that you're the right student for this course, let me give you a quick overview of how it's structured and what to expect. First, let me tell you what this course is not. If you're looking for one of those build an app with AI in 1 hour miracles, you know, where you paste a few prompts into chat GPT, sit back with the latte, and poof, your billion dollar startup is ready. This isn't that course. We are not doing VIP coding here. We're building smart features with AI, the kind that actually make your apps more useful and more engaging. And we'll do it the right way so you understand exactly what's going on under the hood. All right, here's how the course is laid out. In section one, we'll start with the foundations. You'll learn what language models are, what they can do, and how to work with them. We'll talk about tokens, context windows, model settings like temperature, and how to call models. This section sets you up with the concepts you need before we dive into building. Section two is all about setting up a modern full stack project from scratch. Now, we could use Nex.js JS here, but I decided not to because not everybody uses it or even likes it and some developers prefer to keep the front end and back end completely separate. So in this course, we'll keep the back end and front end completely separate. This helps you clearly see how the two parts talk to each other. We'll use a modern stack with bun, express, react, tailwind, and chaten. And don't worry if you haven't used these tools before. I'll teach you everything from scratch. Now, if you prefer Nex.js, JS, you can still apply everything you learn in this course to a Next.js project. The principles are exactly the same. Section 3 is our first big project, a chatbot that can answer questions about an imaginary theme park to help visitors find the information they need faster. We'll start with the back end, build it step by step, and then refactor it using clean architecture principles. Once the back end is solid, we'll build the front end the same way. We'll add features, improve the UI, and make the chatbot better with each lesson. This is where I want you to code along with me. Don't just watch. Understand the code, the problems we run into, and why we solve them the way we do. If it feels like I'm going too fast, just watch one lesson at a time, take notes, and then repeat it. The lessons are short and focused, so you won't need to remember a lot at once. In section four, we'll dive into prompt engineering, the art of writing prompts that actually get the results you want. You will learn how to give context, control output format, use examples, handle errors, and reduce hallucinations. Section five is another full stack project. This time, a product review summarizer. You have probably seen this on a lot of websites. A quick summary of reviews so you can decide faster. We'll build our own version from scratch, complete with a database and Prisma migrations. It's a bigger, more complex project than the chatbot. So, we'll get to explore a lot of techniques and best practices that most courses skip. And here's the cool part. What you learn here isn't just for summarizing text. You can apply the same techniques to build all kinds of AI powered features. Finally, section six is about working with open-source models. You'll learn why they matter, how to find them, how to run them locally, and how to integrate them into our applications. This opens up a whole new world where you're not tied to commercial APIs. Now, throughout the course, I'll share tips, tricks, and shortcuts you don't want to miss. That's why it's important to watch every lesson in order and code along, especially during the projects. This is a hands-on course, and you will get the most out of it by being active from the very beginning. Oh, and by the way, what you're watching here on YouTube is actually the first two hours of my full 7-hour course. I'm giving you this part for free so you can get a feel for my teaching style and see if you want to go deeper. Next, we're going to set up our development environment. [Music] Before we dive into coding, let's quickly set up our development environment. First, make sure you have the latest version of Node on your machine. So, open up a terminal window and run node-v. Look, on this machine, I'm running node version 22.17. So, make sure you have the same version or higher. If not, head over to node.js.org and download the latest version. Now, for coding, we'll be using VS Code. You're welcome to use your preferred editor, but I highly encourage you to use VS Code because throughout the course, I'm going to show you a lot of cool shortcuts and useful plugins that not only help you write code faster, they also make your job more fun and enjoyable. So, that's all you need for now. Node.js and VS Code. We'll install any other tools as we go through the course. All right, with your environment ready now, let's get started. [Music] Welcome back. In this section, we'll lay the foundation for everything we'll build in this course. We'll explore what language models are, what we can do with them, and how to use them effectively in real world applications. We'll also cover practical concepts like tokens, cost, model selection, and key settings that shape the model's behavior. Even if you have used Chat JP before, this section will give you a solid mental model. So, when we start building, you'll know exactly how and why things work the way they do. Now, let's jump in and get started. [Music] Since Chat JPT came out, the software world has changed fast. New models are being released every month, new tools, new APIs, new expectations, and new job titles. One of the most exciting ones is AI engineer. You have probably seen it pop up in job postings. But what exactly is that? Well, it's not the same as a machine learning engineer. Machine learning engineers build and train models. They clean data, tune architectures, and optimize training pipelines. It's mathheavy and research focused. AI engineers, on the other hand, use pre-trained models, especially large language models, to build smarter applications. They don't need to understand the math behind the model. They need to understand how to use it and how to integrate it into real world apps. It's a lot like using a database. As a software engineer, you don't need to know how MySQL works internally. You just need to know how to query it, structure your data, and build a reliable product. In the same way, as an AI engineer, your job is to understand how to use these powerful AI models to solve real problems. Right now, companies around the world are hiring engineers who know how to build AI powered features. things like summarization, translation, intelligent search, automation, and personalized UX. Let me show you just a few examples. Amazon now shows an AI generated summary of product reviews on the product page. This saves shoppers time and increases conversion by making the buying decision faster. You'll see the same pattern in many other applications where AI is being used to surface quick takeaways from long threads. As another example, Active Campaign, which is a marketing platform, lets marketers use AI to generate full email campaigns with just a few prompts. Instead of starting from scratch, they get instant draft content they can publish and send. Here's another example. On Twitter or X, if you see a post in another language, you'll often see a translate link. Behind the scenes, a large language model detects the language, determines your local, and generates a translated version instantly. This feature is becoming standard across social platforms and news applications. Here's another example. Platforms like YouTube and Twitch use AI to automatically flag things like spam, hate speech, or inappropriate content. It helps keep communities safe without needing thousands of human moderators watching everything in real time. Here's another example. Freshesk, which is a customer support platform, uses AI to automatically categorize, prioritize, and route incoming support tickets. So instead of agents manually sorting through every request, the system sends each ticket to the right team. And that means agents spend less time organizing and more time solving. Let's look at another example. On Redfin, which is a platform for finding homes, when we are viewing a property listing, there's a built-in chat assistant that can answer questions about that specific property. So, instead of waiting to talk to an agent, users can get the basic info they need right away. And these are just a few examples. The possibilities are endless. Everyday developers are adding smart features like these into their applications. Not just for novelty, but to save time, reduce costs, and build smarter, more helpful experiences. I believe that going forward, every software engineer will be expected to know how to work with AI models just like we're expected to work with databases today. You will need to know about large language models or LLMs, prompt engineering, retrieval, augmented generation or rag, vector databases, building agents, and so on. This course is your first step into that world. So, if you're a developer and you want to keep up with where the industry is headed, you're in the right place. In the next lesson, we'll break down what a large language model actually is in simple practical terms. [Music] Now that you understand why learning AI matters, let's start unpacking the fundamentals. In this lesson, we're going to answer a basic but important question. What is a large language model? Let's break it down. At its core, a language model is a system that's trained to understand and generate human language. There are several language models available today. Some are commercial like GPT by OpenAI, Gemini by Google, Claude by Anthropic, Grock by XAI which is Elon Musk's company. We also have open- source models like Llama by Meta, Mistral by European company also named Mistl and many many more. They're called large because they're trained on massive amounts of text. Everything from books and articles to forums, code, documentation, and more. Through this training, they learn statistical patterns in a language. Things like grammar, sentence structure, tone, common facts, and phrasing. So when we prompt an LLM with, let's say, the capital of France is, it doesn't look up the answer. It simply predicts what a helpful response should look like based on patterns it has seen during training. It's like autocomplete but on steroids. In practice, a large language model is a giant mathematical structure, usually multiple gigabytes in size, made up of billions of parameters. Those parameters represent patterns in language like grammar, facts, tone, and style. These models don't understand language the way we do. They don't have beliefs or intelligence. They're just very good at predicting what comes next. The output is often so well written, so fluent on structure that it feels like there's intelligence behind the scenes. But there isn't. It's just mass and probability based entirely on training data. That's why if you ask chat GPT the same question multiple times, we'll often get slightly different answers. It's not repeating a stored response. It's generating new output each time based on likelihood, not truth. And that brings us to a very important point. Because these models don't understand what they're saying, the quality of training data is everything. If a model is trained unbiased, inaccurate, or lowquality data, its responses will reflect that. That's why some models appear politically biased or why some models give completely false answers with total certainty. It all comes back to the data. These days, many people use language models to generate code and it's impressive at first. But here's the issue. These models are trained on billions of lines of code from public repositories including GitHub. And a huge portion of that code is poorly written, outdated, filled with antiatterns or just broken. The model doesn't know that. It simply learns what's common, not necessarily what's correct or maintainable. So when it generates code, it might look clean, sound confident, even compile, but it could be buggy, insecure, or full of bad practices. That's the danger of blindly trusting model generated code. We get something that looks professional but isn't always reliable. So once again, I want to emphasize that training matters a lot. A model is only as good as the data it's trained on. Garbage in, garbage out. If it learns from clean, highquality code and accurate language data, it performs well. If it trains on messy, biased, or incorrect data, the responses can be misleading or flatout wrong. Now, training a large model from scratch isn't just about data. It also requires enormous amounts of compute power. We're talking thousands of GPUs, weeks, or months of continuous training, and infrastructure that only a handful of companies in the world can afford. That's why most of us don't train models ourselves. As developers, our job isn't to become machine learning engineers. It's to understand how to talk to these models via prompting, how to handle their limitations, and how to integrate them into our applications to build smarter features. Just like we don't need to build our own database engine, we just need to know how to use one. That's the mindset you will develop throughout this course. In the next few lessons, we'll dig deeper into how these models work, things like tokens, cost, and how to pick the right one for the job. [Music] So I told you that as a developer you need to learn how to integrate language models into your applications. Now let me show you what that actually looks like. Think about a typical application structure. We have a front end maybe built with React or something similar, a back end, a database for storing our application data and now a language model ready to generate or process content. The LLM is usually not the center of our application. It's a supporting system. We send it input or a prompt. We get a response and use that response to enhance the user experience. And the way we use it depends on our feature. For example, a very common use case is summarization. I showed you how Amazon uses that to summarize reviews. This is getting very common in modern applications. We can also use LLMs for generating content like emails, product descriptions, social media posts and so on. Another common use case is text classification. We can use a model to categorize input. For example, is this spam or not? Is this review positive or negative? Is this support ticket about billing, login or cancellation? We can ask LLMs to generate responses as JSON objects like this. That means our back end can easily parse the response, store it and make decisions based on it. We can also use LLMs for translating text from one language to another. I showed you how Twitter or X does this. Also, the new iOS does that to translate texts in real time. Another great application of language models is in extracting information. For example, we can give an LLM some messy text like a PDF and ask it to pull out structured data like invoice number, amount, names, addresses, and so on. We can also use LLMs to build and integrate chat bots into our applications. We can build chat bots that answer questions based on user data or business documents and so on. All of these use cases follow the same pattern. Text in, text out. We give the model a prompt and it gives us back a response. The response can be plain text. It can be an array, a JSON object, a number, an image, or whatever is useful. Now that you have seen what LLMs can do, let's look at what's actually inside them. In the next lesson, we'll talk about how these models work under the hood. [Music] Now that you know what language models are and what we can do with them, let's take a closer look at something that plays a big role in how we use them effectively, and that's tokens. What are tokens? Well, when we send a prompt to a language model, it doesn't process the input as plain text. Instead, it breaks the text down into smaller units called tokens. These tokens can be whole words, parts of words, punctuation, even emojis or spaces. So tokens aren't the same as characters or words. They fall somewhere in between. To see this in action here on Google, search for OpenAI tokenizer. On this page, you can type a prompt here or click show example. Look, this piece of text has 252 characters and it's broken down into 53 tokens. Down below you can see these tokens colorcoded. So each piece represents a token. Now why does this matter? Because tokens directly impact cost. Let's take open as an example. At the time of this recording, generating 1 million output tokens with GPT40 mini costs 60. With GPT4.1, the same task would cost $8. That's 13 times more. So if you're summarizing long documents or generating large amounts of content, token usage and therefore cost can add up quickly. That's why when choosing a model, cost should be one of the key factors. We shouldn't just go for the latest or most powerful model. Think about what your app actually needs. It's kind of like buying a phone. You don't always need the latest iPhone Pro Max. Sometimes a mid-range phone gives you everything you need. Same logic applies here. So tokens cost money, but there's also a limit to how many tokens a model can handle at once. That limit is called the context window. The context window includes our prompt, which is the input, the model's response, and the chat history. That's if we're building a conversational experience. Again, all of this is measured in tokens. For example, GPT4 Mini has a context window of about 128,000 tokens. GPT 4.1 can handle around 1 million tokens. Mistrol, which is an open-source model, supports around 32,000 tokens. So, if we send a very long prompt and hit the token limit or the context window, the model will stop even in the middle of a sentence. That's why it's important to know how much context our model can handle. But again, we don't always need the largest context window or the biggest model. Mistrol, for example, might be perfectly sufficient for tasks like summarizing a blog post or classifying a support ticket. It all depends on the needs of our application. In the next lesson, I'm going to show you how to count tokens programmatically so we can estimate cost and stay within limits before sending a request. [Music] All right. Now, let me show you how to count tokens in code. So, open up a terminal window. Let's go to our desktop or somewhere on your machine and create a directory called playground. This is going to be our playground project. Next, we cd into this directory and run npm init-y to create a package.json file without answering basic questions about our project like its name, version, and so on. So, here's our package.json file. Great. Now we're going to install a library called tick token. This is the tokenizer used by open AI models. So different AI models, different platforms have their own tokenizer library. Okay, good. Now to open this in VS Code, we're on code space period. Now if this doesn't work on your machine, just drag and drop this directory onto VS Code. All right. Now we add a new file here, index.js JS on the top we import a function called get encoding from tick token. Next we call get encoding and give it an argument. The argument is an encoding. Here we have a few options. These options or these encodings are dictionaries that map token ids to the actual tokens. For example, we might have a token ID let's say 9004 that maps to the word hello. Okay. So we're going to pick CL 100K underline base that is short for chat language and 100K means in this dictionary we have about 100,000 unique tokens. So we get an encoding and store it in a constant. Next we call encoding encode and give it a piece of text like hello world. This is the first test of tick token library. Okay, next we get our tokens and store them in a constant. And finally, we log them on the console. Okay, now let's open up a terminal window here by pressing control and backtick. Now let's run our application by running node index.js. All right, we got a syntax error saying cannot use import statement outside a module. Why are we getting this? Because by default node interprets our JavaScript files as common JS modules. In common JS modules we have a different format for importing functions. So instead of this syntax which is called ES module syntax we have a different syntax which is called common.js syntax. So we have to write code like const get encoding equals require t take token that is the common JS format which is older nobody uses that anymore so to tell NodeJS to use the new format we have to go to our package JSON file we can open it right here package.json JSON, we set the type property to module. Okay, now back to the terminal. Let's rerun index.js. All right, look. We got an array of 13 items where each item is a number. Each number is a token ID that maps to an actual token. So when working with large amount of text, we can use the tick token library to count tokens before sending a prompt to a language model. Hey, just a quick reminder, as I told you at the beginning of this video, what you're watching right now is actually the first 2 hours of my full 7-hour course on building AI powered apps. So once you finish this tutorial, if you want to learn more, check out the link in the description to enroll in the complete course. I would love to see you inside. [Music] These days there are hundreds of AI models out there and new ones are released almost every week. So which model should we choose? There is no single right answer. The model we choose really depends on our application and its requirements. In this lesson, I'm going to give you a framework to make that decision. Now, I'm not going to give you a fixed list of model names to choose because model names change quickly. So instead, we're going to focus on the criteria that matter when choosing a model. The first question we need to ask is how smart does the model have to be? If we want to solve complex problems, we want a model with stronger reasoning. But if we just need to extract text, classify a review, or summarize a short paragraph, we don't need the top tier model. A smaller model is good enough to do the job. The next question is, how fast do we need a response? Bigger models are often slower, especially when generating long outputs. If you're building a real-time user experience, like autocomplete, quick summaries, or short form answers, we'll want a faster model. The next question is, what kinds of input and output are we going to send to and receive from a model? Text is the most common, but newer models can also process images, audio, video, or even a combination of those. These are called large multimodal models or LMMs. So if our application involves anything beyond text, for example, describing what's in an image, then we need a multimodal model. The other factor is cost and I told you that this is based on the number of tokens. So if you're processing long documents or generating a lot of content, cost can add up quickly. The next factor is the context window. We talked about this before. That's how much text the model can process at once. And that includes our input, the model's response, and the chat history. If you're building a conversational experience, if you're summarizing long documents, analyzing code bases, or having long back and forth conversations, we need a model with a large context window. The other factor is privacy. If our application is processing sensitive data like patients, medical records, we probably don't want to send that data to OpenAI servers. This is where open-source self-hosted models can help. We'll talk about that later in the course. Now, to see this in action on Google, search for OpenAI models. On this page, we can see the featured models. At the time of this video, we have GPT4.1, O4 Mini, and 03. Now, up here, we can click compare models and compare these three models or any other models you're interested in. Now look, 03 is their most powerful reasoning model. You can see that indicated down here. But this is also the slowest of all three models. So there is no best single model. If you're building an application that requires solving complex problems, then we need a model with strong reasoning capability. But otherwise, if all we want to do is let's say summarize documents or extract structured data, we can go with a simpler model. Now all these three models as you can see are multimodel models because they support text and image as the input. But for the output they can only generate text. So if you need to generate images in our application then we have to pick a different model. At the time of this video we have a model called GPT image one. Now this model can support text and image as the input but it can only generate images in the output. So it cannot generate any text. Now that aside down below you can see the pricing. We have different prices for input and output. So if we need to process large documents like contracts, cost can add up pretty quickly. So always compare the cost of models and go with the one that fits your application. Now moving on below that we have the context window of these models. So this model has the context window of 200,000 token. This other model has a context window of about 1 million tokens. Now, we also have another factor here that's max output tokens. That's the number of tokens that can be in one response. So, this model, even though it has a larger context window, it can process more text or longer conversations, but each response can be a maximum of 32,000 tokens. In contrast, with this model, our responses can be three times larger. The other factor we have here is the knowledge cutoff and that's when the training of these models stopped. So sometimes you can find older models that don't have up-to-ate knowledge of the world but they could be perfect for your application. So once again there is no best model. All right, we're done with this lesson. In the next lesson we're going to talk about model settings and see how different parameters affect the output. [Music] In this lesson, we'll take a look at the settings that control how a language model behaves. So, here on the OpenAI website, on the models page, let's grab GPT 4.1. On this page, you can see all the details about this model like its level of intelligence, the speed, the price of input and output tokens, as well as the modalities. We can also see the context window, max output tokens and the knowledge cutoff date. Now up here we can try this in the playground. First we have to log in. All right. Here's the model playground. Now the first time you want to use this, you have to add credit to your account. So up here, click the settings icon. Then go to the billing page. On this page, you can add your debit or credit card and add some credit to your account. Once you do that, now let's go back to the playground. So, the model is GPT4.1. We can change this to any models. Now, all these models have a few common settings we're going to talk about in this lesson. The first one is text format. Here we have three options. We have text, which is plain text, as well as JSON object and JSON schema. Let's see the differences in action. So I'm going to go with text and send a prompt like give me three benefits of exercising. So this gives us a short answer in plain text. We have all seen this before. Now let's see what happens if we change this to JSON object. Now we repeat the prompt and say give me three benefits of exercising but we also add as a JSON object. Now take a look. The model generated a JSON object with this format. So we have an object with a single property called benefits of exercising which is an array of strings. Now if the response is not colorcoded on your machine, just click this icon. With this you can toggle between plain text and JSON format. Okay. So JSON is useful if you want to parse the response in our application. But what if we expect a different type of JSON object? So instead of having a property like benefits of exercising, let's say we want to have a property like exercise which would be an object with another property called benefits. This is where we can use a JSON schema. So we change the format to JSON schema. In this box, we should define the shape of our JSON objects. Now this format is a little bit complicated. So it's easier to generate it using AI. Here we can describe the kind of JSON object we expect in the response. For example, we can say generate a JSON object like the following. So we want to have an object. In this object, we want to have a property called exercise which would be an object itself. Now inside this object, we want to have a property called benefits which would be an array. So we give it an example and then have it create this schema for us. All right, look. So here's the name of the schema, exercise schema. And here we have more details about this schema. So this is an object with these properties. In this object, we have a property called exercise, which is an object itself with these properties. In this object, we have a property called benefits, which is an array. Here's a description saying a list of benefits associated with the exercise. Next, we have information about the types of items in this object. So, each element or each item is a string. And here's a description of each element. Next, we have the validation properties like required. So, the benefits property is required. And no additional properties are allowed. Of course, we can always change this to fit our application. So, let's go with the schema. Save. Now we repeat the last prompt and say give me three benefits of exercising as a JSON object. All right, take a look. This time the model generated a different kind of JSON object. So we have this object with a property called exercise which is an object with a property called benefits which is an array of strings. So that's text format. Now let's go back to plain text. Then we have temperature. With this we can control how random or creative the response can be. This is a value between 0 and 2. But we never set it to extreme values. Here's a guideline. We use a low temperature like 2 to4 for logical precise answers like summarization, answering factual questions and so on. We use higher temperature like a value between 7 to 1.0 zero for creative expressive tasks like brainstorming, writing, marketing, copy and so on. So it's best to stick to this range. Don't go with extreme values like zero or two because the model can go crazy. Let me show you an example. So here we have set the temperature to two. Now let's say write a story about a robot. Look what happens. The model starts generating a story about a robot. But as we progress, look, it's generating gibberish. There is nonsense coming out because the model is getting extremely creative. This is the problem with really high temperatures. So, a good rule of thumb is to set it to 7. This is a good balance between logical and creative responses. Next, we have max tokens and this sets the maximum length of the response. Now, the value we set here really depends on what problem we're trying to solve. If you want to generate something short like a tweet, we have to go with a lower value. Otherwise, we may waste our tokens and pay more than we need. But when using lower values, keep in mind that the response can be cut off mids sentence. Let me show you. So, I'm going to set max tokens to 50. Now, once again, we're going to say write a story about a robot. All right. So, it says in the quiet town of Maplewood, there was a small robot named Pixel. Pixel was built by a kind inventor, Mrs. Rivera, who wanted to help. But look, the sentence is cut off. So to prevent this, we have to be more precise with our prompt. This is one of the prompt engineering techniques. There are many more techniques we'll cover later in the course. So here we can say, write a story about a robot in 50 tokens or less. Write a complete answer without cutting off mid sentence. All right. Now, with this second story, look, it's saying, "From that day on, Orbit became the twin's favorite friend. Always helping those in need. Robot heart glowing with happiness." Beautiful. So, that was Max tokens. We also have top P. This is another way to control randomness, but it works a bit differently than temperature. Let's say as part of generating the response, the current token is ant. And here are all the possible options for the next word. Now next to each token you can see its probability based on the training data. If we set top P to one, we tell the model to use the full range of possibilities. So any of these words or any of these tokens can be used to generate the response. But if we use a lower top P like.3 that makes the model focus only on the most likely next words. So once again, top is another way to control randomness. It works differently from temperature. In practice, we usually change one or the other, but not both. If you're not sure which one to use, stick with temperature and set top P to one. So these are all the common settings. We also have store logs which is used for logging and debugging. By default, it's enabled which means all our prompts will be logged on OpenAIS servers. To see them, we go to the dashboard. Then we go to the logs. On this page, you can see all the prompts we have sent to OpenAI. We have the input, the output, the model, and the date time. If we click any of these items, we can see more details. So up here we can click details. We can see the exact day time as well as the ID of the response. So each response has a unique identifier and this is useful for creating the conversation state. So the model remembers our previous responses. We'll talk about this later in the course. We can also see the model that was used, the number of tokens, the response format, max output tokens, temperature, and so on. [Music] All right. Now, let me show you how we can call models in code. To do that, first you have to create an API key. So, on the top, let's go to the settings page. Then, we go to API keys and create a new secret key. We give it a name. This could be the name of our application like my playground app. Next, we assign it to a project. We have the default project, but we can also create multiple projects and assign different keys to different projects. Now, let's create the key. Good. Let's copy this back to VS Code. We remove all the code here and declare a constant called OpenAI API key. Reset it to this key. Now I got to emphasize this is just for demonstration. In a real application, we should never store API keys in the source code because with that anyone who has access to your source code can use your API key and you'll be the one paying for it. So as a best practice, we should always store the keys outside of our source code using environment variables. We'll talk about that later when we start building projects. Next, we should install the OpenAI library. So we open a terminal window and run npm install open AI. All right, good. Now this library is just a wrapper around open AAI API. So it gives us a class with a bunch of methods that we use behind the scene. It's going to make HTTP calls to the API exposed by OpenAI. If you go to the docs and look at the libraries page, you can see that they also have official libraries or SDKs for JavaScript, Python, Net, Java, and Go. There are also a bunch of libraries built and maintained by community for other languages. So back to the code on the top, first we import the OpenAI class from the OpenAI module. Next, we create an instance of this class. So we declare a constant called client because this is a client to open AAI platform. We set it to a new instance of open AAI and provide an object and here we set API key to open AAI API key. Next we call client responses.create and give it an object. Here we can set the model to let's say GPT-4.1. We set the input to our prompt like write a story about a robot. We can also set the other settings we talked about in the previous lesson like temperature. Let's set it to 7. And we set max output tokens to let's say 50. Now this method returns an API promise. So we have to await it to get the response. So let's await this and get the response. And finally we log the response on the console. Okay. Now back to the terminal. Let's run node index.js. Now the terminal freezes because we are waiting for the response to be generated. But later we'll enable streaming so you can see the response as it's being generated. Okay. Now here we have a bunch of properties in the response. The one we use most of the time is output text. This is the response generated by the model. But we also have a few other useful properties. We have usage where we can see the number of input and output tokens. Now in this case I'm not entirely sure why input tokens is zero but output tokens is 50. We also have top P which is set to one by default. We have temperature. We have store. So this response is logged on OpenAI servers. And also up here we have the unique identifier for this response. Later when we build a chatbot, we'll use this to maintain a conversation state. So the chatbot remembers the conversation history. Now back to the code, let's see how we can enable streaming. To do that, first we set stream to true. Now to see this clearly, let's increase max output tokens and set it to 250. Now when we set stream to true, we no longer get a response object. Instead, we get a stream object. So let's rename this by pressing F2 to stream. Now this stream is what we call an async iterable. What does it mean? Well, an iterable is an object that we can iterate over like an array. So here we use a for loop and say for const event of stream. So we are iterating over the stream getting one event at a time. Now I told you that this stream object is an async iterable. So to iterate over it we have to use the await keyword because these events are generated at runtime. So we don't get them all in one hit. We get them as they are being produced. Okay. So, we iterate over the stream object and then log the event on the console. Now, back to the terminal. Let's rerun our program. All right. Now, look, we're printing these event objects as we are receiving them. Let's scroll off and take a look at a few of them. So, look, each event has a type property. In this case, the type is response.output text.ta. This is the event that represents a chunk of text or a token being generated at runtime type. Each of these events has a sequence number. So this is 252. Next one is 253. Here we have a delta property that is the token that is being generated. So here's one token. Then we have another token. So to print the response in the terminal as it's being generated, we just have to print the delta property. So back to the code, let's print event.ta and rerun our program. So these are the tokens that are being generated. But the problem is at the beginning and at the end we get a bunch of undefined messages in the terminal. The reason for that is because not all events contain the delta property. The delta property only exists in events that contain a chunk of text being generated. But we have other events that represent the beginning and the end of this operation. So the proper way to do this is by checking if event delta is defined then we print it on the terminal. So let's rerun our program. Okay, we're getting this tokens. No more undefined messages. Beautiful. But we don't want to print each token on a new line. The reason this happens is because console.log log always adds a new line character at the end. So to print these tokens next to each other, we have to take a different approach. We have to call process std out which represents the standard output or the console window. This object has a right method. We call this and pass the delta. Now let's rerun our program. Okay, this is the same experience we have when we use chat GPT. So that brings us to the end of this section. In the next section, we'll start setting up a modern full stack project. So, I will see you in the next section. Welcome back. Before we start building, we need to set up a clean, modern, full stack project. One we'll use as the foundation for everything in this course. Now, if you have done any research, you have probably seen tons of templates and GitHub starters for full stack applications. And while some of them are great, I decided not to use any of them. I didn't want this course to depend on someone else's setup or introduce tools we haven't covered. Also, we will not be using Nex.js. In case you don't know, it's a powerful full stack framework built on top of React, but not everybody likes it and it comes with its own learning curve. I didn't want this to be a prerequisite for this course. So, instead, we'll set everything up from scratch using tools like Bun, Vit, and Express. This gives us full control. no hidden magic and a setup that's easy to understand and easy to scale. Along the way, we'll add Tailwind for styling, set up SHA CN UI for components, format our code with prettier, and automate our workflow with Husky. By the end of this section, we'll have a solid full stack foundation that's lightweight, clean, and fully ours. Now, let's jump in and get started. Before we start creating our project, there is a tool I want to introduce that we'll use throughout the course and that's bun. If you haven't heard of it before, bun is a modern JavaScript runtime kind of like Node.js but faster and more integrated. With Node, we typically rely on multiple tools. We use npm to install packages, TS Node to run TypeScript, and something like Nodemon to restart the server when we make changes. With Spun, we get all of that in one tool. It's a runtime, a package manager, a taskr runner, and even a TypeScript transpiler allin one. So, it can run TypeScript files out of the box. And we don't need to install a bunch of extra tools just to get started. Now, if you're more comfortable using Node, that's totally fine. Everything I'm going to show you can be done with Node as well. But if you follow along with Bon, you will probably find the experience cleaner and honestly, a lot more enjoyable. So, head over to bond.sh. And here on the homepage, find the installation instruction for your operating system. Just copy this command and run it in a terminal window. Now follow the instructions in the terminal. So here on Mac, we have to execute this command. Exec/bin/zsh. Now to verify that bon is installed properly, we run bon- version. So on this machine, I'm running bun version 1.2.17. In the next lesson, we'll talk about our project structure. [Music] Now, to create our project structure, we open a terminal window. We go to somewhere on our machine. I'm going to go to my desktop. Next, we create a directory. Let's call it my app or whatever you want. We cd into this directory and run bun in it. This is the same as npm in it. So, it creates a package.json JSON file as well as some additional files. Let's go ahead. First, we answer this question to select a project template. We have blank, react, and library. Let's select blank. So, this created a few files. We have a git ignore file, a rule file for the cursor editor, an index file, a TypeScript configuration file, and a readme file. It also installed TypeScript. So, now let's open this with VS Code. So, here's what we get. We have a directory for the cursor editor. I'm not using cursor, so it's safe to delete this. We have our node modules directory, a git ignore file, a bond lock file, an index file, which is just a console lock statement, our package json file just like a node project, a readmi file, and a typescript configuration file. Now to set up a full stack project, we're going to use something called a workspace, which is a feature built into bun that lets us manage multiple sub projects like a client and a server application from a single place. It's also available in node projects. So by convention, we put our sub projects inside a directory called packages. So here we add a directory called packages and then we add a subdirectory for our client app and one more for our server app. Next we go to our package.json file and declare our workspaces. So here we add a new property called workspaces and set it to an array of strings. Here we type the path to our sub packages. So we go to the packages directory and grab the client directory and one more for the server directory. Now there's a shorthand syntax here. We can replace client with an asterisk to say all directories under packages should be treated as workspaces. So let's delete the second entry. This is good. So our project structure is ready. Over the next few lessons, we'll create the client and server applications independently. Now I also want to initialize a git repository here. So let's open a terminal window and run git in it. Good. And make our first commit. Initial commit. Next we'll create our backend project. [Music] Now to create our server application here in the terminal we go to the packages/server directory and run boninit one more time to create the sub project in this directory. We select blank. Now back to our project here in the server directory. We have the same files you saw in the previous lesson. We don't need the cursor directory. So let's get rid of it and clean up our project. Now back to the terminal. Next we shall install express as our web server. In node projects we run npm install or npmi. In bun projects we run bun at. So with node projects we have two different tools. Node for running our code and npm for installing dependencies. But in bun projects all these features are integrated into bun. So we run bun at express. Okay. We should also install express types for TypeScript as a development dependency. To do that, we run bun at-d types/express. Good. Now back to our project. Look here in the server directory, we have this package.json file. And in this file, we have express as a dependency and also express types as a development dependency. So in this project so far we have two separate package.json files one in the root directory and one inside the server directory. Later when we create the client project we'll also have a package.json file in our client directory. Okay. Now what is interesting about this structure is that in this setup we don't have different node modules in our server and client applications. So we don't have a node modules directory inside the server directory. We only have one at the top level where we have all the client and server dependencies. So right now we have express as well as all its dependencies installed in this directory. Okay. So we have installed express. Now let's create a basic web server. So we go to the server directory and open index.ts. Here on the top first we import the express function from the express module. We call this function and get an object which we call app. Next, we declare a constant called port. We can initialize it from an environment variable. To do that, we use process.n.port. So, if we pass port as an environment variable, we can pick it up here. This is useful in production environments. But otherwise, if this envi
Original Description
This AI course teaches you how to build AI-powered apps with React & Express. You’ll learn about LLMs, prompt engineering, and full-stack AI integration.
🚀 Want to dive deeper?
- Get the full course: https://mosh.link/build-ai-powered-apps
- Subscribe for more videos like this: https://goo.gl/6PYaGF
💡 Related tutorials
https://youtu.be/SqcY0GlETPk?si=ALGbprFSjzSnVfms
https://youtu.be/d56mG7DezGs?si=NamrMlwEwC99MIfQ
✋ Stay connected:
- Full Courses: https://codewithmosh.com
- Twitter: https://twitter.com/moshhamedani
- Facebook: https://www.facebook.com/programmingwithmosh/
- Instagram: https://www.instagram.com/codewithmosh.official/
- LinkedIn: https://www.linkedin.com/school/codewithmosh/
📖 Chapters
0:00:00 Welcome
0:01:26 Prerequisites
0:02:21 What You’ll Learn
0:06:15 Setting Up Your Development Environment
0:07:12 Introduction to AI Models
0:07:48 Rise of AI Engineering
0:11:49 What Are Large Language Models?
0:16:12 What Can You Do With Language Models?
0:18:37 Understanding Tokens
0:21:40 Counting Tokens
0:25:43 Choosing the Right Model
0:30:45 Understanding Model Settings
0:39:32 Calling Models
0:47:07 Setting Up a Modern Full-Stack Project
0:48:19 Setting Up Bun
0:49:51 Creating the Project Structure
0:52:39 Creating the Backend
0:59:18 Managing OpenAI API Key
1:04:33 Creating the Frontend
1:07:18 Connecting the Frontend and Backend
1:12:31 Running Both Apps Together
1:15:55 Setting Up TailwindCSS
1:19:30 Setting Up ShadCN/UI
1:26:00 Formatting Code With Prettier
1:31:02 Automating Pre-Commit Checks With Husky
1:37:53 Project: Building a ChatBot
1:38:22 Building the Backend
1:38:58 Building the Chat API
1:45:25 Testing the API
1:47:22 Managing Conversation State
1:53:44 Input Validation
1:59:33 Error Handling
2:01:52 Refactoring the Chat API
2:04:00 Extracting Conversation Repository
2:09:21 Extracting Chat Service
2:16:05 Extracting Chat Controller
2:20:03 Extracting Routes
2:24:55 Building the Frontend
#ai #aiappdevelopment #aicourses
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Programming with Mosh · Programming with Mosh · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
6 Visual Studio Tips to Increase Your Productivity | Mosh
Programming with Mosh
Visual Studio Keyboard Shortcuts that Speed Up Debugging Applications | Mosh
Programming with Mosh
Backbone.js Tutorial Part 2 - Backbone.js Models: Working with Model Attributes
Programming with Mosh
Backbone.js Tutorial Part 3 - Backbone.js Models: Model Validation
Programming with Mosh
Backbone.js Tutorial Part 4 - Backbone.js Models: Model Inheritance
Programming with Mosh
Backbone.js Tutorial Part 1 - Backbone.js Models: Creating Models
Programming with Mosh
Backbone.js Tutorial Part 5 - Backbone.js Models: Syncing Models with the Server
Programming with Mosh
Backbone.js Tutorial Part 6 - Backbone.js Collections: Creating Collections
Programming with Mosh
Backbone.js Tutorial Part 7 - Backbone.js Collections: Working with Collections
Programming with Mosh
Backbone.js Tutorial Part 8 - Backbone.js Collections: Fetching Collections from the Server
Programming with Mosh
Backbone.js Tutorial Part 9 - Backbone.js Views: Creating Views
Programming with Mosh
Backbone.js Tutorial Part 10 - Backbone.js Views: Passing Data to Views
Programming with Mosh
Backbone.js Tutorial Part 11 - Backbone.js Views: Handling the DOM Events
Programming with Mosh
Backbone.js Tutorial Part 12 - Backbone.js Views: Handling the Model Events
Programming with Mosh
Backbone.js Tutorial Part 13 - Backbone.js Views: Handling Collection Events
Programming with Mosh
Backbone.js Tutorial Part 14 - Backbone.js Views: Templating
Programming with Mosh
Clean Code: Learn to write clean, maintainable and robust code
Programming with Mosh
C# Events and Delegates Made Simple | Mosh
Programming with Mosh
C# Generics Tutorial: Whats and Whys | Mosh
Programming with Mosh
Debugging C# Code in Visual Studio | Mosh
Programming with Mosh
Repository Pattern with C# and Entity Framework, Done Right | Mosh
Programming with Mosh
Angular 2 Tutorial for Beginners: Learn Angular 2 from Scratch | Mosh
Programming with Mosh
Architecture of Angular 2+ Apps
Programming with Mosh
Working with Components in Angular
Programming with Mosh
C# Tutorial For Beginners - Learn C# Basics in 1 Hour
Programming with Mosh
Difference between Junior and Senior Developers
Programming with Mosh
Step-by-step ASP.NET MVC Tutorial for Beginners | Mosh
Programming with Mosh
[Pluralsight]: Become a Full-stack .NET Developer
Programming with Mosh
Xamarin Forms Tutorial: Build Native Mobile Apps with C#
Programming with Mosh
Value Types and Reference Types in JavaScript
Programming with Mosh
Using Redux in Angular 2+ Apps | Mosh
Programming with Mosh
Testing Angular 2+ Apps with Jasmine and Karma | Mosh
Programming with Mosh
Profile and optimize your Angular 2 apps
Programming with Mosh
Build a Real-world App with ASP.NET Core and Angular 2
Programming with Mosh
Entity Framework 6 Tutorial: Learn Entity Framework 6 from Scratch
Programming with Mosh
Two-way Binding and ngModel in Angular 4
Programming with Mosh
Udemy Live 2017: Teaching Tech Panel
Programming with Mosh
Demo of An E-commerce App Built with Angular, Firebase and Bootstrap 4
Programming with Mosh
My Brand New Angular Course
Programming with Mosh
TypeScript Tutorial - TypeScript for React - Learn TypeScript
Programming with Mosh
Access Modifiers in TypeScript
Programming with Mosh
TypeScript Interfaces
Programming with Mosh
TypeScript Classes
Programming with Mosh
TypeScript Constructors
Programming with Mosh
TypeScript Properties
Programming with Mosh
Angular Tutorial for Beginners: Learn Angular & TypeScript
Programming with Mosh
AngularJS vs Angular 2 vs Angular 4 | Mosh
Programming with Mosh
Angular Material Tutorial | Mosh
Programming with Mosh
Angular Animations Tutorial | Mosh
Programming with Mosh
Firebase in Angular Applications | Mosh
Programming with Mosh
Deploying Angular Applications | Mosh
Programming with Mosh
Building Forms in Angular Apps | Mosh
Programming with Mosh
Directives in Angular Applications
Programming with Mosh
Routing and Navigation in Angular | Mosh
Programming with Mosh
Angular 4 in 40 Minutes
Programming with Mosh
[NEW COURSE] Unit Testing for C# Developers
Programming with Mosh
Unit Testing C# Code - Tutorial for Beginners
Programming with Mosh
C# Classes Tutorial | Mosh
Programming with Mosh
C# Object Initializers Tutorial
Programming with Mosh
C# Constructors Tutorial | Mosh
Programming with Mosh
More on: LLM Foundations
View skill →Related Reads
📰
📰
📰
📰
Node.js Error Handling Patterns for Production Queue Systems
Dev.to · Faisal Nadeem
Make Your CLI Config Write Survive Ctrl-C Without Leaving Truncated JSON
Dev.to · Sam Rivera
Code Review Habits That Actually Stick
Dev.to · Code Atlas
Timeout Tuning for Proxy-Routed Requests: Why Default Values Are Almost Always Wrong
Dev.to · Sota Support
Chapters (38)
Welcome
1:26
Prerequisites
2:21
What You’ll Learn
6:15
Setting Up Your Development Environment
7:12
Introduction to AI Models
7:48
Rise of AI Engineering
11:49
What Are Large Language Models?
16:12
What Can You Do With Language Models?
18:37
Understanding Tokens
21:40
Counting Tokens
25:43
Choosing the Right Model
30:45
Understanding Model Settings
39:32
Calling Models
47:07
Setting Up a Modern Full-Stack Project
48:19
Setting Up Bun
49:51
Creating the Project Structure
52:39
Creating the Backend
59:18
Managing OpenAI API Key
1:04:33
Creating the Frontend
1:07:18
Connecting the Frontend and Backend
1:12:31
Running Both Apps Together
1:15:55
Setting Up TailwindCSS
1:19:30
Setting Up ShadCN/UI
1:26:00
Formatting Code With Prettier
1:31:02
Automating Pre-Commit Checks With Husky
1:37:53
Project: Building a ChatBot
1:38:22
Building the Backend
1:38:58
Building the Chat API
1:45:25
Testing the API
1:47:22
Managing Conversation State
1:53:44
Input Validation
1:59:33
Error Handling
2:01:52
Refactoring the Chat API
2:04:00
Extracting Conversation Repository
2:09:21
Extracting Chat Service
2:16:05
Extracting Chat Controller
2:20:03
Extracting Routes
2:24:55
Building the Frontend
🎓
Tutor Explanation
DeepCamp AI