I've been doing a lot of f coding recently and I'm completely convinced that AI is completely changing the game for building apps or software in general actually. And so in this video I want to walk you through how I plan and build an app from scratch. It's going to be a simple app, a daily joke app and I'll show you some of the tools that I like to use, some best practices, some of the pitfalls you want to avoid so you can use AI for your coding to its full potential. So let me quickly give you an overview of the tools that I like to use. So I have a code editor called cursor open here and that's what I will use in the video. But there are other code editors out there as well that also have AI features and that are also really good. So I actually also like to use Visual Studio Code with GitHub Code Pilot is a really good combination as well and Windsurf is actually also a very popular AI code editor tool. Now in this video I will stick to Cursor. There are some other tools as well that you will see mentioned very often. So these are V0 bolt and love bowl as well. These are all really good to quickly try out some idea you may have. Maybe do some prototyping or just quickly see if the idea that you have if that is feasible. Let's say these tools are really good but I do find that at some point you need to jump out of them into an actual code editor like cursor or visual studio code or win serve. So I would say these are a good place to start and if you have a reasonably simple app you can even create the entire app in one of these tools. But for something that's a little bit more sophisticated, I find that I have to go to an actual code editor where I have maximum control. So I typically don't use this as often as some of these other tools. If you have an idea, maybe you want to draw it out first yourself, you can use Figma for that. They make it easy to create a visual design of your app and then later you can implement that in cursor. I like to use Nex.js for my apps. Next is a so-called full stack framework. So you have a front end as well as a back end together in one app. Essentially it simplifies a lot of things. But it is a little bit harder to do certain things in Nex.js. For example, what if you want to have an API server that also services a mobile app, right? Next.js is a fullstack web framework. So if you also want to service a mobile client, let's say, that's a little bit harder to do. Also things like background jobs like a chron job. Basically I want to do something every hour or so. That's also a little bit harder to do in X.js. Also pub sub. Also, if you want to have some kind of microservices setup, that's quite hard to do with Nex.js as well. It's all one app. It's all JavaScript or TypeScript. So, if you want to use Go or some other technology, that's going to be a problem. So, I've actually really enjoyed working with Encore. They are today's sponsor. They make it very easy to create a backend application. And in this video, I'll show you how to use that in conjunction with Nex.js. So, we'll have Nex.js as our main app and then we'll have a separate backend created with Encore. Encore fits in really nicely in this AI stack. Actually, they also have these cursor rules that we can use. Makes it super fast to create highly sophisticated applications actually. All right. So, we want to build an app and it all starts with an idea. So, our idea is a an app and it just displays a joke and it's a different joke every day. Hopefully, we get some people coming back every day, right? Just a simple app and I want to build it as much as possible with AIS. So, what would that workflow look like? So, we could use one of those tools to sketch it out or use like VZ to prototype something. I often skip those tools. So, so where would I start? Well, some people talk about creating a so-called product requirements document. So, basically a specification of how the app should be structured. You can do this in chat GPT some kind of chat model. Let me actually uh see what we get here. Now, in my view, this is not absolutely necessary. In many cases, in the beginning of a project, it's just an idea that you have. You don't know exactly what it should be yet. it's probably still quite a vague idea. So, you don't know the exact features it should have or the exact tools that it should use. So, actually, um it may actually harm you to have a very specific outline because you may be adding a bunch of things to your app that you're not going to need, which may slow you down actually. So, in my view, this is not as important to getting started with an app. In fact, I think you can skip this. Now, if you have fleshed out your idea a lot, you know exactly what it should be. Yes, in that case it can help out because because you can feed this into cursor's AI here and the AI will be guided by the requirements that are specified here. So it will do almost exactly what you want, right? So this PRD is just going to be an overview of what the app is about, the description, what are the goals of the app, who should be using this app, who are the primary users, what are the key features, right? So it already comes up with some ideas as well. So actually it's nice to maybe quickly get some suggestions on your idea, some user stories. So basically what are some practical things that a user may want to do in the app. All right. So then the functional requirements are important here. Um because the AI is going to create a bunch of code related to this, right? So you can see it already adds a bunch of things. Yeah. So here we have a lot of things actually. Now you could actually just copy this and now we can go inside our AI code editor. I'm using cursor for this video, but the other ones work great as well. And currently my project is empty. So I could open up this chat, right? I can open up this AI pane here and I can say scaffold an app with this PRD and I could dump all of that in here. If I would press enter now, it would create a lot of things that were all specified in the PRD. Now, as I said, I'm not the biggest fan of this because in the beginning, we don't know exactly yet. We don't know exactly if we if we want to have push notifications, right? So, it's a bit of an overkill in the beginning in my view. So, where would I start? Well, I want to use Next.js. Actually, that's where I would start. I want to create a basic next.js boiler plate. I can do it through the chat. So, I could say something like create a Next.js app. However, I would actually like to do this manually myself. If I open up the terminal here, new terminal, I can do it myself here. So I could say mpx create next app. You can look this up. I can say the latest version and this would create a new next.js app folder and then put everything in a new folder which is kind of annoying because I already have a folder. I opened it in the code editor already. So I can add a period at the end. So it will actually just directly put everything in this folder. So let's actually start there. So I like to do it this way because uh this has basically zero margin of error. I'm going to get the exact next.js as starter that I want here. Very basic with no frills added. Whereas I do find sometimes if you try to if you try to go with an AI agent, it may sometimes add things that I don't want or it may use a different version than I want. It may use slightly different commands that I'm that I was actually looking for. And this is so important that I essentially want to have zero margin of error. So I want to use TypeScript. Yes. Yes. Yes. Yes. App router. Yes. Turboac. Yes. No. All right. All right. So now it's going to set up my NextJS app here. All right. So then I can close the terminal. And now from this point onwards I would mostly use the chat here to make changes to the app because now I have the setup here. This is uh this is exactly what I want. So now I want to run the app. I could actually just say here in the chat run the app. Depending on which code editor you use, you may not have unlimited uh requests. So for simple requests you may actually want to do it yourself. So I do maybe want to open up terminal again. Let me close this one. And I can say mpm rundev. That's how you would start a nextjs app, right? So mpm rundev. Okay. So now my nextjs app is starting. I can see where it's running. I can click on this one. All right. So here I have my nextjs app running. I see the homepage here which is this page over here. You can see nextjs has some starter here. The first thing I like to do is actually just remove a bunch of things here and just clear this out because our idea is a bit different because we have a different idea. So from this point onwards I would use this chat with the agent mode here a lot. So for example here we would have still the boiler plan right the title of our app. We would want to change this perhaps. Now I could manually change it. We could say something like change the metadata to be about a daily joke app. Right? So cursor as of recording has the following options here. So they have agent mode. So basically before you had to pick whether you just wanted to ask a question and it would just give you an answer here in the chat window or if it should actually edit some code over here. Now you actually have agent mode and it will decide automatically for you whether it should edit code or just give you an answer basically. And let me actually show you what it will do. So if I send here you will see that um it it's changing my code here in the code editor. So it has decided to invoke a edit tool here. Okay. And then I can view the changes it made. Now typically I accept this very quickly. So I will just accept here updated update here in nextJS. You will see that title here at the top of the tab. Right? And also and also if it's ranking on Google the description will be displayed there. Right? So just quickly show you here in cursor. So I can create a new chat here to clear out that previous contact. So that's agent mode. Now it's using AI under the hood. Right? So the way this works is that cursor will take your message that you wrote here. It will take that message. Maybe it adds some other things under the hood. It may do something with that but ultimately it will send it to open AI or anthropic right so open AAI offers these three models 01 GPT 40 which we can also use inside their own app chat GPT. I was actually using 01 in chat GPT and there's also anthropic uh with with their cloth model right. So these are all really good. So these are at as of recording the some of the cutting edge models. Cursor right now automatically selects the right model for us. However, we can also pick the model ourselves if we want. But you can see it's it's all auto selected and I've had great results for that. So that's okay with me. Now I can also add an image here. So maybe if you have an error in your app, let's say you can take a screenshot and then add it here. So you can uh maybe so then it's clear to cursor or the a or the underlying AI models what the issue is. And then here on top actually we have something that's really important which is the context. So if I say something like uh change the metadata what we just did to a daily joke app to be relevant for a daily joke app. If I don't add any context it doesn't really know where or what this is about. Right? So it may actually start a search by itself. But if you know where it should be edited it's better to attach that file as the context here. So I know in nextJS the metadata here is in layout. So I would add the layout file here. So then the content of this file will also be potentially sent to the AI model under the hood including the message you wrote here. So then cursor can get the result and change the relevant part of this file. So you can see that cursor actually got it right in the first try. Now sometimes it will not be the exact result that you want. So for example, if I say something like create a new react component for a joke cart. Let's say if I do something like this, let's see what we get. I didn't attach any context. I also didn't specify um what kind of conventions to use. So here it prompts me to run a command. So it wants to create a components folder which I didn't specify but that's actually fine with me. Yes. So it will create a components folder to put in all the components. And here it now has created a component here. Let's see what we get. Um you can see it already starts to use a different tool here called framer motion. And so this is already pretty uh important decision actually. So this is not something you would lightly add. And also it has created this file using uppercase for the J and the C. And actually what I would prefer is all lower case with a hyphen. My kebab case I actually prefer that convention prompt like this and you do not have any cursor rules. You may get a bunch of things in the result that you don't want or need. So I in this case would really like not to have additional tools suddenly being used. And also I want to use a different convention for naming the files which actually turns out to be what I want but you can imagine that in other cases where it creates new folders all of a sudden that may not be what you want. So we want to steer the AI in the right direction. So I actually find that cursor rules are really helpful with this. So cursor has some information on the website about the rules. We can have global rules for all our projects. So I can go to my settings here. Uh let me close this. So here we have uh some general rules. We have our features here. We have models. We have So here we have rules. Now here they call it user rule. My uh understanding is that those are the global rules. But here we have project rules. So these are going to be specific to our daily joke app project. Let's actually do that. So add a new rule. I can give it a name. Let's call it uh component names, right? Component file names actually. So I will press enter here. Okay. So I get a so-called MDC file. Let me close this. And it puts that in a new folder called cursor slash rules. And then we have a new file here with the following name. So basically whatever I put here will also be sent to the AI model. So not just my prompt and the context the file that I add but also a rule here. So it knows the format for example to process the result. So what I would want here is always use kebab case for new component file. Right? So very simple but just to demonstrate how this would work. Now this rule if I open up my chat here and start a new chat. So now when I say something like uh create create a new component a joke card. So let's actually remove the one that it already created for us. So I will actually leave the components folder but I will delete this uh component. So we want to make sure that now when I run this it will have the kebab case but also don't use additional third party tool right this is maybe a little bit fake but just to demonstrate how this would work. So now I want it to take this rule into consideration when we send off a request like this. Now it allows us to specify when this should be added. This is a small rule file. So actually I think it makes sense to always add this cuz it's not going to pollute the contact too much the context too much. You may also want to go for autoattached. So in that case you have to specify for which files this is relevant or agent requested. So then you have to give it a description and then cursor can decide if it's relevant or manual. So in that case I have to manually add the context here just like you would add a file. I actually find that this is a bit risky because you often forget to add it. So if you can I do like to add to always add it. Now if you have a massive file here and you're always adding this I would be a little bit more hesitant to always add it. But for a small file this should be fine. So now let's see what we get. So now let's try that again. Create a new component for a joke card. Okay. So it should Okay. So uh it's going to do its thing again. All right. So now we get a new component and you can see it's using joke-cart the kebab case that I like to use for my file names. And you can see it's not using frame motion here. It has not added any third party tools all of a sudden. Right. So with these cursor rules we can guide we can steer the AI we can guide the AI into the direction that we want. There are some other things that I personally do not like. I don't like to have types like this. React.fc. It's a bit of an old school way of typing these react components and probably it has to do with these AI models. They are trained sometime in the past, right? So they have a cutoff day. They may be trained a year ago or half a year ago. And so now we are working with these AI models. And so when they have to type these props as it's called, they're going to use what was popular at that point in time. However, these days, I would say it's more common to have the types like this, right? So, we I like to use joke card props. I actually like to use a type instead of interface and then I would do something like this. I think this looks a bit cleaner, but this is also personal preference to a certain degree. And I could also add that as a cursor rule. All right. So, I could specify that maybe in a new file or have one big file for coding conventions or something like that. Do you have to come up with these cursor rules all by yourself? And actually, no. There are some people out there that have already created them for you and they have shared it online. So there is a GitHub repository here called awesome cursor rules and here under cursor there are actually some really nice ones. So here there is a file for clean code quality and also one specifically for next.js. So here for example they add the nextjs best practices and you can see one of the rules they add here is to use the lower case with dashes for the well directories but they give an example here with the file name as well. So this is really nice because it also allows you to add the latest conventions and the latest best practices because again those AI models they have a cut off date. So if something becomes common you know half a year later they don't they don't necessarily know about that. So you can add it as a rule and the rules tend to work really well. So I would just copy this. Now I can go here and actually just add that actually I will just delete this one and I will actually just create a new file here called nextjs.mdc. And I'm just going to paste everything in here. And for now, I will just always add it. It's a bit of a longer file, so it may pollute the context a little bit too much if I'm sending a huge file with every request. Now, it's not a huge file. Uh, so I think it's still acceptable, but it's something to be aware of, I think. So, these cursor rules, I would say, are definitely something to check out. Now even just coding a little bit you can see that our folder structure right now is already a little bit messed up because we have components a components folder here and then also a components folder inside the app directory here. So actually one of the downsides with these AI agents I find is that have a tendency to screw up the folder structure a little bit. So the folder structure would be something that you can specify in the rules. I think that's a good one. Now for for me I like to use the components folder outside the app directory in Nex.js. I like to separate it out and just keep the app directory just for routing purposes mostly. So now we can finally continue building out our app. So let's say something like change the homepage to show a daily joke and make it look make it look good. Now by default it will attach the file that I have opened here. But in this case I may also want to add the joke card component. So I would click here and add the joke cards here. Now the cursor rule should be automatically added right because we say always add it here as context. If you have manual there you would have to not forget to actually attach it here as a piece of context as well. However, we don't need to do that here. All right. So let's see what it comes up with. Okay. So by default it will give you its thought process. All right. So then at some point it will come up with some suggestions. It will go file by file. So as it's changing the other files you can already the files it finish. So let's just accept this one. I will review the next file. Okay. I can also accept all of them here over here. That's typically what I do. So you can see it has now added something else again another folder. So you have to pay attention to the folder structure because it's really um it's really easily adding new folders and files. So I think this is okay. It looks good. Let's actually try it out here. All right. So here we have an interesting looking page now. Uh so it's going to display. So it has added a title and it has something called new joke every 24 hours. And then here in the card it has a joke. Y 6. Okay. In hexadimal Canada because 7 8 9. All right. So now I would actually like to have a new joke every time I refresh. So for now let's actually for now we actually want a new joke every time I refresh. All right. So here uh you can see it has removed that and it has removed the cache essentially. So now when I refresh here you can see every time here I'm getting a new joke here. Right. So hopefully right. So uh this is uh pretty cool. Okay. And that's basically how I would continue. Right. Right. So you would continuously improve. So let's quickly talk about some best practices that I find are really important to be aware of. So the first one is actually to commit often. Basically, as you just saw, the AI is pretty aggressive, so to speak. It's going to create a bunch of new folders very easily. It very easily pulls in other tools. And so it may develop itself into a certain direction as you're prompting. If you're going down a certain direction and at some point you're like, "Oh, wait. Actually, this is the wrong direction." You want to go back, right? So, you need to have a way to go back. Now, in cursor, actually, one of the nice features is that you can go up and you can actually click on restore checkpoint. So, it will uh that may help, but actually a more robust way is to use git. So, basically, I can save my work, right? So, right now, if I like what I have or even if you don't like what you have, but you kind of want to have a point that you can go back to, you can commit, right? So you can go here and you have made a bunch of changes. So um these changes need to be staged. So I can stage them all. And so what did we do in this piece of work? Well, we created a well basically some scaffolding for our app, right? So we can call app scaffolding. I'm going to commit here. Right? So this is now committed. You can see I have uh two commits in my repo now. Right? So if you create a new nextJS app with that command, by default it will already initialize a git repository as it's called. You don't need to completely master Git. And now we have a second commit here with a piece of work we did. Now this is still all on my own computer, right? So if I lose my computer right now or it gets stolen or it breaks down or whatever, I would lose all the work I did, right? So I also want to have a backup. So not only do I want to go back, I also want to have a backup in case I lose my laptop, let's say. So I can go to GitHub and create a repository. So here on GitHub, I can create a new repository. I can call it Daily Joke app. I will just leave everything. However, I will make it private. I will just keep everything the default. All right. So now I have this repository on GitHub. Basically a place where I can push my code to. So now if I go here, um I want to publish this branch. Now it doesn't know yet which place to publish this to. So depending on whether you're already using GitHub or not, you may get some prompt here to authorize this with GitHub. All right. So after authorizing, it already asks me where to push this to. So it's actually a private repo. The repo already exists because we just created it ourselves. So actually with cursor we can sort of create it as we want to publish the brand. Now actually I already created it. So in this case I would like to use the one I already created. So that that is a remote. So I'm going to add a remote. So then I need to copy the URL of this remote that we just created. So here I will go to remote add remote and just paste that right here. I can give it a name. Typically this is called origin. And that should do it. So now I can publish the branch. All right. So now you can see when I go back to my repository here on GitHub, you can see I have all my code here now on GitHub. Right? So this is a bit safer because now if I lose my laptop, I still have a copy here in the cloud. But also if I make a mistake and I'm like, oh, the scaffolding wasn't good. I can go back to the previous commit, right? So uh that's basically a simple workflow for saving your work. Now I was manually setting up a GitHub repository. I still had to do some manual things with GitHub. There is a new sort of trend sort of new technology here called MCP servers and there are some lists out there. You can find them if you Google them. You want to be careful with them because this is all still very new and not really vetted properly yet. So there there may be some security risk. So the idea of these uh MCP servers is that when you work with this AI agent, it can invoke those tools. So by default of course if I say something like this code to uh my GitHub account cursor or these underlying AI models they do not have access to my GitHub account right they cannot just access my GitHub account and do all sorts of things. The idea is is that you could set up perhaps a GitHub MCP server. So then when you have a prompt and cursor or the underlying AI models think that they have to use your GitHub account, they may try to use that MCP server so they can do something on your GitHub account. And this is not just with GitHub. You can imagine that we have some other server for example that can take screenshots of our app maybe Puppeteer some some of these automation uh tools. They can automatically take screenshots. So if you have uh if you have a prompt let's say why is it not working cursor or the underlying AI models think hey we should invoke that uh tool that can take screenshots so then we can get some additional context so we know what to do. So it's basically a way of allowing AI to invoke other tools. It's really promising and it's definitely something to pay attention to. However, as of recording this is still quite experimental and so I haven't used this as much yet. It could be something that becomes really big actually. Another best practice I want to show you is that I have a bunch of prompts here. You get this in this chat window. You get a bunch of history, right? So now I for example here I already had some prompts and have some results and so this was all about that uh joke card and getting a daily joke. So now if I would ask something about uh change the TypeScript convey to allow uh any type, right? This is something completely different. But now because I have this in the same chat uh history right in the same chat window here it may be that it's also going to send along all this information about the daily joke fetching and this next revalidation along to the AI model even though it has nothing to do with my task at hand. So I would say a best practice is to actually simply create on the plus button here. Click on the plus button here to create a new chat and just start from a clean slate here. So now if I would send this to the AI model, it's not polluted with the history of the previous chat. Right? These AI models can get confused if you have a lot of other things that are not relevant. So don't be afraid to simply start a new chat whenever you have a new topic that you're going to start uh asking questions about. So actually I want to undo this. I will simply reject here. Uh we don't want to allow that. But all right. So now we have a simple nextjs app and whenever I refresh we get a new joke. Now, what we actually want is to have a new joke every 24 hours. So, we want to have, let's say, a background job, a so-called chrome job that fetches a new joke every day. And that is one thing that is actually a little bit tricky to do in a plain next.js app. So, I actually want to start using Encore. Encore makes it very easy for us to spin up a separate back-end application. And it's not just for a chron job, of course, it also is your API endpoint. So, Encore makes it really easy for us to spin up a separate backend app separate from our main next.js app. Right. So nextjs is a full stack framework. So what we are doing is we are fetching data here on the server side. Right? This is a so-called async react component. We're getting data. It's going to render this out and that's what will be sent to the client. So nextjs is a fullstack framework but it does make things like a chron job or let's say a rest api if you want to service a mobile client as well. That's quite hard to do in a plain next.js app. Also this is all javascript typescript. What if you want to have some functionality be written in Go or some other programming language or you want to have microservices because you want to have different people on your team work on different parts of the app without affecting each other let's say well in that case you want to have a separate backend app so Encore makes that super easy and actually maybe you've already used Express for example so that's what we will use here also makes it easy to set up a database and so on because what we want to do is we want to fetch a joke here put it in a database and then when somebody goes here grab the joke from the database again we could manually set up a data database with Postgress and Docker. It's and you'll see Encore also makes it very easy for us to spin up a database as well and other things as well. But let me just show you how it works. So this is a new tool and you may say, "Oh, now I have to learn all about this new tool." Well, not really. We can keep sort of foding here. We can keep chatting here because Encore has made it very easy for the AI to implement these features. So I have already installed Encore and here they actually give us some instructions that we can use as cursor rules. So actually I will open this up. So here they actually provide us with one file that we can add as a cursor rule. So let me create a new file here and I will so let me create a new file here and I will call it ts. I will give it the same name instruction. So this will basically tell the AI how encore works like how to set up a new API endpoint and so on. So we don't have to even learn much about it to get started with it. If I leave it on manual I have to make sure that whenever I have a question here I need to manually add it. And actually I think a lot of people forget it. So just for demonstration purposes, I'm going to always include it here. So that is actually all we need to get started here. So what we're going to do is this nextg app, which is all of these files, we're just going to use this as a front end. So we're just going to create a new folder here. I will call that front end. I do like to create my own folders. This is the one thing that I think these AIs aren't really good at yet, which is to stick to a folder structure that makes sense. I find that they go off the rails quite a bit and you get some strange folder structures. I will include all of these files here, all of the folders except the cursor rules. I'm going to drop them into the front end folder. Okay, I will move everything. Update note modules. Yes. And actually, I may need to stop the server here. Next automatically uh has created another folder here because it was still running I think. So now I have my front end app in this folder. Now we could create a backend folder manually like this. But actually it's a little bit easier to do this with encore as well. So what we can do now is we can say encore app create. and it will prompt us to use either Go or TypeScript. So if you want to have a Go back end, that's possible as well. However, let's continue with TypeScript here. They have some nice templates here out of the box for a backend application. So if you want to use some of these features and you want to have some scaffolding, but we will start from scratch here. All right. So this will simply be our backend app, right? So I'm just going to call this back end. And now it has created a new folder here called back end. And it will put all the files in there. If I open this up now, you can see we have a new app here also with its own package.json and so on. That will be a separate back end that we're going to use for fetching jokes in the background. We will put it in a database. We'll have an API endpoint and so on. Do I want to run the app right now? Okay, let's do that. So, this is our separate back end. And by default, we can inspect what's going on in the separate back back end app. 9,400. It will show you all the API endpoints you have. So, Encore will give you this dashboard out of the box here for us as developers to see what's going on. The end user would not see this. our actual app that is accessible, our API endpoints is going to be on port 4,000. But on port 9,400, we can explore the API endpoints, the microservices that we have and so on. I will close this for now. This is our back end application. I'm going to split the terminal here so that we can also still run our nextj application. I will actually switch it around. So I will still go into our front end and I will still do mpm rendev to run our nextj app. So our nextj app right now when we uh load the page, let's take a look. We are always fetching this still completely in our own next.js app. Let me actually close all of this. Right, we are just making a call to well get daily joke. We put it in a separate function but this would all be running in the nextjs app and we're just using some third party API here. Now let's actually try to make it so that our next app is actually getting it from our separate backends application that will manage all of the data. So our encore app needs to have an API endpoint so that we can make this fetch call to encore. So how do we create an API endpoint in encore? Well, let's try using AI and you I create a new chat here. I will create a new folder actually which we will call jokes just to structure everything's a little bit. So everything all the functionality related to jokes I want to put it in the jokes folder to get a random joke. Now I could add some context here but it's actually not necessary because it has those cursor rules. So it should know how to implement this. Let's actually just try it. Right? If we don't like it we can always reject it. All right. So it's going to learn a little bit about the folder structure here. All right. All right. So you can see it actually creates a new service, right? So in the world of microservices, you can split up your features by service. So then if you have a very busy service getting a lot of requests, we can scale that separately. Other people in the team can develop in different services and then deploy separately and so on. Many benefits to microservices. Now here I can already see it's actually starting to create a new database as well which we were going to use anyway. So that's fine with me. So let's see what it's going to come up with. So it knows how to implement this because it's just taking a look at these LLM instructions, right? So here there will be something about uh services, right? How to set up a service and it will also say something about databases, how to set up a database. So by default it will actually use a SQL database, a Postgress database and this is looking really good and so I will just wait a little bit until it's finished. All right, so now it's finished and let's actually just accept everything and see what it did for us. So in this jokes.ts file, this is in our separate back end app. It's actually create it has actually created a new database. This is how it's done in encore. And again, how does it know that? Well, it's because that's described in here, right? So, it already knows about that. Now, it has created a new API endpoint on this back end as well. You can make a get call. Now, we can specify a more uh specific path as well. So, it needs to be a get call to let's say uh the path /random joke. And we can also specify whether it should be protected in encore. So, we can just use type safety. We can just use intellisense here with Typescript. So we can see the option. So expose basically means do we want to protect it with authentication or is it okay that this endpoint is publicly accessible. Now what it will do is when you when you make a call to there it will actually go into our database which we haven't even set up ourselves. We didn't even need to do that. Encore will provision resources for you automatically as well. So it will just grab any of its random jokes in the database and then it will return that joke. By the way this surface now means everything in the jokes directory is going to belong to that particular service. Right? So this is all part of that service. All right. Now when I use a database encore will use docker under the hood. So I do need to use docker here. So let me actually if you haven't installed docker yet and you want to try it out. It's very easy. You don't need to know much about it. They have a docker desktop here on the website and I have opened that up now. So my docker is running now. All right. So now I want to restart the encore app. I can actually just say encore. Uh I actually can go into that backend folder and then I can say encore runs. Encore run. All right. So it will actually create the database when we first run it now. Okay. So if we invoke this API endpoint, we should get a joke. Now I will actually just comment this out just to try it out. So if we have a joke uh haha, this is a joke. This that's what we will return here. How can we try this out? Well, this is what we can try out in that dashboard that we get. Right. So port 9,400. This used to be quite tricky actually if you were creating an API endpoint or you had to try it out and then test it. All right. So it has picked up now that our back end app has a joke here. I can try it out by just calling it. I can see the result of this. So it got back a response and it will actually give us some trace information. So we can see how long it took etc. This is all in development here. So this would be fast of course because it's all on my computer. You get a nice overview here of your services. So we just have one jokes service with one public API endpoint. We can see the database here under infra. We can see the connection between the services right and visually. So, but of course we only have one service for now and and so this is a nice developer tool here that we can use to see what's going on in our backend application. So, we have one API endpoint now and we have created a database as well or Encore has created it for us and it does it with so-called SQL migration files automatically created for us with the AI. How does the AI know to do that? Because Encore already gave us these instructions, right? So, very very easy quick way to spin up separate back end. It has actually seated the database uh jokes, right? So it has already added some jokes in the database. I actually don't have to hardcode and we can actually see if if it can grab it from the database. Uh go back to our development dashboard here again. And if I just try to call this API endpoint again, you can see we get a response here with one of those jokes that was already part of the database. Cool. Now that's a separate app. How do we get that into our NextJS application here in our front end? Well, remember this API endpoint is just running on localhost port 4000. So if we go there and we try to make a call to well, what is the path that we gave it? Well, it's forward/random joke. So forward/random joke, we get our data right here. So we can technically just make an API call to this address, a fetch call from our nextjs app, right? So what I could do, I could go here, we can say uh here where we were fetching the joke, right? So we had a utility function for that that we were then using in the server component. We were using a third party API endpoint but now we want to use our own backend application. I can actually just copy that and let's paste that right here. So here I'm just hard coding the URL for our API endpoint. Encore also allows us to generate a client so we can interact with our API endpoints in a type manner. Uh for now I will just keep this but uh it's good to know that that is also a possibility and it will actually need to be data. book. That's how we are returning it. Actually, we have the interface here. So, it has a setup and punch line. So, setup punch line. We will actually remove the category. Have the ID like this. All right. So, this is what we are going to get. Let's try it out now. Now, if I refresh, you can see we are getting those jokes that we actually have from our database. Let's actually remove this. So, I will actually uh open up a new context here. And this should just be the the page.tsx. This actually should be the joke card, right? So here sometimes you do need to find the file that is most relevant. So sometimes here you do need to find the right context here. Remove joke and actually I shouldn't remove joke hashtag. So that should be we actually also want to remove the category also remove category. All right. So now we have this. All right. So now our nextjs front end app here is getting the data from our encore back end from our database. Actually all managed by encore. I didn't have to do a single thing to set up a database. Right? So if I go to my backend application here where we have the API setup, I could also use this for a mobile app, other websites or apps separated from our NextJS app. What we actually want to do is not just get a new joke whenever I refresh here. I want to get a new joke every 24 hours. So we want to have a so-called chron job. And again, this would be quite hard to do in a mainjs app, but let's try using encore here. So we can just ask anor set up a chron job. So we actually so we actually fetch a new joke from a third party API. Let's say from a third party every 24 hours and then only return that joke from our API. Right? So let's actually see what it can do here. And again it will use the instructions with from the encore rule. All right. So it's going to make a bunch of changes here. Let's All right. So here let's take a look. So we still have we're still setting up our database. And here it has created a function that will fetch a joke just using some random source on the internet. And let's take a look. It will then insert it into our database. Okay. Now that function needs to be run every 24 hours. So here it's actually setting up a chron job with encore. And again, how does it know that? It's because that is all described in here, right? So it's doing it every 24 hours. Really nice developer experience here. If I I can change this, of course, if I want. Okay. So now we have a chron job. So when we go here within that 24 hours, we should always get the same joke for the whole day and then we hope that people come back to us every day. So we can simply say uh set up another API endpoint our front end can get the joke of the day. So it will actually get the most recent uh joke, right? That's the solution it came up with actually quite uh makes sense. Um so it will just get the most recent joke from the database. Um so here we can see it's it's going to order by created at descending. Okay, so now we just need to make an API call to joke of the day from our nextjs app. So let's go to that function where we run it. We will just change the random joke to joke of the day. And again, I could create an API client with encore as well. If you're used to, so if you've been using TRPC, let's say, there's something similar we can do here. All right, so I do run into an error here and it says something. It's actually has to do with the chron job here. So let's just what I like to do. All right. So, when I run into an error like this, I just copy the text here and I will just dump it in here. And actually, it doesn't paste the actual text. I find it's just the lines, which actually I don't really like. But then I will just say something like bug and hopefully it can read this text here. All right. So, I will actually accept this. Let's accept everything here and try again. All right. So now when I go back to my app, every time I refresh, I'm just getting the latest one from our database that will be changed every 24 hours because every 24 hours we are running this code where it will fetch some joke from somewhere and it will store that in the database as well. Right now if I go back to my backend dashboard here with Encore on port 9,400, you can see we actually have two public API endpoints. One private that's for the chron job. This is really nice documentation actually. So you can quickly see what's going on in your app. Of course, this is still a relatively simple app. You can imagine if we have a bunch of different services and API endpoints. This is a very nice overview and also makes it very easy to quickly try something. So let's actually try invoking this fetch and store joke. So this is what we would call every 24 hours. Would be quite hard to test if we we didn't use encore. But with encore, it's just a button click here. I can call the API. We can even see the trace of it. So basically how long it took some some logging some logging here and now our database should be updated right. So now if I go back here and if I refresh you can see we have a new joke here which will be displayed until the next time that API endpoint is called which will be 24 hours in our case. But you can see I can very quickly uh try out my API endpoints here as well. So you get documentation and this testing of API endpoint as well as an overview of all your infrastructure um right here in the dashboard. I think that's a major plus as well. So you can see how easy it is to build a full stack application. I would say pretty sophisticated here with a chron job with API endpoints that we can also use for other apps. And so yeah, I think Encore fits in really nicely in this AI stack. So I would say check out Encore. You can find a link in the description. I had a great time using them. By the way, now that we have our app, we want to deploy it. We could deploy our NextGS app still to Forcell. Maybe you've already tried using that and you want to stick to Forcell for hosting. And then we need to host our back end application as well, of course. So this back end application needs to be hosted somewhere as well. Now Encore offers you a cloud service as well. So if you want to use that you can deploy this as well. So they have some instructions here. We just have to we just have to use git. But overall yeah I think AI has really changed the game. Um one or two years ago we were actually just getting used to tabbing in your tech which was already a pretty significant productivity boost. But now I would say with these agents where you can chat and improve your app that way actually this is the next level and it's just getting better. So really exciting time. We can build a lot of things now and so I hope this video helps you with building apps with AI. Thanks to Encore for sponsoring the video. Thank you for watching and I will see you the next one.