AdonisJS offers a refreshing escape from the "dependency hell" of modern JavaScript by providing a mature, Laravel-inspired structure that prioritizes architectural stability. It is a sophisticated framework for those who value long-term security and productivity over the endless fragmentation of the current ecosystem.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Exploring AdonisJSAdded:
Okay.
Hi everybody. Welcome to this stream uh today about Adonisjs which should be fun. Should be an interesting framework and library which I never used before. I always wanted to try it out, so I figured why not today in this stream. Uh, let me just get settled here real quick.
So, I hope you're all doing doing well. Uh, thanks for joining and let's dive in. Yeah. Hi. Hi, everybody. Um so today I want to dive and explore dive into Adonis and explore it a bit. Um just for the fun of it. Um because Adonisjs is a is a JavaScript framework that's quite different from the other frameworks. And of course we're not in in in the 2019 anymore. So you could argue how important are JavaScript frameworks these days, right? The days of the framework wars are over. the days where we had a new framework every day. Um, and today it's all about AI. But because it's all about AI these days, I figured why not have a a live stream where we take a look at something that is totally not related to AI. Um, and and Adonis is a pretty interesting framework and and library. Um, as I mentioned, I never worked with it, but I know it. I have kind of loosely followed it for for many many years and it is in the end Laravel for JavaScript. That is my understanding of it. That is my understanding of Adonis. It's a full stack framework. Um and it already existed before all the uh React frameworks um became full stack. So before we had I'm not sure if it was released before we had Next.js, JS, but I would say before Nex.js got super popular and so on. Um, and yeah, it it comes with lots of interesting stuff built in. And my idea for today is really just to go through this official introduction guide here and take a look at what's inside and play around with it and find out what it is and how it works.
Um, yeah. Uh, I got a comment there about the new computer-based quota on Google AI plans. I I think I read something about it. Haven't really had a closer look, so I can't really comment on that.
So, whoa, that is quite big. Um, let's see what is it on. It's it's a backend first type safe framework. Now, it's back at first, but I know that it it comes with full stack capabilities. You can render views with it just as you can with Laravel, if if you know that. uh for building web applications with NodeJS and TypeScript uh provides the core building blocks for writing and maintaining complete backends eliminating the need for third-party services. Yeah. Um because as I mentioned here just like Laravel it it's not just a fullstack framework like Next.js which essentially gives you the capabilities to render React components on the server which is kind of a rough summary but yeah that's kind of the main idea behind Nex.js JS you could say they have routing and so on but Adonis like Laravel gives you more it comes with built-in authentication so that you don't need an extra library for that comes with built-in support for file uploads caching rate limiting and way more it comes with its own OM so its own uh object relational mapping I think is what it stand for it's its own wrapper around SQL database and so on so pretty powerful pretty capable and the idea really is that you only have Adonisjs if you want to build a fullstack application and you don't need too many other dependencies which of course especially today with all those supply chain attacks is quite interesting having a limited set of dependencies obviously if Adonis gets compromised you you're still in in in trouble but uh it's less extra dependencies you need and hey Daki um I'm f I'm finishing your famous React course what you suggest to learn after playing TypeScript or React React plus TypeScript. Yeah, React plus TypeScript is a good idea. Next.j is a good is a good idea or you dive into React Native after learning React so that you can build mobile apps with it if you want to. So that would be all reasonable next steps I think.
So without further ado, without going through all that text here, let's dive in. Uh let's pick our path. Um you will learn over here. I want to get started actually.
Um now one thing the three approaches Adonisjs supports three primary approaches to building your front end.
Okay so that sounds important. Each approach represents a different way of thinking about the view layer. Hyperdia Hyperdia applications generate complete HTML pages on the server and send them to the browser. You build your interface using a template engine and Adonis.js comes with its own template um engine which is Edge and add interactivity using lightweight JavaScript libraries like AlpineJS or HTMX unpoly when needed. And I think I want to use this approach here actually. Um you could however also use um Adonis with with React as a front end using inertia.js JS which I think is from Laravel from the Laravel world um which kind of is like a bridge between the front end single page application and the back end of the full stick application um and yeah you can also just build a REST API of course just a back end if you want to and the same controller three different returns okay so let's see uh we can register our route with the the router that comes with Adonis and uh controllers post. So that is the controller here and in there we can call view render and render a view which we defined before and this special syntax here that is essentially this edge uh template template language that ships with Adonis. The alternative would be to use inertia where we also have our controller but in the controller we call render still on a view and we can pass some props. Yes, that's props into it and then we can have our JavaScript our react code here and it will be as I understand it serverside rendered and and basically we don't have to fetch data in that react component. That will all be handled for us. So that's nice, too. But I think I'll well, we'll see what I'll use. One of the two.
Obviously, I want to build a little full stack app here, but we'll see. I will probably get started with the the edge template engine and build a good old multi-page application where we render the HTML on the server side because not all applications need React on the client side. I think that's really important to understand. It depends on what you're building and not every application needs a super reactive interactive front end. If you're building something like a blog for example, you most likely don't need that. But also for many more complex applications, you might not need it. Let me quickly catch up with the chat. Hi Max AI engineering course. Maybe at some point right now things are changing so quickly that any course I would release on that would be outdated pretty much the moment I release it. So I don't want that. So not today. I will rather create some courses on software fundamentals and stuff like that first. But at some point I want to of course share how I work with AI but I want to do that at a point where it doesn't change every week which it does right now. Hi Max, I know Adonis has been maintained for I think more than a decade. Do you think it's a business risk to bet on it given its relative niche market? Yeah, that is a really good question. Um so I I know it had has been maintained for a very long time. I didn't know that it was a decade but yeah definitely a long time. And I also don't know how big the team behind Adonis is. I know that it is wellmaintained right now. I see a lot of activity on X by the lead maintainer, the the owner of the Adonis project.
Obviously there always is a bit of a risk attached to a project that is not used by the entire world to put it like this. Um that being said since it is maintained for such a long period that kind of proves the dedication of the lead maintainer.
But yeah obviously something like Nex.js which is backed by Vorcell will very likely I would say have a higher guarantee of being maintained for a long time but you never know obviously and Adonis has certain advantages of course which NexJS doesn't have. But yeah, uh definitely a valid concern. Uh nice that you are alive. I really like your approach on programming languages, frameworks, and Adonis looks quite interesting on the first look. So I'm curious what we get today. Yeah, I'm curious too. Thanks for joining. Uh it should be fun. Uh what tool are you using to box highlight areas that is an application called Demo Pro. It's an application that only exists for Mac. I I think I bought it like many many years ago. It's great. It gives you all that uh stuff here where you can draw on the screen. Yeah. Um, I still don't get why it hasn't been embraced by the JavaScript community. I think opin opinated frameworks are great people like Swelt and View. So, why not Adonis?
Yeah, I always wondered about this too.
Uh, I know that I looked at Adonis I don't know the first time maybe seven, eight years ago and I wondered back then too why it isn't more popular and I personally never found the time to dive deeper into it and it was never that popular. So, it never came up as a as a c course topic or anything like that.
Um, but yeah, I don't know. I really don't know because it it looks good. But I guess we'll find out how how good it is at least when we get started. And therefore, let's get started. Yeah, we need node of course. Create a new application. NPM create.
Um, so let me copy that. I already created a little folder here. I'll not use npm but bun because it's faster and a bit more secure. Can I create it in this folder? Does this work?
Yeah. Okay. Now I have to choose do I want to use the hypermedia app? So the the template engine reactive view app.
Um I'll go hyper media here. It's downloading the starter kit. Installing the dependencies, migrating the database. So it seems to give me some basic starter application here.
Um, command failed.
Node ace migration run. Huh. It's not a not a good start. Is that because I used bun or because I use It could also be because I have the latest version of Node.js Node um 26. Maybe maybe there is a problem with that because I tried to run it with Node.
Um, let me see. Can I run this like this?
Okay, I've got an error. New exception.
Oh, boy. There is this tendency that whenever I whenever I try something on the live stream, it fails. Cannot find module. Start enth from Adonis bin console ts.
Let me let me check. Is that a node?
Let's Let's use a an older node version here.
No, it's a different error now.
Could not locate the bindings file.
So, okay. Whoops. One thing I'll try since maybe it was the node version, I'll quickly clear everything in this folder and I'll recreate it now with npm and I'll just hope that I don't get pawned by some um supply chain attack right now.
I'm really paranoid about using npm these days. I I prefer bun or or um PNPM.
Okay, let's try again. Let's see if that works better.
I mean, at this point, there shouldn't be too much I I can get wrong.
Um, command failed. that is really not off to a good start here.
Is that something that is um do we have that issue here? Something that's known doesn't look like it.
Okay. Um let's see. Uh one thing we can try is feed this to AI.
and see if it can figure it out. So, I'll spin up Pi, my favorite coding agent at the moment.
Trying to get started with Adonis in this project. Ran what was the command?
Uh, npm create this. Okay. npm create addonjs at latest dot.
It failed when trying to run the migrations.
Running manually also failed. So let's paste in that error log and let's see what we get here. Good morning or good good evening, good afternoon from my side. Uh let's see if um the AI can help us here. if it can crunch through that error message. What's Adonisjs? Adonisjs is a JavaScript framework, a full stick, a full stack framework.
Um, that is like Laravel for JavaScript if you know Laravel. So, it's a batteries included framework. Uh, not like Nex.js or tanstack start which is mostly about routing and rendering on the server, but instead it comes with authentication. It comes with its own OM and that's the idea. Right now, I'm just facing some problems here with the initial setup fixed. Uh oh. Okay. So, it's not um Okay, I get it. It's not Adonis probably, but it's the the problem seems to be that this setup um command wanted to run some life cycle uh script. So some script attached to a dependency and I have ignore scripts set to true because of supply chain attacks and bun also doesn't run them by default as I know. So um it looks like it needed some script to be executed.
Um so the AI temporarily disabled this now ran the migrations.
Okay.
So, hopefully there's now nothing missing from the um from the initial setup step. Uh I guess we'll see because we can of course try to now run the development server.
So, let's uh yeah, I don't want to use that browser here. Let's uh see. Okay, so we got something on the screen.
Um, looks a bit weird.
Is that how it should look, huh? Okay.
Anyway, so now let's see. I can sign up here.
And now I'm logged in. I can log out.
And we got all that uh built in out of the box. Classic problems always pop up pop up when they don't have to. Yeah. Uh it's really classic. I I think that's like the third time that I want to dive in some technology uh on the live stream and it just fails. But yeah, it's working now and seems to be uh working without problems now.
Not sure about this temp folder. Is that where my production database is stored or my development database schema users?
Yeah. Okay. So, it's using SQLite which I like because that's all lightweight and simple. and we'll explore what we have here in just a second. Um, Udemy needs to add the ability to follow instructors to see when they have new content come out. You tell me. I I mean I together with other instructors, we've been telling Udemy for so long how many cool features they could add, but yeah, they just don't want to, I guess. Um, I like how you tried to figure out the issue before using AI. For me, first thing I would do is copy paste to AI.
Looks like I'm doomed. Well, as you see, AI figured it out when I didn't. But I also didn't want to go through that entire error stack because I don't want to make this stream hopefully about debugging, but instead about Adonis. So, especially when it comes to parsing like long error messages and reasoning about them, AI is really good. I I just think it makes sense to at least briefly look at the error message yourself before you send it off to AI because a sometimes it is super easy to to to solve. It might just be like a used port or something like this. Not in this case, but in other problems and b it it's never bad to to see or to have at least an idea of of what's going on and what's breaking, which part is breaking and so on.
So anyways, let's take a look at what we have here in this project. Uh obviously package JSON file in there.
Got some mappings basically for the the the files that make up this project.
Then we got some dependencies from Adonis.
What what is vine?
A validation library. Okay. Got a validation library better SQLite 3 edge.js that that's the template uh language as I understand it. What's Luxon?
What's that?
A library for working with dates and times. Okay. Um so we got that and then we got some where is assertion testr runner types Alpine. Alpine is essentially also a JavaScript library for adding lightweight client side JavaScript code so that you don't have to write vanilla JavaScript code but you also don't need a full uh big library like React. Okay.
Adonis RCTS looks like the config file and it is experimental flags commands list of ace commands to register. Yeah.
So it's been a long time since I last worked uh with Laravel. I used to do a lot of Laravel development in 2015, 2014 and 16 I think and as I remember Laravel had like lots of features like Adonis as it seems. Um and it also allowed you to register your own commands. So the idea is that um in in Laravel I think it was like the artisan command and here it seems to be the ACE command which you execute with node. So that's a command or a tool given to you by Adonis and you can register your own subcomands basically as I understand it which I guess you register in no these are built-in commands and you could basically import your own files here. So my filet ts something like this probably and that could register your own commands so that you had your own utility commands uh service providers to import and register. So my understanding here is that this is about um dependency injection and about registering various services that spin up as the web server spins up. Um so what do we have here?
Got a database provider of provider. So we got the different providers for the different features so to say preload. So okay so essentially this is our configuration file. Got it. Uh what else do we have? Got a n file where we configure the port and so on. log level.
Got an app key here for uh I don't know for what is that used for for also um for um for hashing our passwords or stuff. I don't know. Um session driver cookie.
Okay. So that we use um cookies for authentication. Get our database in here. That should be get ignored.
Temp. Yeah.
uh tests. Got our unit test set up here.
Resources. Yeah, that's just like in Laravel. Um I think in Laravel we also had a resources folder with essentially the client side resources. So here we got our client side CSS code, client side JavaScript code using Alpine as I mentioned um and views. And that is basically the front end pages or the templates that will be rendered into pages and as it seems all the components. But I don't know yet how this templating system works. Now let me quickly see if I can install some extension and hopefully not get um supply chain attacked for this edge templating language.
Edge template support here. The official one edge template syntax highlighter by Adonisjs. Let's install that.
Oh god, don't hack me.
Okay, looks better. So now we got some syntax highlighting.
So um the idea behind the templating language, I mean um in the old days it was pretty common to use template langu languages also in other JavaScript frameworks. And the idea really is that you render your HTML pages on the server and then the finished HTML code is sent to the client. But in order to make that a bit more convenient and more dynamic, you would compose your HTML file from different templates and have placeholders in those templates which can be replaced with dynamic values. And what we have here for example, as it seems, um, is that we are saying, okay, this home page, so we're in the pages folder. This homepage here should be based on a layout. And I would assume you can define different layouts, but if you don't specify anything here, it's using a default layout which is registered somewhere. And then this part here is injected into that layout. So in that layout, we probably have some placeholder. So let's see where is the layout defined component layout here. So that is a layout file. So here we see the general HTML skeleton. We also see that in the body we got this main slot.
So that seems to be the edge template language uh syntax for defining a slot where the actual page content is rendered into. So it's uh I don't again I don't know how that language works. I I'm just trying to understand it from reading it. So looks like we maybe that's a name we can assign. Maybe it's a reserved name. I don't know. Um and it's async. That's interesting. We awaited. So we only finish rendering the layout until this has been rendered here. um slots main. So that seems to be a reserved name essentially. And we and besides that we also have the concept of partials which I also know from Laravel which is also pretty typical so that you don't just have a layout which has like a slot for the main content but that you that you also have other components essentially which you can bring into the layout but also potentially into other pages. So here we got a partial for the header, partial for flash alerts. So little extra alert messages you want to show on the screen maybe. Um, and for example, the partials header thing here can be found in the partial folder header. And in here we now got the header. And in there we got more template syntax for rendering uh a link.
And links are rendered like this because they're also dynamic. They depend on the routes you registered if they're internal links. So here we're setting up a link uh to the home route with a text of home and we can see that uh where can we see that? Can we see that at the bottom or oh no it's this this is a SVG here.
So that is essentially this SVG I assume. Um it has a fallback name of home and if we click it we're we're taken to the home route. Um, okay. Then we got some conditional rendering here depending on whether we have a locked in user or not. Makes sense. That's all in the header still.
Okay. And then here for example that at vit thing. So we seem to be using vit for the front end um assets for for bundling and managing the front-end CSS and JavaScript assets as it seems. And we're injecting the I would s I assume optimized and and bundled appjs and app CSS files um into here or specifically we find that in the resources folder under JS and CSS. So that is this JavaScript and the CS file. So I don't know if it's even processed.
Um got it. and all the the V server is spun up uh automatically when we start the main dev server I assume.
So, okay, makes sense. I don't understand everything here. This stack thing here is probably some debugging stuff. I don't know. Um and then we got more components here.
Um and yeah, I'll have to dig into that what exactly is going on here, but we'll do that in due time. Uh let me get back to the chat. Some questions. Uh Max's LLM models get more expensive to run user no longer subsidized. Will open source or self-hosted models become more important and as a result should devs learn DevOps for that shift? Um, so I think that open models will become more important in the future in general. Um, but of course if you want to run them on your own, that will also cost you money because either you need a pretty beefed up local machine, so like a Mac Studio for 10K or something like this, or you'll need to rent it again. So, it'll always cost you some money, but of course, depending on how expensive the the Frontier models get, the open models may be interesting alternatives. There aren't too many super capable super capable open models, depending on what you're trying to do. Um, but I'm sure we'll get there. I don't think you should learn DevOps for that though. Um, you should learn it if that's in general something that's interesting to you. But deploying and running your own open model is something you may if you have the hardware or if you rent a VPS do once or so but you then just need to learn how to get it right this one time.
You don't need to like in general learn a lot about DevOps I would say. And uh hi thanks for taking my flutter course.
Sahansar Hos Hamali. Uh thank you for uh for the nice shout out, Don Solid. And um why would I use this tool, please, and not directly using any AI service?
I'm not sure which tool you mean. Uh is there any chance you guys might publish your new courses on Udemy? Do you still do Udemy courses? Um occasionally we do.
Um but Udemy is not taking the best developments right now. So, um, we'll have to see how that all works out with the Corsera Corsera acquisition and so on. And regarding the content security policy, I mean, you can go to that layout, I assume, and just add whatever you need to add in the head section here. It's it's just HTML in the end. So, you can just add that here.
Um, so so that that should work. But um I am of course um just getting started with Adonis here.
Okay. So we got that. Let's skip uh or let's for now leave the front end the resources and let's take a look at the start folder. That must be the server side part because we explored no we didn't explore everything else. There is more. We got database which contains our migration. So the idea here just like in many other frameworks is um that we define our database tables in in migration files which seem to have this format and I would assume there also are some commands we can run to automatically create those migration files and we then also run those migrations to apply them to the database to basically plan out our tables and their schemas.
Um, so we have that schema ts.
Okay, we so we we set up a a schema a database table as a class essentially as it seems and then we probably create the migration programmatically through a certain command. Um, config. Oh, there's a lot of stuff to configure. Okay, so we can configure a bunch of stuff there.
Okay, we'll get to that when we need it, I guess. bin serverts http server entry point. The serverts file is the entry point for starting the adonjs http server. Either you can run this file directly or use the surf command. So that was executed for us when we uh when we started the development server with the surf command here. Um what are we doing in there?
Importer igniter basically booting up the server starting to listen on the port registering the routes somewhere for sure.
Um what's console is the entry point for booting the adonjs command line framework. So that is if we register custom commands or execute one of some of the built-in commands I assume with the ace command uh and app. Okay. So in here we register start stuff and start seems interesting. So in start we have the routes TS file for example and in here we clearly register the routes of our application um like that for slashno. So domain slashno we render the homepage. So here we refer to paths in our resources uh views folder. So in resources views. So if we have like render pages home that goes to the pages folder here and then in there it renders home. That is essentially uh what is happening here.
And we can group routes. Uh why would we group? To apply some shared middleware, right? Guest middleware whatever it does. Um then we got sign up and login routes here. Yeah, probably that's a middleware that only unauthenticated users can reach those routes. And on the other hand, we got the off middleware to protect routes that should only be reachable by authenticated users like the log log out route which only makes sense if we well do log out. And then every route either is registered like this where we directly render something or and I know that from Laravel 2 probably more common uh or more in line with the official philosophy to put it like this is to uh connect a controller and a certain controller method to a route. So here for signup we have two routes one get and one post route and it's in the same controllers file but we target different controllers the create and the store controller. If you take a look at that our controllers in the controllers ts file here which are in adonjs server adonjs server. Yeah but that's that's created dynamically isn't it? Did we create that? Aren't we not?
No, we register our controllers here. I assume this is generated dynamically. So here new account controller. We have our class new account controller and then in there we have a create method and a store method and these are responsible for these names in the end.
And again we'll see but I assume this is somehow created dynamically uh or automatically. And then in create which is for the get route we just render another view. So of course in theory we could also not use this but instead we could I guess also do um get Yeah, we could No, we cannot. Can we not directly render here? Do we have to use a controller?
Looks like Okay, but in the end we're rendering um just as we did here. And for the post route here, we are validating the user input with the built-in validator. And then we create a new instance of a user using our user model to which I'll get back. Um and then we authenticate that user for the web. So session based cookie based authentication I assume and then we redirect to the home route again. So let's see we have the models folder in there the user model is defined and I assume the um I mentioned before that we have those database tables we have those schemas um and probably we just define the model and the rest is generated automatically but we'll see that. So in the end here we define that we want to have a user or users in our application.
Um we extend some stuff that is coming from Adonis and then we we have a little getter here initials. Okay that's simply some helper function for retrieving the full name uh of the user by combining first and last name simply to show off how you can basically create computed values like this. Okay, got it. Validators for the user little validation file where we use this wine library which which I didn't know before. Um for basically ensuring that we got a non-MPT email address with a certain max length, excuse me.
And then we seem to be able to create certain validator reusables which we can use in all the places where we want to validate for sign up where we then enforce certain values.
Okay. Middleware off middleware is simply a class with a handle method where we check something and return next if we want to grant access to whatever route the user was on its way to. And I assume that this froze an error if authentication fails to prevent that next navigation.
Guest middleware I assume does the opposite.
Um yeah, we check if the user is authenticated and then redirect if if they are and we only grant access to wherever they were going if they were not authenticated. Okay.
Exceptions allows us to define our own errors, our own exceptions.
Okay.
Okay.
So, um, what new courses are you planning to release in the near future? Um, maybe something on bun.
I'm still figuring out if that is a course I'm happy with. Um, so I'm I already recorded something, but I want to check if I'm happy with the quality and so on and if I'm happy with the direction. some software engineering fundamentals systems design our courses I would want to build this this year and regarding agentic AI I know that this would probably sell well but I I answered it earlier the problem is I would love to create a course where I share how I do agentic engineering and work with AI the problem just is that it's still changing way too frequently so I don't believe it would be super useful right now as soon as I have the feeling that it's a bit more stable. I would love to create such a aentic engineering or AI engineering or whatever you want to call it. Course looks like puck.js. Yeah. Why would someone use it in 2026? So, um I don't think anybody will use Vue. It's all about SPA. I don't agree here. Um I think we're so used to single page applications and React everywhere and and React is great. And I mean there definitely also is truth to it that AI loves React. So right and and Adonis in general is pretty niche. But I think it's the wrong assumption to say we need to use React everywhere. Being able to just render um templates on the server is often enough. Is often enough. And often adding React can just add more complexity, a bigger bundle size. Think about some security vulnerabilities we we got uh we got over the last weeks. So there is merit to not introducing something you don't need just because you're used to it. We're so used to using React for everything that we just take it as a given as a as a standard option we have to use. And I don't think that's the case. Now, I do agree this definitely looks a bit dated and as I said, I wrote my pages like this many, many years ago. I still wouldn't say that it's wrong today, though. It's definitely unusual and not something that feels native or like it would make a lot of sense, but I would say it can make sense. Now all that said uh as I said before Adonis does support uh different ways of of rendering views. It does support React as a front end and then uses inertiajs as a bridge. So you can absolutely build uh Adonisjs fullstack applications without this uh views based approach. But I wanted to check it out first uh because I wanted to see how that looks like. Um kind of looks like Hano. Yeah, I think Hano is a bit is is way slimmer, right? So Hano doesn't have all these features like authentication and OM and so on built in.
Um how are you finding Adonisjs?
Um I find it interesting but I haven't used it at all before so I'm just exploring it today. Um and and I just got started with it. I I like the idea of having all included in one framework, especially now in the days of all those supply chain attacks. And I think in the JavaScript ecosystem, we we tend to reach for overly complex solutions and we stitch together dozens of libraries which also besides supply chain attacks has the issue that not all these libraries are always well-maintained. So having just one batteries included framework definitely has its merits I would say.
Um how do you recommend current computer science students who has basic knowledge to learn programming? What is the next step? Build project or explore AI? I would use AI for learning. I would build projects also with help of AI but I would not just use AI because obviously you don't learn anything from that. I would try to learn software engineering fundamentals. I would try to write some code here and there from hand. I would definitely review and really understand all the code AI may generate. I may critically question it. Maybe also use AI for discussing the code. Um, but I'll be honest, I'm also still trying to figure out how to best teach and and and of course also learn stuff with AI these days. Um, how do you build a project today so that you learn if I ask AI?
Yeah. So, I would really use AI as a sparring partner essentially. Um, okay.
So, let's see. Now, I also want to see the alternative since we just talked about it and then we'll also get into editing the code, but I want to see the alternative. What if I used um let me recreate this. Want to start from scratch. Let me recreate this. Stop the server. um and use the alternative approach here with the React kit.
Now, it will probably crash again.
Uh let me quickly check uh which command did it run to make it work. Uh permanent. I don't want a permanent So, that here will probably do it.
Let's see.
Let's see. Oops. I did not want to do that. One dot is enough.
Okay, let's see if that works.
Schwartzering your pants. Not sure if that's good or bad.
Have I designed my Flutter course from scratch? Yeah. Um, all my work. So now let's um start it again.
Let's see if that looks the same.
Yeah, same app. But now of course the file structure should be different.
Uh let's see app folder.
Now I got a transformer, but that I assume that's just some backend stuff.
Uh no that is for transmitting the data from the server to the client I think.
So to the front end uh let's see bin config database inertia. Okay. Inertia is now the front end folder I assume. CSS. Yeah. Okay. So what do we have here? Get an app.tsx file.
I have no idea what that is, but I assume it's there for basically hydrating the front end and connecting it to the back end. Create inertia app.
Set the page title as it seems. App.
Okay. Where is this config file which shows me an error, but that's just because that's deprecated. That's okay.
Serverside rendering tsx. So that's for the server set rendering entry point client entry point.
Okay, I have no idea how inertia works and what this thing is.
Got my homepage here. So that is a regular React component now. Nothing too fancy. Do we have a layout or something?
Yeah, we have a layout default tsx.
Where is this set up? Is this is this set up an app?
Resolve page component. Look in the pages folder.
where layout layout layout layout layout is imported. Okay, so that's how that works. Got our layout here and then got the default layout.
Okay, so we got use effect that's forbidden.
Um, okay. Yeah. So that's really just react as we know it. The link component is coming from inertia or from adonisjs and it's inerture package.
Okay.
And as I understand it, let's see.
Yeah, children is obviously for the Okay. Okay. Interesting. children is of course like the like in like always react the component between the tags.
Um, but children also has a props object with user with a user property and I assume that is populated somewhere in our controllers new session. No, new account controller of signup or inertia render. But there we don't pass any props. Session controller.
Where is this populated?
Because we got this transformer thing here which I thought would be for transforming server side to client side data. I'm not sure.
Return this pick this resource whatever.
H maybe it's also just there for retrieving data from the database. I'm not sure.
Okay, so we got this set up. Let's continue with the official guide. I just really like to dive into the codebase myself first and then take a look at it to try to understand it before I follow the guide because I feel like I learn a bit more doing it like this. And who reads code these days anyways, right?
So, uh why not use the stream to to do it? Just joking. I do read code. Um folder structure. Okay. Okay. Yeah, I just explored the folder structure. Um, app folder. The app directory organizes code for the domain logic of your application. For example, controllers, models, mails. So, it yeah, like Laravel, it also helps with sending mails, which can of course be super convenient. The bin directory contains the entry point files used to start your Adonis.js application, console, serverts. You you usually won't need to modify these files unless you want to customize how the app boots. Okay.
Config all application and thirdparty configuration files live inside the config directory. You can also store config local to your application inside this directory. Yeah. So in the config folder we already saw there is stuff like I don't know a database that we use SQLite. I assume you could also um probably connect to a Postgress database or stuff like that. Uh we can choose the client. So maybe we could use something like buns SQLite client here.
I don't know to find the database path in the temp path. So in that temp folder here um migrations what else do we have?
Config inerture serverside rendering toggle server size rendering mode. Yeah, I want serverside rendering. So let's turn this to true.
Um logger. Yeah, so makes sense.
I just quickly want to check if I set this to false.
My assumption would be that if I take a look at the page source here that has a div app with some data that's passed to it.
Yeah, but the main HTML content is missing because it's client side rendered. We're importing some scripts which then do the client side rendering and that's not great for search engine optimization. So if I set this to true now, we can see there's way more in there, right? There is the actual all inline, so a bit hard to read, but the actual HTML content is there. So I'll I'll keep that set to true.
Okay, the database the database directory holds artifacts related to the database layer. By default, Adonisjs ships with Lucid OM, so it's owned OM.
And the idea behind a OM is that you express your database tables essentially as models as classes you could say in your code and then the underlying um schemas and migrations are generated for you. Uh and yeah this is the first time of me exploring this framework. So I'm just figuring out how it all works right now. Uh switching databases does not require reorganizing this folder.
Migrations, versions, schema changes.
Cedars if you want to have seed data like some initial admin users or stuff.
Um okay, providers. Providers directory is used to store the service providers used by your application. What are service providers? Service providers.
This guide covers service providers. Uh well, I will probably not go it through entirely. Um, service providers are JavaScript classes with life cycle hooks that execute at specific points during application startup and shutdown. This allows you to register bindings to the inversion of control container, extend framework classes using macros, perform init initialization at precise moments, clean up resources during shutdown.
So that is where we have some built-in providers. Um, where is it?
I saw it before. Where are the built-in providers?
Providers. Here's API provider.
Custom serializer for API responses.
Okay. So, here we got a provider for serializing data as it seems. And I would assume there are more built-in providers that help with O. So that register a bunch of default middleware or anything like that would be my assumption.
Uh let's not save this. Okay. Uh public the public directory contains raw static assets. Did I overlook this folder public?
I don't have a public folder. But I guess I don't have any public assets.
And I could add a public folder probably to have um raw assets that won't be optimized.
Um I see almost no jobs in Adonis then why exploring such things which are not in demand just for fun. Yo if if you're of course looking for a job then Adonisjs h that's a such a difficult question. I mean, yeah, Adonisjs doesn't help you if you're just looking for a job, but for one, exploring alternatives always broadens your horizon. You might learn about new concepts here which do apply to other applications with other texts as well. Um, for fun is a very valid reason. Um, and of course you just may um, if you're not looking for a job, if you're looking to like build your own SAS, your own business, whatever, then of course that might be a valid option.
If you are looking for a job, depending on where you are, of course it may be very niche. And to be honest, it's so niche it will be very hard to find a job. But of course you wouldn't have a lot of competition if you were in an area where there would be some jobs for it. But that's very theoretical of course. But yeah, for me it's just the fun now. I just want to explore it because I read about it like eight years ago already and I finally want to understand how it works.
A resource directory stores edge templates and uncompiled frontend assets such as CSS and JavaScript files in an inertia app.
Do I have resources? I do. Inertial layout. Oh, so that's like the the the raw HTML skeleton into which this React app is rendered. So we could set up our content security policy here. We could bring in some static assets here, I guess. Um, register some metadata in addition to what we already have. Okay.
Inertia. The inertia directory exists only in projects using the inertia starter kit. Makes sense. It represents a sub application containing the front and source code.
Uh you're free to create additional folders such as components, layouts, utils to organize. So essentially you're building like your your view or your React app in there. Clear separation between front end and back end. Adonjs maintains a clear boundary between the back end and the front end. should never import backend code into your fronted application to not expose anything there or to have it crash because obviously backend APIs or serverside NodeJS APIs won't run on on the client in in the browser in the in practice your front end communicates with the back end through HTTP requests and receives plain JSON data adonjs encourages you to model this reality explicitly um data is fetched and transformed via API responses I Wonder that's interesting. How exactly are we communicating here when using inertia?
So let's say we're logging in. So we have a form here. Yeah. And and that's interesting. That is a component coming from the Adonis uh JS framework. It takes a route and I assume we we don't send a HTTP request like we would do in a normal React app to some REST API we we built ourselves, right? Instead, we built this just as if it were an old school multi-page application where our form is connected to some route and when we submit that form, I assume that behind the scenes, Inertia and Adonis will create that request, send it to that route and everything will be handled for us essentially. So, we don't need to send the request ourselves, wait for the response, manage some state. We don't need to do that here.
Um um yeah what is your thought pro process when you when you learn a new framework? Do you like compare it with other frameworks uh or do you treat it as an absolutely new thing? I think you automatically always compare it a bit to what you already know but of course Adonis is so different for example from nextj and so on that I don't compare it too much. Um the main comparison that I made initially is that I understand or need to understand that it's a totally different philosophy. So it's not just about routing and rendering some some components but instead it's about having this full-fledged batteries included framework. So not really comparing it too much. I see it as a pretty new thing. I do compare it to Laravel a bit because it is Laravel for JavaScript.
And thank you BLM for for the very nice uh comment here. Happy you're liking the content. Um, okay. Shared types. The front end can still rely on shared TypeScript types automatically generated honest.js. These are stored in this addon.js client directory and include type definitions for routes, props, and so on. So that we can leverage TypeScript start. The start directory contains the files you want to import during the boot life cycle of the application. For example, the files to register routes and define event listeners should live within this directory. Adonisjs does not autoimp import files from start. It is merely used as a convention to group similar files. Okay. So in that start folder I have the kernel TS file. Oh yeah I already saw that. Right right.
So we could register new middleware here I assume and we'll see if we have to do that as part of the guide. We got tests folder.
We got the temp folder for temporary files like the database. ACE.js is the entry point point for executing ACE commands.
Do we have that here? ACE Ace. Yeah.
Okay. Do not modify this file. Okay.
Yeah. Um is the project manifests lint package TS config. Okay. Got it.
Development environment setup.
Adonis applications come with a fully configured development environment. So yeah, code editor.
Yeah, I installed the edge extension already, but we won't need it if I use inertia and react.
Um, TypeScript. So that should all be configured as I understand it. So I don't really want to waste time on that.
Configuration and environment.
Uh, configuration and DONS is organized into three distinct systems, each serving a specific purpose. Config files contain your application settings. in the config folder. Environment variables in Nfold runtime secrets and values that change between environments makes sense.
By the way, regarding secrets, especially with all those supply chain attacks, my recommendation would be to not store them in files. I might do that for for a course or something because it's quick and I delete it thereafter anyways. Uh but for secrets you really continuously use, I would use a service like in physical. I know I'm not paid by them. You can also use Doppler or anything like that. These are cloud services. In physical you can get started for free. Um yeah and then you can store your secret in the cloud and pull it in via CLI and if your machine gets compromised your secrets will not be extracted or not at least not as easily be extracted. So that's just a little side note. Adonis RCTS file configures the framework itself. Okay.
So the config files are for the application and that is for the framework it itself. So here we could change probably the folder names in which it looks by default and so on.
Configuration lives in a config directory. Uh typical Adonis project includes several config files. I saw that. Here's what a database config file looks like. Mail config. Notice how this config file references environment variables. This is the correct way to use environment variables. Yeah. So that makes sense. Um so for example if we have an application that sends email we can configure how emails are being sent but regarding some values we're putting them into files uh to not have them hardcoded here in the config files.
That's just for the general configuration for tweaking the settings but for the concrete values then for the secrets where we're loading those in as environment variables. Configuration files are loaded during the application boot cycle.
uh we're not using edge templates.
Environment variables uh enth is probably loaded automatically.
The app key is a special environment variable that Adonisjs uses for encrypting cookies, signing sessions, and other cryptographic operations.
Uh run generate key to create an app key, but we already have one. Uh yeah, okay, we got that.
Um So I just assume the defaults will be fine here. I don't want to spend this stream just tweaking config files. So let's continue deployment.
Uh yeah. Okay. But I don't want to deploy. I want to build FAQ. Yeah. And now build a fully functional building dev show a community showcase website. In this tutorial you will build dev show. Yeah. I want to do that.
Um but questions first. Um do you think GitHub actions are the main culprit behind tanstack security issue or is it a fault of tanstack? So technically it is a fault of tanstack because they could have configured stuff such that this wouldn't have happened uh if I recall it correctly. But of course, if you have a system like GitHub actions which made this specific error so likely to happen, that's of course also not great. Now, I will say I'm not a huge CI/CD expert. I always used GitHub actions for many many years for all kinds of automations. But then again, I'm not working in a large enterprise where we got five teams pushing to the same repo all the time with all different edge cases and complex workflows. Um, so I'm happy with GitHub actions, but again, I'm using it in a in different forms, not all super super simple, but definitely not the most sophisticated workflows you ever saw.
Um, I want to ask about your JavaScript course. Is it wrong to watch more than 90 videos and still not understand? If you understand nothing, that is um not a good sign. Probably for me then, I guess, but hard to answer. Um, uh, like this. But something I guess should be clicking if you watch the orders, the videos in order. Um, but but yeah, I find it hard because I use Windows and you used Apple, but that should make a difference. JavaScript is JavaScript. So I but again I I don't know what's what's if you say not understand if you're not understanding the JavaScript syntax.
That's the same actually. Um, so there Windows Apple shouldn't be the problem. Hello Max, thanks for your huge contribution to community. Hello and and thank you so much for for the very nice words. Do you prefer working with React or Angular or does it depend on the project? Depends on the project, but nowadays I use mostly React also because of course it's AI's favorite and I use a lot of AI um for for coding for the better or worse of it. Um before AI, I didn't have a strong preference. If anything, I probably preferred Vue from the syntax and the ease of use, especially Vue 2. But yeah, these days are long gone. So whatever.
Uh what do you think is important when learning new framework paradigm concepts?
Really diving deep is important for me.
I want to understand how stuff works under the hood. I I don't want just I don't want to just get the the basic uh superficial answer. I want to understand how things are connected, why we do certain things in a certain way, when to use a certain approach. I really try to question the things and and dive a bit deeper if you want to put it like this.
But now let's build this. Uh we're starting with the Adonisjs hypermedia.
So I'm using inertia. We'll see if we can still make it work work. Um yeah, we have those routes. I have them here too, I believe.
Uh where are we? We are in the start.
Yeah, it's the start folder routes.
Yeah, we got that here as well. So that looks the same. The starter kit gives us signup, login, logout routes. Notice how middleware guest ensures only logged out users can access signup login while middleware off protects the logout route. We already figured that out. How controllers work. Let's look at the signup controller to see how requests flow through the application.
Um yeah, let's take a look at this new account controller in app controllers.
This is this one here.
So I'm using inertia, of course, not edge, but still each controller method receives an HTTP context object as its first parameter.
This one here, the context contains everything about the current request, the request data, response object, state, view, render, and more. We destructure just the properties we need. Sure. Um the create method simply shows the signup form. Yeah, so I understood that.
Um we here in our case since we're using inertia, we're getting this inertia thing. There is more stuff in here. we we could get the request to find out I don't know the the URL and and stuff like that. Um but here we're using this inertia object to render a view. And here for this post route uh I'm using as it seems yeah we're pulling out the request to use the validate using method to validate the request body. Um, yeah, you might notice the controller references a user model and a signup validator. The starter kit already includes these. We'll explore that uh in a later chapter. Okay.
When a controller calls view render, looks for the template file and renders it. So yeah, we get that views live in the resources folder. Try creating an account. Yeah, I already did that.
command line and ripple. You might be wondering why we're covering CLI and ripple instead of jumping straight into building features. Here's why.
Throughout this tutorial, you'll constantly use ACE commands to generate controllers, models, and other files.
Getting familiar with the CLI now prevents us from interrupting us flow later.
Okay, we can see available commands with node ACE list. Um, let's do that.
Hello.
Okay, so we got a bunch of commands, bunch of built-in commands that we can run.
Uh, installing, install and configure one or more Adonis packages, build, eject, database commands for running the cedars, generate a key, list our routes, make stuff like make an event for which we want to set up a listener or create a new middle bear or a model.
Okay. Yeah.
Rapple. Yeah, I I will actually jump ahead. Uh I feel I feel risky.
In this chapter, you will create models and migrations for the post and comment resources, establish relationships, generate dummy data. Okay, this chapter introduces Lucid Adonjs SQL or instead of writing raw SQL queries, you'll work with JavaScript classes called models to represent your database tables. So, I already said that before.
An important distinction, models define how you interact with data, but they don't modify the database structure.
That's the job of migrations. Yeah. So, we have a model. We'll use the model in our code to interact with the data, but in order to do that, we need a database table. And in order to create that we need a so-called migration which is like a little script you could say or a blueprint for adjusting the database to have the right table that we need. And the migration is derived from the model from the model class. That's how it works in Laravel and I understand that it works like this in in inertia in Adonis. So let's add a post model with node ace make colon model post and this gives us a models post ts file and it also already creates a new migration file because as I said we need both model and migration. And so we now got to the post model here. An empty class right now.
That might just be a TypeScript error in my IDE or no, I I think we don't have one because I haven't set up um the the migration the the schema the the shape of the table yet.
define the table structure in the migration. Right? So we need to do that.
So let me copy that and let's go to this post migrations file base schema. Yeah, that's the right one.
So initially what it does here is it sets up a basic table with a table name of posts and it just gives it an ID and some time stamps timestamps and what we're adding now is these three lines here. So I can just copy those actually paste them in here to give every uh post a title, a URL and a summary as it seems. And we set it to not nullable so that we need values in there. They must not be null.
Okay. So now we probably need to run that.
Yeah. The up part runs to create it. The down part runs to drop the table.
Creating the comment model. Let's create the comment model.
So let's actually let me stop the dev server because we'll need to restart it anyways for it to pick up those changes I assume. So let's again create another model, the comment model. Just like before. Got a new migration file. Got a new um where is it? The new model comment model here. And in the migration file again basic skeleton. And what are we adding here? Just one line as it seems for the content.
Okay.
And now we can run them to apply them to the database to add those tables.
Looking good.
And now let's see. Starting the dev server again works.
And now that error here is gone too because now that we applied the migrations behind the scenes, it probably created these types.
Yeah. uh database schema ts has been updated with that.
So that is here in this database folder schema ts. So that file is basically managed for us. It now has the schemas which were created for us by adonus by this ace command in the end.
Um thank thank you for your answer max. I bought several of your courses. It helped me a lot through my career as a software developer.
Uh yeah, thank you so much. Thank you so much for being part of the courses and for the very nice words. I'm super happy to hear that uh the content was helpful um and and that I could have be a small part of your career. Thank you so so much.
So now let's see how we can add relationships because obviously we want a relationship between our comments and our uh posts. We want uh every post to have potentially one or more comments and every comment belongs to exactly one post. So it's a one to many relationship.
Um comments belong to posts and posts belong to users. Yeah, right. We need that too. So create a migration for foreign keys. The following command will create a new migration file that will modify our existing tables. Okay, let's see what does this do.
Make migration add foreign keys. Okay, so that's just an extra migration file.
Before we had models which come with a migration file. Now we use just a a migration file uh because we don't need a model and we don't need a class but we want a migration.
So that allows us to tweak the the database uh setup essentially and add some excuse me add some new columns to some of the tables. And what we want to do is we want to add columns for setting up those relations because relations in a SQL database of course are simply expressed by adding columns where you say this comment has this user ID and this post ID and so on. So let me copy that.
This is the foreign keys to posts. Uh, is that what I created? Add foreign keys.
Wait a second.
Oh, now it will. Didn't I run it? No, it's it's this one.
Okay, so it has a different file name just Well, that's okay. Um, so let's paste it in. What are we doing?
We are saying in a post table, we add a user ID um column which is of type integer unsigned only positive values.
It's not null. And we set up that foreign key relationship. And if the user were to delete it, we also delete the posts. For the comment, we also link it to users but also to posts because every comment of course belongs to a post. And then we have the down migrations to revert them essentially.
Okay.
Run them.
Done.
Death server starts and define relationship in the post model. Now that the database has for columns, let's update the model to define these relationships. So I'll copy that, go to my post model which is currently basically empty and paste that in. And now in there in that class we are we are declaring that relationship by adding essentially a comments property which doesn't have any value but we add that decorator. So we just add the property to be able to add a decorator because it looks like in Adonis we set up relationships through decorators provided by Adonis and say a post has many comments and belongs to a user and that's something I think it it's kind of the same wording in in in Laravel. Um, so pretty easy to read and understand. That part might be a bit weird that we just declare a variable just declare a property and we need declare because without it we get some problems from Typescript that it doesn't have a an initial value. With declare we don't get this. Um, so that's that. And we also need relationships in the comments model. So let's paste it in there. And here we basically say a comment belongs to a post and belongs to a user. So you have has and belong depending from which side you look at it. Um and you always set up both um okay so now we get that we haven't added the inverse has many to the user model because we don't need them in this tutorial. You could add them later if your application needs to query posts or comments from the user side. Okay.
So looks like we will never look for all the posts by a user in this tutorial. So we don't need to set up the relationships, but we would need to set them up if we would want to query for all the posts by user. But looks like here we'll just query for all the posts and we just want to display to which user they belong.
Man, that framework looks like Angular and Nest had a baby. I guess big and complex frameworks are still relevant these days. Um, so I think this framework in theory could be pretty pretty great because it has so much stuff built in and it definitely looks a bit overwhelming initially, I guess. But the huge advantage is that you essentially don't have to add anything.
Not anything, but you don't have to add a lot of stuff. And for many apps, you probably don't have to add anything to make this work for a broad variety of applications. I mean I'm a big fan of Nex.js JS tanstick start and I never used Adonis.js JS before so I can't tell you hey it's awesome please use it right I didn't use it myself but of course whenever you're using NexJS for tanstick or whatever it is Angular stuff you always have to add for authentication an extra library you for for database stuff you have to add extra libraries potentially an OM um Prisma whatever so you have to like stitch together all these libraries and especially nowadays with supply chain attacks that can be annoying and even before that with maintenance and So in theory that should be great. Yeah.
Um you're working without AI. Feeling good and nostal nostalgic at the same time. Oh yeah. Has a nostalgic feeling to it. Now obviously I'm not using AI here because I want to understand how it works and what's going on here. And I find that important if you're learning something new. Even in these days it also wouldn't make for a fun live stream if I would just vibe code away. And yeah there is only so far you can get with vibe coding anyways.
Now that our models and database tables are ready, we need to populate them with dummy data for development and testing.
Factories act as blueprints for creating model instances filled with realistic fake data. You define blueprint once.
Okay, so we want to make a post factory to pump out some fake posts.
So we run the make factory command. This gives gives us a post factory file where we now basically define how we want to generate posts, I guess. So let's copy that in here and let's take a look.
So we're saying we want to build a fake post. We have a bunch of titles from which um this faker tool can choose when it generates posts and some madeup URL and some madeup Lauram ipsum paragraphs it should add.
So just a programmatic way of quickly adding some fake data. Obviously, these days we could also use AI for that, but let's go old school and cheaper because no tokens. Let's also create a comment factory.
Here we are. And let's copy in that code here. And here we just spit out some Laurum dummy paragraph.
And now we need a cedar. So now we got the factory that can pump out fake data.
But what do we want to do with the fake data? we want to get it into the database and that's where a cedar comes in. Um so we want to create one and these are general concepts factories cedars you don't just know them from adonis you know them from laravel or you could use these concepts um uh for in any setup also in an xjs application you might have a database which you want to seed with some data there obviously the node ace commands are adonis specific though but now we create a cedar and let's take a look at the post cedar so that's now a file which we and run to push some initial data into the database. And therefore, we need to define what we want to do in here. And I would guess what we want to do in here is create some dummy posts and comments, connect them, and them uh then run something to get it into the database, however that looks like in Adonis. So, let's paste it in and take a look.
So, we are finding or failing. So we're trying to find a user and that should fail because it doesn't say that it creates one and we don't have that user. So we try to find that user. We'll have to create it.
Then we merge this user and we create many new posts and basically link them to that user with this command. And then for each of these posts we create some dummy comments which we also then connect to that post and to that user. and we create some random number of comments plus three. So at least three comments um but up to uh up to six comments in total for each post. So between three and six comments.
Uh first we fetch a user with this email. This is the user we created in the previous chapter with the O. So I will create that user myself. Let me quickly do that. Uh, let's serve this.
I haven't tried to running the cedar yet, so that should work. That's wrong.
Um, let me quickly sign up.
Yeah. Yeah. No, not this. Let's uh I will use Okay. So, I will use a different email address obviously. I will use [email protected].
Okay. So, we got that. Um, yes, please keep going such streams. We like them. Yeah, I definitely want to keep them going. And by the way, uh my plan is to have a stream like this every Thursday. Next week, I won't be able to do it. Uh I got some other appointments there, but in general, every Thursday this time, so starting at 5:00 p.m.
Central European Summer Time, that is my plan. I try to make it as often as possible. Um and hi, David. And do I think Claude in Copilot will continue? I read they'll cancel pro next month. So to me it looks like Anthropic really wants to push their own tools. They want to push claude code and nothing else.
They want to lock people in there. So we'll see. I I'm not too confident that we'll be able to use Claude in all kinds of other tools at least not with the subscription. Paying for tokens that will probably be possible because you're just using the API then. But that's of course also super expensive.
Uh so let's now run the cedar.
Cancel this server.
Run it. And that now created the dummy data. And we should be able to see it already even without the app being ready. In the database we can see posts and comments tables. In the users table I got my user. And in the posts table we get some dummy posts here. And in the comments table, we get some dummy comments.
And each comment is linked to a certain user and post ID. Obviously, we only have one user here. So, they're all linked to that one user. That was what we wrote in the cedar. And then for the post, we see here we got a post with what is that? Five comments. Here got one with three comments and so on. So, that's in line with what we wrote.
Okay. So, I understand what we did here.
Querying data with the ripple will not do that. we already saw that it's there.
Uh but yeah, but we'll take a look at the code here. So the interesting thing of course is that with that model based approach, you don't write SQL queries or anything like that. Instead what you do is you use your your model and or you access all the models then your model and this exists because we registered a model with that name and then you can use methods like all to get all posts or as we see here you can write queries where you have some wear clause to limit the number of posts and that is how it OM works you programmatically query your uh data and you don't write SQL statements now to be very honest I'm not not a huge fan of OMS or I have nothing against them but I'm not using them typically and especially nowadays with AI I find writing raw SQL queries easier than ever. So for me I typically use raw SQL queries in my applications. I don't use OMS because of course you got the full power if you write raw queries and even before AI many many queries weren't that difficult to be honest even with joins that's not that hard and of course SQL queries can get quite complex and AI can get it wrong but in my experience it's pretty decent at most queries including more complex ones so that's just my two cents but here we're using the OM so I'll stick with routes, controllers, and views. Uh in the previous chapter, we created the post and comment models with their database tables and relationships. Now, we'll bring those models to life by building pages where users can actually see posts.
Your posts and comments exist only in the database. The the server is already up. Uh so now we want to create a new controller. And the idea with this framework as I understand it is that you have a route, you have a controller and you have a view. So good old M uh VC if some of you remember model view controller it's it's a it's quite an old way of structuring your your applications not just web applications.
Um but old doesn't mean bad just to be very clear about this. Um but you don't see it really in in all those Nex.js applications and so on I guess. So yeah um in a different tab let me run this create a new post controller. Here it is an empty file and in there we now register methods which then define what will happen in four different routes. Again I'll copy this in to save some time.
And what we have here is an index method. uh we get some HTB context here which again is that thing that gives us all kinds of data and actually we have to tweak this because this here is for I I need to use inertia um I need to use inertia and of course we'll need to add this component but what we're doing here is we're um using our post class so from our models uh file right so here the post class uh which we defined before and then again this is the for M& action where we're creating a query preloading user is probably there so that we load it um once and then not again for every post we're fetching I assume and then we order um the posts obviously by creation date descending so the the first post is the uh youngest uh the most recent one so then we render and therefore we will need to add this defining the route.
So now we have to yeah well the route is that we go to start routes and here we added here we could add it anywhere of course.
Um and why is this not working? Why is this not working? Do I need to restart the dev server or something like this?
Whoops. That's wrong.
Oh, I didn't have the dev server up and running. That's my bad. So now let's bring it up and then hopefully yeah, now this is auto created. So basically Adonis is creating a bunch of type definitions on the fly. So now this is this is here. Um we tell Adonis that for requests get requests to slashposts, we want to trigger the index method in the posts controller and that of course is this method.
Now we will need the view and we can make a new view. It I don't know if this is the right command if I want to have an inertia view. So let's see.
Um I can run node a list to see what I can make.
So I can make a view but that's a edge.js template file. I don't want that.
Uh maybe I do have to create it by hand.
Looks like I have to create it by hand, but that shouldn't be too difficult.
Let's go to inertia pages off. So in there, I would now add posts and in there add a index.tsx file, right? And then I export a default function and I'll name it posts.
And I'll say something like my posts. So just a regular react component.
Now this error here is gone because now I did add um that thing right. So I did add a posts folder with an index.ts file and that is exactly what I said here. So this is how this is linked up and there for now of course with the development server up and running I can go here enter slashposts and I see my posts here. So that's working. Um, and now of course we just need to get the data from the controller into that component.
And actually we're already doing that here I assume as props. So the question is if in here we get this. Now how do I Oh no I think we have to do children.
How how does this work in the other file here? Do we have any file where we transmit data?
We don't. We don't. We don't. We don't.
In the layout, right? Uh children.
So, I assume this is what I need, but I never did this before. So, we'll have to figure this out.
Um, is this not what we have here?
Uh, oh yeah, my bad, my bad, my bad. This is not valid TypeScript code. Of course, this should be like this. Okay. So now um we need to add those at import at import. So I assume this is correct.
Is that what we have here? Data generated data. Yeah. Okay. Okay. So now let's see can we add like a fragment here and then do something like children props.
Hm.
User. Yeah, maybe it's not the share props. How do I get the I probably have to dive into the uh let's see. I probably have to dive into the docs for inertia here.
Uh guides. Where is here? Inertia. How do I get props into my components?
Uh I need do I need a transformer?
Use a transformer to serialize model instances into plain objects. Got it.
Got it. Got it.
Okay. So, what I'll do here is I'll cheat a little. Bring in some AI here.
Um, building an Adonis JS app. I need to get my posts.
see post controller into my posts inertia. Whoops. I see that this is not readable for you.
Okay, wait a second.
Okay, building an Adonisjs app. I need to get my posts from my posts controller.
Add oops add posts uh controller into my posts view inertia view.
So that is um index in the posts uh folder here. And now I'll just link to these pages. Please check out and to help me do that.
And let's see if it can figure that out.
Um, ORMs are good for schema transformations and collaboration.
Um, yeah. Uh, and again, I don't say OMS are bad, just just not what I personally lead for my projects. But then again, I'm not working in any large teams or anything like that.
Um I I definitely do say that I use migrations though. So it's not like I don't use migrations or anything like this. Um I just also write them myself or have LLMs write them. So migrations are very useful. I just don't need the ORM part. I was wondering to ask you about WIP coding is good or not. I don't think wipe coding is good for anything serious, but wipe coding definitely is very good if you just need a quick utility tool or if you just need to get a job done, right? If you're building some software, you're selling, if you're working on anything serious which you plan on distributing or in your job, wipe coding just lets you lose all track. You don't understand what's going on in the codebase and eventually you'll hit a wall and you won't know how to continue. So not caring about the code is not a good solution for for such situations. But again, if you just need um a a a quick tool which you run on your machine or anything like that, you may not care about um about the all the details and and stuff. So yeah, V coding can be good there. And yeah, live coding is always always challenging, but we'll see if the AI can figure it out. seems to be fighting some linting errors here.
But yeah, I am just using AI by the way.
Normally I would dive in here and build it myself, but I have to go in 20 minutes and I rather get the finished code now and work my way through that now so that we can also thereafter continue here.
That's the main reason. So, okay, now it did something here. And let's first see if it works before I start explaining it. And then we'll see what it did. But looks good. Styling is totally awful, but as we can see, um, I got a bunch of posts being rendered here. And I can see that they are linked to my user. So, sending the data from the controller seems to work. So, let's now see how it works. And again, I gave it the links to the official doc. So that is just um um that is just what the docs would have taught us too.
Um so in a post controller we're getting the posts. Um the only thing that changed here is essentially that we pass our posts but not raw like this but instead with help of a post transformer that is a new thing it added. So this file is new post transformer and that is a class which extends base transformer.
Okay. And in there we just describe how to serialize a post. So we're saying hey pick all these properties and for the user also transform the user. So essentially I mean in this case transforming should be pretty simple. Um it it just probably takes the ISO uh format dates here and and the other raw data can be packed into a JavaScript object like this. So it basically describes how to convert the class which may contain stuff that can't be easily converted to JSON. How to convert that to JSON? That is the job of the transformer as I understand it.
Okay. So then we set the posts here and now in the view in the view we get page. Okay. We just set up page props like this. Okay. We just set up a props type, a TypeScript type using inertia props. Is that some generated types or did the AI add that? I assume it's some gen it's some some standard types not not generated by the AI and we just say okay hey here we'll have a posts key and that is of type yeah so that's an autogenerated type here for for our posts and I assume this type is generated based on how we transform the posts so post here um this thing yeah is coming from the post transformer exactly Okay. And then we can just render them here. It's not too difficult. Got it.
Okay. Now, again, the official tutorial here uses the edge view. So, I'm using inertia. And as we see, it's just a react app in the end. Uh where we also then uh transform and send our uh props.
Okay.
Um displaying a single post. Yeah, sure.
So now we can add another um method here in our controller because in our post controller at the moment we have one index method for displaying all the posts but now we want to also add a method for displaying a single post. So we are adding a show method here as it seems and again these names are up to you and later when you connect them in in the routes file you must make sure that they match but we'll see that in a second. So here we're getting some params because now we have a dynamic route and again you may know that from react or that's the routes with the with the colon parameters in the route name for example or the dollar signs in the file name. Um so here we're also getting some dynamic parameters and we'll see how we register those routes in just a second. And then we expect to have an ID parameter. So we're looking for a post with a specific ID. We want to fail if we don't find it so that we can show a 404 error or any other error. I assume we want to render not a view. Instead, we want to render we want to get inertia here and we reuse our post uh transformer to pass our post to um to a show component for example. So now in the inertia folder in the post folder we need to have show tsx or detail tsx or anything like that. And now in there uh we have our our post component here. Actually let's name it post post like this. And then just as before, I'll quickly steal that.
We get a single post here. No array.
So like this. And then we can return um Yeah, sure. The post title like this.
Hello. Yeah, like this. Okay.
What are we doing here? So uh and then of course also the the post summary for example. Sure. Okay. So we got this uh should work. Now we need to register it in the routes folder. So now we can add a new whoops a get route for slash for slashposts. And then I assume that is how we register dynamic routes. Let's see.
Yeah with colon id. Pretty typical. And now we're saying, hey, in our post controller, it's the show method we're interested in because in that controller, we named this method show.
If you picked a different name here, we have to pick a different name here, too.
But show is the name I'm using, so that should work. Um, so, uh, which links do we have here?
Oh, that's not a link to a detail. But if I add posts one, yeah, I do load the styling is totally off, but here at the very bottom, we can see the the content.
So, and um the title markdown blog engine is also here. So, it's just totally broken styling, but it it works.
We can see that route. Uh and we could of course fix the styling, but that's not the most important thing right now.
So, yeah, we we got the view. We already got all of that using the named routes.
Oh, that's interesting. Yeah, right now we're hard coding URLs and and I am actually not setting up any links at all. So when you use a controller in your route definition, Adonis.js automatically generates a route name based on the controller and method name. So if we have controllers.postsindex, that is that gets the name posts.index automatically. So I assume we could go to the posts index page where we have all those posts and instead of using an anchor tag like this we could use the link component which comes from inertiajs react also here and then I'm not sure has it a two prop or is it is it ref and then we could say something like routes post Show doesn't seem to work like this. Uh post show.
Yeah, I'm using a different approach. I want to use this link component again.
Do we have that in here somewhere? Link route.
Oh, okay. Okay, it's just Okay, so it's link route.
Why am I getting an error here for route?
Creating links. The link component creates navigation links. Oh, the import is wrong. I need to import that from here from the Adonis package. Now we have support for the route. Now it's just posts.
Um h it's just a string. It's just a string.
Okay. So it's just route. Okay. Now we got some auto completion here. And now I need to set the params.
Route params.
Post ID. Uh no post do ID.
So that must be an object ID is set to post do ID and that will now dynamically generate a different route for every post and populate that dynamic placeholder with the post ID I assume.
So if I now reload here, not here but here.
Um why was this not updated? Do I need to restart the development server?
Oh, save saving the file also probably helps. Yeah, now I can click here and navigate to these posts.
Styling is still awful, of course, but that works.
And of course, the advantage of using route names here is that if we ever change the path, we don't need to change the links as long as the route name didn't change. So, that's of course nice to have. Now, you might not change the path all too often, but still pretty nice.
Um, hi, it's Kitty. And yeah, it is inspired by by Laravel. It's absolutely it's I think they themselves brand themselves as uh Laravel for JavaScript.
Do you have to write software with your hands? That's like a baby's toy.
Um well for for so when you learn something I would definitely do stuff I would definitely write code with hands because just by reading I I'd do a mixture but of course for a live stream I don't find it too interesting if I just let the AI rip through it. But I did use it just a couple of minutes ago. Um but yeah for learning you should definitely get in there and reading alone reading alone doesn't teach stuff that well now I will not say that you will write all the code like you did maybe four years ago not even close to it but at least some basics to get a feeling I mean here you just joined right but I was just copying code I wrote basically no um code yeah I know I I I got you no offense taken. It's just I think writing code it's it's just in general a good point. That's why I'm just commenting on it. Uh I think uh writing code is still good for for learning. Um but even though that was a joke or or a quote um it's it's it's obviously changing and um I got asked earlier um about new courses and one problem or what I'm trying to figure out is how you best learn technologies right now and if it still matters and I would say yes it definitely still matters. Um but yeah, exactly that point. How much do you write by hand? How much do you copy in?
How much do you let AI explain or generate that? That's I'm just rambling on, but that is definitely something which is changing. And this is adon.js.
Um cha cha cha. So it's um it's uh basically Laravel for JavaScript.
Um okay. So, um, yeah, comments. I don't think I'll do that. Um, and I got to go in 10 minutes.
So, we'll probably leave it as is here and just take a brief look at the remaining few uh pages here. It's not much left in this guide anyway. So, we went through it pretty well. Forms and validation. Um so here the idea is that of course we can also have controller fun uh controller methods that are invoked upon post requests. We can see that in the do we not have a user controller uh user uh this the new account controller uh here store that is um a controller method that is invoked upon a post request. this one and therefore it's just a regular method.
But in there we can already see you can use the validate using um method and define a validator which is in the end just a little utility object created with that vine tool here uh where you can define some rules for which kind of data you want to accept and then errors will be generated automatically for you if if the validation criteria is not met. So the entire idea behind Laravel and Adonis is that they do a lot of work for you and you can define your logic at a pretty high level. Whereas in Nex.js and and so on, you often have to really become specific and obviously you have to bring your own validation library and all that fun stuff.
Um so what we're doing here is um yeah registering the routes. We already saw that uh creating a new view in this case and here they're creating a forum. Now these are all some edge specific um code snippets but of course um we have that here as well.
Where is it? Log in. Yeah, we can see that if we're using inertia we have this form component here which is coming from the Adonis.js JS inertia package which is also linked to a route that should be triggered if the form is submitted which is that store route we just saw or that store controller action that's in the end invoked by that route and the data I assume is packed into the request and submitted to the back end automatically which is of course convenient that you don't have to write the code for that yourself or ask the AI to write it for you. If you're using edge, you can render your form inputs like this. And arguably this is a bit easier to reason about and than and read, I would say.
Um, and then we can create validators. We saw one already before with that wine thing where you simply define for the data you're about to receive. What are your rules? So, min length, max length, data type, and so on. Get the store method. And then again we can use the OM use our class call the static create method to to store the data comments do the same thing also link it to a user through the ID and we get the user through that off um property which we get automatically and again that is like Adonis doing its thing and uh doing the authentication for you thanks to the middleware that is registered right so in routes We get some off middleware for example and any routes in here require authentication and any routes in therefore also um also get this off property which you can use to get the data about the currently authenticated user or which you can use to log the user out like in this case and so on. So that is all pretty convenient once it is set up. Um, I assume at least it's it's not like I've worked with that before, but yeah.
Uh, I've learned view free from you and forwarded the principles to codeex such as Codex writes high quality, so your lessons are still valuable for good prompting. Yeah. And one thing I'm exploring is also how can you for future courses include stuff like agent skills or extra documents that you can feed to your agents to help them write better code. though of course it'll never be a guarantee because um agents can always do it their own thing and so on but that is something I'm also exploring of course and do I prefer Adonis or Vue3 so Adonis I really just got started with um I haven't used it at all before and U3 is not really an alternative because Adonis is full stack and Vue is client side front end with next it would be full stack again but then we would still have different philosophies where Adonis is batteries included. So all that stuff like the authentication and so on built in whereas with next just like just like with next you have to bring your own libraries and ultimately I don't know what I prefer. I I like the Adonis approach and I definitely see it being valuable if you're building um a full stack application. Now I'm so used to Nex.js JS to to tan ST start and all that stuff that I I don't know if I would switch to Adonis just because I'm probably faster with those other tech stacks.
But then again, there are good reasons like having less external dependencies besides Adonis and so on. So, um I will probably continue playing around with it and then evaluate where it's useful for me, where it isn't, if I want to build more with it. Um yeah, that's that's essentially the plan. And I think well, no, will not end yet. I don't care too much about styling. That's just CSS. But authorization, I want to take a look at that.
So there is another package we can install that's part of the Adonis ecosystem the balancer package which is there to by the name and the name of this chapra would say it's it's responsible for blocking people that are not allowed to do something. Um and of course authorization unlike authentication is about blocking users from doing certain things they are not allowed to do. Um so for example a user could be logged in but of course should not be able to edit the posts by another user. Makes sense.
So authentication alone is not enough.
Often you need authorization in addition and that is where this bouncer package seems to be useful because then you can create so-called policies as it seems.
And let's take a look. A policy is a class which extends a class from Adonis from the bouncer package here. And we can then define okay so we can basically define permissions here like editing is allowed if the user ID matches the ID of the user of the post we're trying to edit. The same for deleting and then we can probably apply those policies. Let's see. We we have them um add controller methods. Where are we applying? Oh yeah, here. So in our controller we here they added a new method an edit method which should be triggered obviously if you like try to submit a forum where you want to edit a post or where you probably want to load a page for editing a post here now that I look at it and in this method we're finding the post you want to edit but then before returning the view this bouncer package gives us a bouncer thing where we load a policy we want to apply and where we basically check through the policy if the user that is trying to edit this um is allowed to do so.
Makes sense.
Okay. Um so let's see chat AI can build an app in 10 different ways in the same library. So maybe focus on programming paradigms on how to organize code. Yeah, absolutely. uh I think that these are the important skills for both developers and AI through documents through skills that you teach it certain patterns that you know your fundamentals and stuff uh and that's why I'm also planning courses on programming fundamentals systems design and and all that fun stuff when there is a better bet to do backend web API and strongly typed languages like C and not sure why it was censored here or rely on NodeJS with TypeScript which types are erased And there are tons of vulnerabilities in npm packages.
So ultimately regarding the backend languages, I could probably talk an hour about just that and I don't have an hour. But the the huge advantage of NodeJS and the entire JavaScript ecosystem is of course that AI knows it really well if you plan on using AI for development that there are tons of packages. But of course there is the huge downside of supply chain attacks and so on. Definitely and other languages can also give you better performance. I would absolutely look into using Go, Rust, C, whatever you're interested in for back-end development too. But I will say that my experience is that you have a high velocity when using TypeScript because with AI it's it knows it so well. And of course for me I know it so well. So I can quickly see the parts where AI takes a a wrong direction and so on. So there is that but yeah definitely there is a lot of merit in using other backend languages as well. It doesn't have to be JavaScript for everything. Uh why is NestJS more popular? I honestly don't know. I never fully understood why no why Adonis uh was and is so niche. I I I have no great explanation for that, but I now have to leave. So, that was interesting. That was fun. Um, definitely was interesting to dive into Adonis and and take a look at it. I hope you liked it, too. Thanks for joining again. I try to be back every Thursday.
Next week, I won't be able to make it um the week thereafter. I'll have to see.
But yeah, I always announce it in my Discord. So, if you're not part of it yet, you can head over to.com/ community. Join the Discord. I announce it there. Or, of course, simply subscribe, follow me, and then you'll see it. But yeah, Thursday, um 5:00 p.m.
Central European Summertime, and I typically end at the time where I end now. And yeah, so thank you all and have a great day, evening, morning, whatever it is for you. And hopefully see you in the future. And uh yeah, thank you all for joining.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











