Build Fullstack Apps in Record Time with Blitz.js


Blitz.js is the Fullstack React Framework. It's heavily inspired Ru on Rails and is focused on making you as productive as possible. It's built on Next.js and adds all the missing pieces you need for building a fullstack app with a database. By far the biggest innovation of Blitz is the new "Zero-API" data layer that abstracts away the API so you don't have to mess with REST or GraphQL APIs! Brandon will cover all the important parts, so you'll know if you might want to use Blitz or not.


Hello. Hello. I'm so excited to show you Blitz.js. Let's get into it. I was building React apps for a number of years. Full stack React apps. And I happily put up with the complexity and struggle required to do so. And I did that because I loved building user interfaces with React more than any other way. But the honeymoon ended. And I became increasingly frustrated with all the complexity. Things like REST APIs, GraphQL APIs, multiple servers, deployments, state management, configuration, libraries, tooling. Everything, just anything that got in the way of me building features slowly depleted my morale. I really wanted to love full stack development again. I wanted to be extremely productive again. I wanted to focus on building features instead of all this other unnecessary configuration and conglomeration in my app. So I decided enough was enough. And I set out to build the best possible developer experience for full stack React apps. So there were two things that I really wanted to have for this experience that I was going for. Number one, it had to be a monolithic. Monolithic means there's one thing to think about, one thing to build, one thing to deploy. It's everything is together and cohesive. And it's just much simpler. I got into web development through Ruby on Rails, which is monolithic. And so I know the productivity benefits that you gain from that. And I wanted to get back to that. Secondly, is I wanted to get rid of the API. The API layer in React apps is one of the biggest sources of complexity, confusion, headache, heartache, just pain. And so I wanted to get rid of that. It's amazing, like we don't realize how much that API layer slows us down and gets in the way until you don't have it anymore. And then you're like, wow, this is amazing. And so I knew a sense of what that was like because of Ruby on Rails, there's no API. You can talk to your database directly from your view if you want to, not recommended, but you can. And so this was very critical. But how can you accomplish this with React? At the time, so this is back when I started Blitz, like 14, 15 months ago, I was thinking, how can we do this? The only way I knew was server side rendering. And that's how Ruby on Rails does it. And so, well, I was like, we could do this. At the time, Next.js had just added the get server side props, and it would just seem like that would be a good approach. So when I first announced Blitz, I said, all right, here it is. What it is, I had initial prototype that was server side rendered. But I didn't love it. I didn't love it. And that was critical for me. I wanted to love what I'm using in my day to day work, you know? So me and the other early Blitz contributors were hashing this stuff out, talking about what would the architecture look like? Would it be a model view controller? Would it be, what would it be? And one day, I was laying in a hammock in Thailand, pondering this. And I asked myself, what would this look like if it was easy? So as I sat there dreaming about what could I possibly, what would be easy, I got this picture in my imagination of just a function that runs on the server that talks to the database, and just importing that function directly into my front end code, my React components. And then the framework would magically make that thing work, actually like put an API layer in there. And but the user wouldn't have to deal with it. And so I was like, wow, that's a cool idea. I wonder if I can make it work. And turns out, we made it work. Oh, yeah. All right, so let's get into some more specifics about Blitz.js and why it's awesome. Number one, Blitz is built on top of Next.js. If you don't know Next, Next is a hybrid framework. Excuse me. Next.js is a hybrid framework that allows you to do basically everything you need to do. So it allows you on a per page basis to do client side rendering. So it's just a static client side rendering. You can do server side rendering. You can do static page generation like Gatsby, where the entire page with data is generated at build time, or even updated during runtime. And then lastly, you have API routes, so you can do any sort of API processing. And lastly, you can deploy it to a server or serverless. So it's really awesome, but it's very minimal, and it doesn't give you very much. So if you want to use it to build an app, you still have to do a ton of work just to get to ground zero. All right, secondly is Prisma. Prisma is a next generation ORM for JavaScript and TypeScript. And Prisma does two things that you really need inside a full stack framework. Number one, you need an easy way to manage your database schema and your database migrations. And Prisma allows you to do this in a really awesome way by defining your database schema in a GraphQL like syntax. And then Prisma will declaratively generate the migrations for you. You can modify the SQL directly if you want, but by default, it's just super simple and easy. And then secondly, Prisma gives you a fully typed database client that gives you autocomplete in your editor. And so you can see exactly what fields are in your database, the types, etc. And it's just a really handy interface. All right, let's talk about the foundational principles of Blitz. Number one, full stack and monolithic, which I already mentioned. Number two, API not required. So, of course, you can add your own API if you want. If you need a REST or GraphQL, you can add that and it's fine, but you just don't have to if you don't want to. Number three, convention over configuration. Number four, loose opinions. So we have opinions and recommendations on how to do things, how to structure your code, etc. But for the most part, we don't enforce those. And so the opinions are loose. It's easy to go off the rails. Secondly, or sorry, next, fifth, easy to start, easy to scale. And a framework has to be good for both ends of that life cycle, right? It has to be easy for people to pick up, but then it has to actually last you well into production projects. Next is stability. We're going to, once we get to 1.0, implement a stable, predictable release cycle inspired by EmberJS. Lastly, community over code. We really care about community, about having love and respect for each other and getting along. And so that's a key aspect of what we do with Blitz. All right, so now what does Blitz actually do for you? How does it actually help your day to day life? Well, number one, when you set up a new project, it saves you up to like a week of work, perhaps, because all the basic setup is done for you. So things like folder structure, ESLint, Prettier, Husky, GitHooks, Jest for testing, databases already set up for you, forms, form abstractions. And the big one is user sign up, login and logout is already done for you. Out of the box, as soon as you create a new app, you can instantly start the server, go to the web page, click on sign up, enter a username and password and sign up as a user. And then you can log in and log out. And this is amazing because you don't have to worry about using Auth0 and integrating it or setting up your own password stuff or whatever. It's just all done. You don't even have to think about it. It's so awesome. And then also we have the reset password flow in there for you. And so it is just, it is just so sweet. All right, now the next big piece of Blitz, which I already mentioned, is this zero API data layer. This is the big innovation of Blitz and one reason that people pick it. So we abstract the API into a compile step. So there is a client side rendering. It is an API at runtime, but it's just a developer doesn't have to worry about it. So you can import your server code directly into your front end. And then at build time, we swap that out with an API call. And this is enabled via what we call Blitz queries and mutations. Now these have nothing to do with the GraphQL. It doesn't use GraphQL. It just uses the same naming. Queries and mutations are plain asynchronous JavaScript functions that always run on the server. So here's a simple diagram on the right side. The top right, you have a purple box and this is representing a client side rendered page. And then the bottom right, you have two green boxes representing a query function and a mutation function that talks you to your database. The dotted line represents importing these queries and mutations into your React component. And then this gray box is what is auto generated at compile time. And so each query and mutation has its own endpoint. All right, so let's do a quick demo and get into some code. So what we're looking at here is I have just created a brand new app, Blitz New JS Nation. So it allows you to pick a form library. In this case, React Final Form is what I chose. And then it creates a bunch of files. So don't be overwhelmed by this. And because what we're doing here is optimizing not for initial first impression, like, wow, this is so simple. There's only one file. But it is we're optimizing for actually building a production app. So we give you all the code that you're going to need at some point, like your root app component, your document, etc. But most of this code is related to authentication, which you can easily delete this folder if you didn't want it for some reason. So and then there's a lot of just configuration files like Babel, Jest, all that sort of things. So just take your time with it and go through and explore it. But it's pretty minimal, even though it looks like maybe it's not so minimal. Okay, so now we are going to run Blitz Dev. And this is going to start that server. And we'll just take another look at the files here. So this app folder, top level app folder, is where most of your application code goes. And then we recommend separating it by domain. So in here, you have like auth folder. And here's your components, pages, mutations related to auth. You have core. So this is things you're using all across your app, components, hooks, layouts, pages. And then you have a users folder inside there. We have a query set up for you. And so now we can... Oops, wrong monitor. Get this in the right monitor. So here's what you get when you run this thing. So pretty simple, but you can have a sign up and a login button. So we will click on sign up and hide that thing. All right. We are creating a user. And now we're signed up. User ID of one and a user role of user. And so I could log out, log in, whatever I wanted to do. Isn't that awesome? So now I'm going to show you another really cool thing, which is Blitz Prisma Studio. Now this comes from Prisma, but we have it integrated here with Blitz. And this opens a graphical, like here, it's a web page that allows you to see all your tables or models in your database. And click on that and then see the records in here. So you can see the email, the hashed password, the user role, all of these sort of things. So it's super easy. You can add things, edit. So it's a really nice experience. All right. So now I'm going to show you how we have code scaffolding. So it makes it easy to add models. So we're going to say Blitz generate all project. And we're going to give it a name and it is archived to Boolean field, which is optional. And so this creates a number of pages. Projects, adding the migration name there. Okay. So this creates all the files that you need for all your operations, your CRUD operations. So create, read, update, delete. Gives you all the pages and then all the queries and mutations. And so this is all ready to go. And then of course, add your model to the schema. So it adds ID, created that, updated that for you, since you almost always want those. So now we're going to run this again. Go back here, reload the page. And now we can go to slash projects. And you can see there's a list of projects here, but there's nothing created. So we can click create project. It takes us to slash projects slash new. Let's just say JS Nation, create project. And then there, the slash projects slash one is project idea one. And then we can edit this thing, go back to the projects list and there it is. So it's all set up ready for you to go ahead and add your own styling, your own features and functionality. So I'll quickly show you what that looks like. So we're going to go to project ID. So this is the page that display a single project. So down here at the bottom, we define a page. We use the suspense fallback loading thing. And then we say this is authenticated page. So you must be logged in. Otherwise, you'll get an error. We define a layout. And then up here inside this core component, we import a use query hook from Blitz. This is built on top of react query. And then we import the get project query Blitz query that I'll show you in a minute. And you pass it the arguments, which is ID project ID, which comes from the URL. So this returns a project and you can see that this is fully typed via TypeScript ID, name, created that, etc. And then we just render this out. So in this case, we just say you have project ID. We just stringify it and display it here. All right. So now let's go look at this get project query function. And I'm just going to reformat this slightly here. So it's easier for you to see what's going on. Okay, so this is exporting a default function. And the signature of this is you have input data as a first argument. And then you have context parameter. And then it returns a result. So this is the basic format. But what we have set up here is a bit more what you want for production. So we have a pipe utility, which is a functional pipe. It just pipes the input and the output up from one function to the next and just like chains them together. And so the first thing we're doing here is using Zod, which is a validation schema library to ensure that this input is what we expect it to be. This is very important. Secondly, we call resolver.authorize, which ensures the user is logged in. So if they're not logged in, it's going to throw an error. Now we could if we wanted to define a role, a required role. So we could say authorize admin. And so this would throw an error if the user is not an admin. So we have all this stuff built in out of the box. It's super cool. And then this function, first argument is the data. And then we also have a context argument in here. And so what we do is we call db.project.findfirst. So this is Prisma. This is how Prisma works. So we just pass in a query and we get back this project. If it doesn't exist, we throw a not found error. And then we could also access the user information like user session.role, user ID and things like that. And so then we just return that project. And so that's it. Okay, so you take this function and then you go back here, import it here. And it just works. It's super cool. And then the same thing works for mutations. So we have a delete project, user mutation, and that goes and similar code there. All right, get back to a few more slides here. Now we have a thing called Blitz Recipes, which makes it super easy to integrate third-party libraries. So with just one command, it'll do everything that is required, like installing third-party dependencies, creating config files, adding theme providers and things to your application. It does all that for you. It's super cool. We have Blitz Console, which is like a Rails console, if you know what that is. It's a REPL that loads your code, your database, and allows you to just run one-off commands and things. It's really cool. All right, list a few other features here. We have Passport.js adapter for social login. We have HTTP middleware, advanced data serialization. We actually wrote a special library to serialize. So dates and things are automatically serialized and deserialized for you. You can deploy to a server or serverless. We have custom server support and it's database agnostic. So you can use anything you want, such as FAUNA or DynamoDB. All right, who's using Blitz? Tons of people. Startups, people tired of Rails or Laravel. Mr. is our biggest Blitz app. It's a high-traffic site, and they converted from Next.js and Sanity to Blitz. Agolia has two internal Blitz projects, students, high projects, et cetera. So this is a testimony from one person. He said, I used Rails professionally for over a decade, and I feel 10 times more productive with Blitz already after just a few months. So that's really cool. So why did people choose Blitz? Mainly because it's built on Next.js and product iteration speed. So it's super fast because you don't have the API layer getting in your way. So you can try Blitz by installing Blitz globally and then running Blitz new MyApp. So we're open source, so we would love you to contribute in any way you can. If you want to do code, documentation, videos, blog posts, financially, anything is super helpful. And then you can become involved as much as you want. You can become official maintainer. We have a couple levels of maintainers and then, of course, all the way to the core team. All right, go to to get started, to read all the documentation. And then on Twitter, I'm flybear and Blitz underscore JS. You want to keep up to date there. And then last but not least, you can get free stickers. We have free stickers for you. Go to slash stickers. Enter your information and we will send you free stickers anywhere in the world. So thank you so much for listening today. And I hope that you try out Blitz and let me know how it goes for you. Thank you very much, Brandon, for your session. No doubt you'll see that number of downloads from NPM after this 20 minutes go up. And I bet you inspired many, many folks to try Blitz.js. And yeah, we have some questions for you from audience. But first, let's check what folks answered on your question. And the results show me that only 13% of people tried scuba diving. Actually, it's funny what I see, like 13% answered yes and 88% answered no, which gives us 101%. I don't know, maybe I don't understand how Slido works or they have to fix some rounding. But yeah, let's keep it for later. So are you surprised by these answers? No, it's probably about what I expected. If anything, it's maybe a little bit less lower number of people that have tried it, that have been scuba diving. And I believe if you have this question, you tried it yourself, right? Yeah, I've wanted to my whole life. Last year when I was in Thailand for five months, I finally got my certification. And so yeah, it's a blast. Cool, cool, cool. Is it very different from regular snorkeling? So do you recommend everyone to try this? Yeah, yeah, I would definitely recommend to try it. Also, free diving is pretty cool. I did that a little bit. So free diving is where you just hold your breath and you can go down really deep, even like hundreds of feet deep if you're really good. Yes, and thanks for questions like this. I think by mixing technical and non-technical questions, we provide very nice balance between learning and fun, between work and rest. So yeah, kudos. But we have technical ones also. Let's start from this one. Since API layer is abstracted away, what's the experience like for integrating mobile apps with Blitz? So there are some people doing that today, integrating it with mobile. It's not the greatest experience. We're not optimized for it yet, but it's something we definitely want to work towards and make it really nice. So we have some discussions on GitHub and even a page in our docs, a section on it. But the basic starting point is there's a number of different approaches you can take. You can add a GraphQL or REST API to your Blitz app and just do that. Sometimes that works great for your mobile needs. You can also use the auto-generated Blitz API and use that manually inside your app, do the manual fetching yourself. Right now, we don't do anything to help you with that, but we want to. So there's a couple of things we can do is generate a client that you can import into your mobile app and it'll make it easy to access your Blitz APIs. And then we'd like to go even a step further and bring the same magical zero API experience to mobile apps. So if you have a Blitz app and then in the same repo, you have a React Native app, and then you can just import your server code into your React Native app, and then we'd have a compilation step that would swap that out too. So multiple different approaches, but yeah, so there are people doing that today. Awesome, awesome. Nice plans. And by the way, you always mentioned we. Could you tell a bit more about the team behind Blitz? How many people and how do you build your collaboration? Sure. So it was my idea. I kind of started it, but I sort of built the community before I built the framework because when I announced that there was just a couple hundred lines of prototype code, and I was like, hey, I need people to help me build this. And so I got a bunch of people that helped. And so contributors have been like super important to this. So I think we're getting close to 300 total contributors. And yes, we have like level one maintainers, level two maintainers. And so there's a lot of people that are helping make this a success. So thank you everyone that's helping with Blitz. Kudos folks. And I really love your statement about build community first and framework then. Or like product then. It's a great hint. So folks, use this hint. Go back to the technical questions. Is it possible to have in the same project some pages pre-rendered and others not? I have an application where I have a couple of pages which are pretty simple and it makes sense to pre-render them. But others are quite complicated with much logic and there I would prefer to stay with client rendering. Yes, the answer is yes, you can absolutely change on a per page basis, whether you want it to be statically rendered at build time or statically rendered like a runtime, like to regenerate that thing or server side rendered or just a regular client side rendering. So it's up to you. Awesome. Awesome. That's impressive flexibility. The question from Tom, is it possible to use Blitz with a different framework than React or vanilla JS at all? No. So we are heavily coupled to Next.js. And so whatever the rules are for Next.js is pretty much the same for Blitz. And of course, Next.js is very tightly integrated with React. Like it doesn't make really sense without it. So right now React only and for the foreseeable future React only. Got it. Fair enough. And the question about support of different databases, for example, do you support or plan to support Microsoft SQL, Oracle, Spanner and others? So today Prisma officially supports MySQL, SQLite and Postgres. And then there's Mongo support is like in early access, I believe. And I know they're going to be working on expanding to other databases in the future. I'm not sure about Microsoft SQL, Oracle and Spanner specifically, but you can you don't have to use Prisma to use Blitz. So you can just skip Prisma and use your own ORM or whatever database client you want to access any database. So Blitz is database agnostic. So you're welcome to do that. Awesome. Awesome. Is it possible to generate GraphQL API? And yeah, let's get to the second question for the next one. So now about GraphQL API. So right now, the best recommended way if you want to generate a GraphQL API is use Nexus. And Nexus integrates really well with Prisma. And so we already have Prisma in there. And so we have a we have a recipe that you can run a Blitz install. I forget what it is exactly. It's like Apollo GraphQL, something like that. And it will install Nexus and Apollo server for you. And you'll get a generated GraphQL API based on your database schema. Yeah, cool. And from the same participant question, any planned interoperability with open API? So there has been a bit of discussion about that and like how to publish the specs and be able to generate clients and so forth. It's still kind of up in the air. It's really it's just open for somebody who really cares about that to to come in and just like make it happen. So there's a lot of things that we want to do that we just need help for. And so if you have something that you want to see in Blitz, like we'd love for you to come and make it happen. Yeah, that's that's awesome answer and awesome call to action. It's open source after all, folks. If you wish to have some new functionality, please go create an issue or maybe even pull request or at least start the discussion. I think this is it works like this. Are you OK with having more and more contributions and questions and issues and bug reports, Brandon? Yes, absolutely. Cool, cool, cool. So folks, you know what to do then. Yeah, this is all what we have for now. Thank you very much, Brandon. And see you. OK, we'll see you in the full stack app discussion room.
32 min
10 Jun, 2021

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic