Design-Driven Full-stack: an End-to-End Dev Workflow that Scales


I’m going to show you something you haven’t seen before — a simple, integrated workflow made possible by React, RedwoodJS, and Storybook. We’ll start from scratch, generate code for components, design and mock state, then finish with a secure API and CRUD UI.

Sounds hard? It was. But not anymore! 🤯

You’ll learn how to bridge existing development gaps between stateful designs, data fetching, and your API using Redwood Cell components — a one-stop-React-shop for fetch, state, mocks, and design. Teams can move faster. Solo devs can iterate more quickly. And there are secondary benefits from documentation to security to accessibility, which add up to improving long-term maintainability at scale.

Get ready to be inspired by what you’ll be able to build!



Hello Amsterdam, people of internet land all around the world. It is really good to be here. Are you okay if we have some fun? Would that be okay? Alright, I mean some of it we're going to do a walkthrough, but some of it, well, it may get a little bit strange, but we're going to have some fun. So again, my name is David and I come to talk about building a full stack application if, oh, yep, there we go. Oh, we went too far. My clicker, my clicker clicked. That's a question I want to ask you. So you want to build a full stack application, yeah? Yeah. Alright. So that's some good news, but of course you always start with the bad news. And the bad news is that sometimes things can go out of hand a little bit quickly, right? Is anyone, so question for you, anyone who's built a full stack application, who would say, raise of hands, that you've used probably 75% of those tools or tools like that in your application? Raise of hands? Right? How about 80, 90%? Raise of hands? Right? Okay, maybe three out of four, but right? That's a part of the beauty of the ecosystem that we work in, and it's also one of the tensions of the ecosystem that we work in. So what happened before this train literally went off the rails? You're shipping features, right? You just want to build features as quickly as possible, design, dev, deploy, on repeat. And sometimes it doesn't always go the way that you want it to go. There's this way that we assemble all the parts that adds a lot of dynamic complexity, right? And complexity means often going off the rails. The beauty of the JS ecosystem is its diversity, the modularity, and the rate of innovation. The bane of the JS ecosystem is its diversity, modularity, and rate of innovation, right? It's powerful, but sometimes it goes wrong for the same reasons that it goes right. All right, so again, our goal, we want to ship features. We want to do it frequently. We want to ship features as soon as possible. And as our application, as our team scales, as our user base scales, we want to ship features continually, frequently. design, dev, and deploy. And it's not just the technology. So that's what I want to talk about today. We need both an architecture and a process that's going to work across a stack as efficiently as possible. So what gets in the way of architecture and process? Oh, it did a thing again. Hang on a second. You know, I don't trust my clicker anymore. Uh-oh. Did I just give away something? All right, what gets in the way? Has anyone done config before? Oh, come on, raise your hands. I know we'll get there, right? Yeah, config. Well, come on, all you do in javascript is config. If you're not raising your hands, then you're lying. I'm a framework developer, so all I do is config. But I don't know if I love config. Integration config dependencies. All of that adds overhead over time, because also you've got to move fast and keep up with those dependencies. As break and changes happen, you have to keep up with config. Separation of concerns. Now this is actually interesting. In full stack, what you're taught to do is you're taught to separate concerns, which you have to. That could be at the specific end point level. Maybe you're creating an integration with a third party application. Your entire api, right? We want to separate concerns. We want to separate from the front end, right? Working with react, working with state, working with data. If we want to just do design and lay up, we want to separate concerns. What happens when you need to bring those separate concerns back together? What are you doing? Oh, come on. That was a... So what was overhead? You're doing integration and config. So even when you separate concerns, then you have to come back and do integration and config on them, right? Okay. Next one. Clicker. Clicker let me down today. security. Is your api secure? Really? Because you did it? You wrote the CI test too, right? All right. Bad news. Let's go to the good news. design driven full stack. Yes, we kind of made that up. But it's a workflow for people who like to ship features. And I'm going to show you how you can have a full stack workflow end to end that includes that architecture process I talked about that lets you ship efficiently from the start of your project all the way through to scale. So here's what that means. I want to start with a standalone project, and we're just going to have a file that's going to be html and css. And we are going to do a walkthrough. It takes me about 25 minutes, and I knew that wouldn't fly. So we're going to go through some recorded and do a little bit at the end. But I want to show you this. We're going to start html, css, JSX file. We're going to create a component. We're going to design in isolation and do layout. And then this coupling place, we need to work with data, because data is what we need to couple. But the lack of being able to mock data specifically for fetch and state is often where coupling breaks down. So we're going to work through that stage of doing mock data. And then we're going to build out all of our api for CRUD. We're going to build out all of our UI for CRUD. And then we're going to make it secure. And I'm going to do all that in how much time do I have, Ellie? Never mind. Don't answer that. So we're going to do that in this presentation. And that is what we call design-driven full stack. Sound good? All right. See that now? That's good. I may be a little sleepy, so you all are helping me out. Keep it going. All right. So how does design-driven full stack solve those four challenges I showed you? Overhead. We're going to have Indian configuration, zero configuration out of the box. We're going to have code generators and setup generators so that you can get going without having to think about, wait, what add-on do I need for storybook again? Wait, how do I actually mock data in storybook? But then what do I tell my back-end developers about that? So we're going to handle the overhead. Conventions? True. I want to show you and introduce an innovation at Redwood called Redwood Cells. And Redwood Cells are a way to handle data, state, and fetch. And I want to show you separation of concerns. And how we use data is the coupling, then. Once we have the data structure defined, to then move into CRUD and then integrate the front end and the back end. And lastly, I'll show you what it looks like to be secure by default, your front end, back end. And again, this is with Redwood. That's where I work. I'm a co-founder at Redwood. It's an open source project, so you know, work. But there's other ways to do this across other systems. And I just want to show you, for your stack, some ideas and concepts that you can bring to it. So bear with me for a second. An analogy. All right. So say you wanted to harness all the power in the universe to build your full stack application. You might try to seek out the Infinity Gauntlet, right? Because what else? I know. This is going to get, just bear with me. This is going to get a little strange. But right? We want to grab the Infinity Gauntlet so that we can harness the full power of the javascript ecosystem that wants to run us off the rails so that we can do our full stack application. So each one of these different steps, you can imagine, isn't that beautiful? You know, if you turn Keynote into a video game, it's a lot more fun to make slides. Each one of those is an Infinity Stone. So our mission is to go and grab the Infinity Stone so that we can get the Infinity Gauntlet before, is that the Mad Titan himself? Thanos is trying to get the Infinity Gauntlet, too, because every good story has a villain. So ours has a villain, too. And it's Thanos. We want to ship features, and remember Thanos? He wanted to do exactly the opposite. All right? So that's our quest. But how do you beat Thanos? We've all seen the movie. It did box office well. How do you beat Thanos? Yeah. I don't, I think I know who that was. Right? With a team. So okay. So here's where we're going. We need the Avengers. And what we're going to do is build a dynamic app, and we're going to assemble the Avengers. See? It's fun, right? We're going to have a great time here. All right. Because what I really want to show you is a bunch of code. But what we'll do is start with the JSX file there, and all it is is html and css. By the way, we're going to use Tailwind. And we're going to build a dynamic page to assemble the Avengers and all the team members there. Sound good? All right. Let's see how this goes. Okay. Start with a quick little video. But this is the file we'll start with. It has some data in it that we're going to use. And I just want to show you it's html and css. And then where we want to go to, this will be the dynamic web page that we're going to end up with. Okay? Here's the CRUD UI. It's got an api with it. And we're going to, if you noticed, Vision was missing. That guy. By the way, WandaVision was great. Anyway. So you can add Vision in, and now we've got a full CRUD application. Right? That's what we're going to do. Okay. Redwood JS. Real quick on Redwood. Started by a guy named Tom Preston Warner. He was a co-founder at GitHub. Built one of the largest, helped build one of the largest Rails applications in existence. Also built Jekyll. And about four years ago, conversations around what Redwood could be, take advantage of modern javascript, modern infrastructure. And now Redwood JS is a full stack, fully integrated, fully featured application that we say is for going from side project to startup as quick as possible. It includes a few of your favorite tools. Right? So you'll recognize graphql, react, right? We're at the react conference, so I had to talk about that. prisma. We're also going to use storybook and we're going to use Tailwind. Okay. Those are our tools. Infinity Stone 1. See? It's more fun already, right? Okay. Infinity Stone 1. Overhead. How quickly can we go from install to coding features? And all I wanted to show you is that I wasn't cheating. All right? Well, I could have been cheating because I could have edited the videos, but you don't need to know that. All right. So we're going to create a new Redwood app. Spins up and yeah, I know. yarn. Packages. Installing. Okay. So I sped all that up. We're going to CD into the directory. Oh, sorry. And then immediately we did not start our local dev server. This is really important. We just started storybook. All right? Full stack code base, started storybook. storybook fires up. All the add-ons are already ready for you. There are no stories yet because we haven't even started coding. accessibility is activated. storybook is ready to go. So that was our first step. Install. Run the storybook process. Quick note on the Redwood project code base. You've got yarn workspaces. So there's two main projects in there, your api and your web. We call it a proper api. If you're familiar with Rails, it's going to feel and look a lot like Rails services for your business logic. We also have functions for serverless or using fastify for deploy, graphql for the SDLs. And you'll notice Jest comes pre-config. And the web is a react application. We'll get a bit more into that. But just that's the code base. I don't have any more time to go into it now that we'll be looking at. The first thing we need to do is get our page ready. And again, we're capturing stone number one here. I want to show you what we do with boilerplate. So this is a generator to create the page. yarn generate page team. Got to start with the team page. That's done. And you'll notice storybook, the process is running. And immediately storybook, now you're seeing that page. We just have some boilerplate data that shows up. And wouldn't it be nice if in one command you could just set up Tailwind? And it worked with storybook. And so immediately you're designing inside of storybook using code that you're going to use. You'll notice there's three files that got generated. This is going really quickly, I know. And those three files were your main JSX file, your story file, and a test. So it comes with a just test out of the box. And all I'm doing here is copying and pasting. We want to work inside of our new page component. So I'm copying and pasting that starter code that I had. And now you have your page mocked up. Not mocked up. You have your page created inside of storybook. And as you're making changes to your css in this case, I just want to replay that right there. As you're making changes to your css, you'll immediately see those changes inside of storybook. Has anybody used storybook before? Yeah. Do you love it? Come on. We love it. storybook is wonderful. And if you haven't used it, it's probably because of config and integration. I really recommend you check it out. storybook is an amazing tool. All right. Next up, conventions. So how can we make the hard things simple and get Infinity Stone number two? I want to introduce you to Redwood Cells. And Redwood Cells are going to handle all the hard things about react State, graphql, Client Server, because we like to talk about graphql, but I don't know if we like graphql. And also fetch requests and endpoints. So this is the component architecture that I'm about to build out. I started with a page, so I already have the page. Next up, I'll have a team member component. And I'm going to use that predominantly for just the layout and the styling of a team member. Page component, you could basically think about it as a wrapper. Sorry, layout in the way that I'm doing it here. But there's a middle component now, and that's the Redwood Cell. And what I will use that, the work that that cell is going to do, that's a good metaphor, right? Would it be analogy or metaphor? I screw that up sometimes. But the work that the cell is going to do is that it's going to handle the data and pass the props down to the team member component. And that's it. I'll show you that code here in a second. But first off, let's get going. And of course, there's a generator for that. I want to show you generating the Redwood Cell for the team members. And immediately, you see these one story, but there's four sub-stories there. And those are handling state, empty, failure, loading, and success. Isn't that interesting? Where did we get that from? And if you look at the team member cell, we have several things going inside of this one component. We have a query. We have all of our states, loading, empty, failure, and success. We also have two other files that were generated there, the stories and the tests. But does anyone, what does this remind? This is a Redwood Cell, the structure of a Redwood Cell. Does this remind anyone of anything in react speak? It's effectively a higher-order component. Not technically. I said effectively, because we've been corrected. But you can think of it as a higher-order component. So it has the query for the graphql. We are using apollo Client. And then you have four states, all inside of one component. And again, this infinity stone, see the analogy is really working. This infinity stone is helping us with conventions and it's letting us leverage conventions so that we can make some things that are really hard and complex a lot more simple. I talked a little bit about the cell, but again, you'll notice at the top there's a query, graphql query. We'll do some more work on that. And then we have effectively four components, the loading, empty, failure, and success. All right. Next video I want to show you, there's a lot of code moving around. But remember that diagram I showed you, the architecture, the hierarchy that I want to create, page, cell, and then a team member inside of it. I'll talk you through it. But all I'm doing is moving the code down the hierarchy. So I'm kind of cascading code so that each component can do individual work. So here we go. First, we're going to start, the page component is where the code is. And I start with importing the team member cell that I've created. So that I'll go down. I don't need this data here anymore. That was never meant to be, other than just to start the process. And here, for my unordered list instead, that's where the team member cell is going to do the work. And now I'm over in the team member cell, and that unordered list that I just copied, I'm now pasting that in. Just working down the hierarchy. And I'm also, like, I know graphql query is scary, but just props. Think of props. What props do I need? And I'm putting them in my query right there. Next up is a mock. And this is a mock for storybook, right? So if you've never seen a mock file before, by the way, we're using mock service workers for this. It goes with storybook, right? So it's what storybook is using to now show the success state with mock data. Isn't that cool? And what you can't see, I just couldn't do it side by side at the time coding. But you're working in storybook, and instantaneously you're seeing your components with mock state across each of the states. Sorry, mock data across each of the states immediately. So that's pretty fun. OK, one thing I want to show you really quickly, there's a cell story file and a cell mock file. There's no magic there. It's just an import. All right? Kind of makes sense. The story file is getting its data from somewhere. All right. Next up, we have, there was one more component we needed. Do you remember? Team member. You do remember. You're actually just paying attention. That's good. Team member. And I want the cell to do the work of the data because that's query and state for me. So that's a fetch and that's state. And I want to move everything else into a new component that I'm calling my team member. And that's where I can think about my layout for the team members. So that'll be the html and css. Again, just moving code around. It's strange to not be typing this. But it's so much more efficient. And you don't get to discover what a terrible typist I am. All right. Here we are. We're now importing the team member component into the team members cell. And plural to help us remember that it's iterating. Cleaning up our props. And here inside the team member, this is the component. And now this is where all of the html that's going to be for layout is going to be. And I need to make sure I pass in member. Actually I'm glad I'm not doing this live right now. That wouldn't have gone well. You would have not been impressed. All right. So, that mock that I created for my cell, I can use that same mock file for the team member component. Because I want to see that in storybook. Right? And a cell would be passing the props down to a team member. So in this case, I can handle that at the mock level. And then immediately, and again, it's more impressive if you can see it full screen. I have all of my components displaying stories inside of storybook. Right? So, the data is being passed up at the page level. I can see the mocks for the cell and the member. It's all getting... It's just all there. It's a beautiful thing. And it's really fun and magical to use. Okay. So, we have two stones so far. Following a bit. Is that cool? Has anybody seen something like that before with storybook? I... Yeah. I didn't think... We wanted this to be... This was a vision we had for use of storybook. So, I know it's a vision that storybook... We love working with the storybook team. That they had as well. All right. Two stones down. We have one stone to go here. Infinity stone three. Separation of concurrence. How can we couple the front and back end development using mocked data in state? And how we're gonna do that is we're gonna take that query from the team member cell. We have our data structure already. And now, in our data model... In our data schema, we're gonna create a model using that same structure. We're using prisma. Don't worry much about the attributes. Right? But you've got the same data model. You've got the same image URL. And let me show you how quickly we can move once we start up the Redwood dev server. So now we're in local dev. Right? We're not working in storybook anymore, because we're gonna work across. And this is that coupling piece. Right? So, typically, your front end, or you, would work up everything you need for the front end UI. And then now you've gotta figure out what that's gonna look like in the back end. Or if you're a back end developer, you're gonna start in the back end. And you're gonna think through what tables and models you might need. And then you're gonna try to work forward in the front end. And it's just like when you're building a tunnel under a mountain. Like if you miss, you miss by a mile. Right? So trying to bring those two things together, you really wanna have alignment. And that's what we're using cells and mock data and mock state to do. What happened there is, with the prisma migrate command, we now have a local SQLite database with the same schema and table that's needed for the front end code. This will be quick. This is what I really wanted to talk to you about. I wanna talk about performance. There's a lot of wonderful focus right now on tool performance. Right? And rightfully so. Web performance, web performance. And that's important. We need to do that. But Thanos, I'm talking about Thanos to a group of adults. Thanos, how do you beat Thanos again? With a team. The Avengers. Right? So if you want to beat Thanos, it's gonna do it. You need a team. I love this. This was so great. It's a little bit ridiculous. Performant teams build performant products. There's a massive body of research talking about this. Right? We can focus on technology and we need to. But we also need to affect the whole. And we need to optimize for the, we need to optimize the process for the people in order to affect the whole. All right? So let me show you what that looks like in this scenario. When you optimize a workflow for the people that will be working on the application, what that might look like. So in one command, we're gonna run scaffold for the UI and this will create everything we need in the api. All of our endpoints based on that data model that we have. And this will create everything we need in the UI so that we can run CRUD. And at this point, we now have a full stack application. There was a lot of files that were generated, but again, it's the SDL files, it's the service files where our logic takes place. In the front end, it's the different cells that are doing the data work for us so that we can do CRUD. And really quickly, this is the actual admin UI. Quick CRUD demo. You'll see that there's nothing on the team page. We don't have any team members created yet. We're now inside of a dynamic application. Falcon, apparently, is who I chose to start with. And boom, we have Falcon. If we go back, team members, edit, we can edit that. That's pretty cool, right? All right. We just went from front end to back end in one flow. Oh, by the way, empty state. It's there for you. And I kind of, yeah, a little bit. But if I made it too simple, then your mind might not be blown. But it should be blown just a little bit. Just a little bit. All right. There's one last infinity stone. And I'm going to make this really quick. What was the last infinity stone that we needed? I skipped that real fast. Right? security. So how can we do end-to-end security? Which I promise, that would be our bonus that we get to. Oh, man. Spoiler. And I'll show this really quickly. Update first. Did we do it? Main display. Won't work if my displays don't work. Am I up? No. It's my thing. There we go. I know. You know, it's a bummer when the grand finale doesn't go the way you want it to. But that's quite all right. I'm going to skip that part and go back to my slides. Redwood has authentication by default. And in one command, and I'll just talk you through this really quickly. When you set up Redwood authentication, those SDL files that I showed you, it has directives on them. And they're all secure by default. So that public page that you saw for the team members, all of that would no longer be accessible, although the page itself would be. But your end point would be secure by default. And then with one change of a directive on an SDL file, you would change it from authenticated to skip off. You would have a public api. And then inside of our routes file, if you add private to any route, that route now becomes hidden, you can redirect them to the homepage. And again, why did we do those kind of things with Redwood? We did those kind of things because we wanted to build a workflow for people. All right. I have one final slide. Can we get it back up by a chance? I wanted this was, I was excited about this one too. Is it going to come? No. All right. I had Tony Stark at the end. You've got to end your presentation with Tony Stark if you're going to talk about Thanos, right? All right. The slides aren't coming. Okay. No, we got it? I mean, come on. Right? All right. Thank you. You were very gracious. That is not the way I wanted to end. If you are interested in Redwood, the best way to learn Redwood is through the Redwood tutorial. And the best way to be successful with the tutorial is to join our community. We have a wonderful community of contributors, over 400, and we love our contributors. We have a helpful dynamic on our forums and our Discord. And lastly, I promise I'll get this demo up online and you can take a look at it there. Follow me on Twitter if you want to find out more. Thank you. You've been very generous. Thank you, David. Reminder, David will... Nobody move. We'll be at the speaker's booth outside where maybe he'll do the demo for you. That's your time, not my time. All right. David, what about server-side rendering with Redwood and typescript? Yeah. What about server-side rendering and typescript? I meant submission and I omitted. Reminder to leave quietly out of respect so we can all hear. Thank you. No, that's great. Yeah, fully typed. I meant to mention that when we started the project, but you can pass typescript. I just started with a javascript project because it makes the demos a little bit easier when you're working through code. Server-side rendering means a lot of things in today with marketing speak. We don't do server-side rendering right now. We do a pre-render, which is basically a static site generation. We have dynamic pre-rendering coming up soon. And you will... Don't owe me to this, but you'll see a server-side rendering before the end of the year. Is that a promise or a threat? It'll be great. All right. Can Redwood generate typescript contracts based on the mocked api? Probably. Orda? It's not really a problem you want because you would need some forms of RLs. Yeah. So, see, that's Orda, typescript guy. Don't do it, folks. You heard it. So, what Orda said, and this is helpful, that's probably the right question, but in the context of Redwood, that's not something you would need. Cool. Does it support other frameworks besides react? That's a fantastic question. Redwood, because of that workspaces that I mentioned, you can run Redwood as a standalone api, and why would we use graphql if we didn't intend it to be multi-client? Because today, what products are not multi-client, right? I mean, there's a lot of great sites that stay there, but we intend it to be multi-client from the start. So, yes, there's a lot of great startups right now using Redwood's api with Next, running multi-client across Electron, CLI, using different websites that they're deploying. So, yes, is the answer. And is it free or how is it monetized? Yeah. Redwood's an open source project. It's sponsored, but it's open source. Yeah, if I didn't hit that grade at the beginning, that's my bad. Open source and will be open source. Before I let you all go, you had something you wanted to share, I believe. Yeah, I did. Thank you, Ellie, for the time. So, the last few years have been a little crazy for everybody, and what I wanted to leave you with is how important community and team is in my life. There's a really good friend here that I've never met before. And sorry, it's been a long week. Toby, I just wanted to say hi to you because none of this was done by me alone. It was done with a wonderful community of people, and it's a shame that I'm the only person up here telling you about it. So, I wanted to say, Toby, come up here. I just wanted to meet you for the first time. Hey, man. That's a great plug. I flubbed it at the end. Nice to meet you. It's really good to meet you. That was it. Thanks again to David for joining us and to Toby.
32 min
17 Jun, 2022

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