I'm Dan Abramoff, and you're listening to The Change Log. Welcome back, everyone. This is The Change Log, and I'm your host, Adam Stikowiak. This is episode 187, and on today's show, the topic at hand is Redux.
We're talking with Dan Abramoff, the mastermind behind Redux. Not only did we dive deep into Dan's past and where he came from to become a software developer, but we also dove deep into JavaScript, Redux, React, talked a little bit about Elm and ClosureScript and functional programming in JavaScript as a whole. Dan shared tons of advice and tons of great insight into the inner workings of Redux. We had four awesome sponsors, CodeShip, TopTile, Braintree, and also Linode.
Our first sponsor is CodeShip. In the new year, January 12th, they have a free webinar you have to check out. CodeShip's engineer, Laura Frank, is going to give an overview of Docker's ecosystem, Docker Compose, Docker Machine. She'll talk about containers, and you'll learn about Docker images, why they're so powerful, and how you can start running services in containers.
And when it comes to web apps and Docker, you'll understand how to develop your web apps using Docker, working with images, registries, and running services in containers. The link to this webinar is rather long, so I'm going to put it in the show notes, but you can also go to resources.coacheship.com and look for webinars in that list, and see the link to the same webinar I'm talking about, or head to the show notes and click the link there. Again, totally free, January 12th, 2016, from noon Eastern Standard Time to 1 p.m. Eastern Standard Time.
That's one hour, and now on to the show. Everyone, we're back. We have Dan Abramoff here, maker of Redux, and so much more, but Jared, this show got started by an issue. Can you tell us about the issue that got pointed up to get you on the show?
No, I don't remember the issue. Can you tell it? No. Put it on the slot, bro.
Well, actually, it was, how do you say his name? Let's see. His name is Kevin McGee, and he posted an issue, let's see, it was about November 10th, so not too long ago, and he said, consider interviewing Dan Abramoff, product lead and mastermind. Dan, you got a mastermind, bro, of Redux, a predictable state container for Redux.
So we kind of knew about Redux already, but that's how this got started. Dan, you chatted back in, and we said, hey, get in touch with us. We'll start communicating around dates, and so here we are. So welcome to the show, Dan.
Thank you. And one of the ways we love to open up the show lately, it's been a growing trend to kind of dive a little bit deeper into who our guests are. So aside from being the mastermind, the product lead behind Redux, who is Dan? Who are you?
How do you introduce yourself? Well, I'm a 23-year-old guy from Russia. I have a wife and a cat. I just moved to London.
Before that, I lived in St. Petersburg pretty much my whole life. I lived a little bit in Moscow, but mostly in St. Petersburg.
And I don't know, I guess that's it. I haven't really done much to have something to tell about myself in this way. What brought you to London? I'm actually starting, I've already started working here.
I work at Facebook now. So I'm in boot camp. It's not, I'm not doing actual work. And right now, I'm just helping out different teams and kind of learning about the Facebook internal structure, about different teams that are there, what kind of tools they use, the infrastructure, the people, and stuff like that.
And I'll go to MPK, which is, okay, I started actually talking with these crazy abbreviations that they use. So I'm going to Menlo Park in January for two weeks as part of my boot camp. And later, I graduate from the boot camp, and I'll be working on React Native team in London. Interesting.
So what does the boot camp involve? It involves, you go to classes to, I assume, learn some things, some internal tools and languages that they use, and just kind of get to know what different people on Facebook are working on because there are so many teams, there are so many projects. But I'm actually pre-allocated to React Native, so most of the people in boot camp, they go through boot camp to later choose a team. But I'm just going through boot camp to, I don't know, to do something different before working on React Native.
And it's also a great way to kind of specialize and to get to know a lot of people because you're going to need people later when you're working the projects. So Facebook is very social inside. I did not actually anticipate it to be so, but Facebook is very people-oriented, and people use Facebook to communicate inside Facebook, and they ping each other all the time. And it's best to know as many people as you can to get job efficiently.
That's interesting. Is there any particular challenges that you're facing now as you said? It sounded like you were not so much not social, but it was a surprise to you. Is there any concerns there?
No, not really. I think the main concern for me right now is to figure out my kind of life kind of issues. Like settling in, I need to find an apartment to rent. I'm currently living in a temporary apartment in London, but it's going to expire in a couple of months.
So I need to do that. I need to get the insurance. I need to get some kind of numbers so I can go to a hospital or whatever. Just a lot of life stuff that I have to do with.
And I never moved to another country before. And when I was in Russia, my mother used to do that for me. So the paperwork is kind of surprising. Yeah.
You mentioned you have a wife and a cat. So I imagine they're with you or they're on their way soon. What's the situation there? Yeah, they're with me.
Actually, UK has very strict restrictions with regards to moving paths. So we had to hire a company that would take the path with a special agent and through a special airline. And it costs a lot of money. But yeah, we have a cat here now.
You must love that cat. Yeah. Let's go back a bit. And you mentioned you're 23 years old.
So you're not old. You're not young. So just to kind of give some perspective here. I'm 36.
I'm about to be 37. You're this going to be March. Jared, you're 33, right? Right.
So you're 23. You're basically 10 years and a few more younger than the two others on the call with you. So not that matters in terms of your age, but just kind of dive back a bit in your history. Can you talk a bit about what you've been doing the last couple of years?
What got you into programming? Where have your interests been lying in the past couple of years? I started programming when I was 12 years old, I think. And it actually started.
It wasn't on purpose. We did have programming in high school, but I didn't like it because it was Pascal mostly. And I didn't understand it. I didn't understand why we need to sort a race and that kind of stuff.
So I wasn't interested. And I actually got into programming when doing different school assignments. I loved PowerPoint. So PowerPoint was my favorite software when I was a kid.
Because I like to create the facts and animations and to schedule animations one after another and all of this kind of stuff. And I think once I found a menu called Service Micros. So Micros, if you don't remember, in Microsoft Office, you can record some actions and then press play and they are automatically repeated. Right.
And you can actually edit that code. It generates Visual Basic code and you can edit it and the micros do something different. And so I was hooked back then and I bought some books and my grandma used to go with me to the bookshop and every few weeks she would buy me a new book as a treat. So I started with Visual Basic, but later I transitioned to the NetSharp and eventually I got a job when I was 18.
So this is how I started programming. What was that? It was a job at an outsourcing company in Russia. So it's a joint Russian-American company called DataArt.
They do projects for different enterprises like financial companies, that kind of thing. And it was fun in the beginning because I just, I got a real job finally, right? Right. It was fun and I got to get paid for what I like to do.
So I learned a lot there. But later it was just too much enterprise stuff. Like, I don't know if you know Microsoft SharePoint. Yes.
That's the worst. Unfortunately, right there. Yeah, 2007, it was back then. And so everybody kept using very old software, very complicated software, piles of complicated software, one on top of the other.
And I was just really tired of that. And on the other hand, my skills were mostly in native development, meaning Windows native development. And I didn't know how to create mobile apps or I didn't know how to create websites. And I felt a little bit scared that maybe I just can't do, maybe I cannot learn it.
Maybe it's too complex for me. So I stayed away from it for a while. But after that, I quit my job. And I was lucky enough that my mother could support me for like six months and pay my rent while I learned to have technologies.
So I went to an internship, which is not exactly an internship. It's just, it was a volunteer club of people helping one Russian entrepreneur build his websites and projects. So the conditions were that we don't get any money. But on the other hand, we just get to learn different things for free.
And he doesn't care that we're not actually good because he just wants things done and we want to learn. So we had this lab and I learned Git and CSS and jQuery and Python Tango just by helping him do these projects. And there were like 10 people there, but we had a lot of fun. And later, after that, I got some idea about JavaScript, although I wasn't really an expert.
I didn't know what is this and, you know, these kinds of JavaScript patches. But anyway, I was looking for a job and I got a job at a startup. So I was working at a Russian startup, which pretended not to be Russian. It is called StempC.
It's like a medium, but for images and multimedia content, videos, audios. And back then, we were focused on creating an iPad application that would allow you to create and consume this kind of multimedia content, like small magazines that you can create right in the application. And I didn't have any iOS experience. But again, I was lucky to be somewhere where I could learn on the go.
And this probably helped. I think this is something that helped the most in my career, that I was lucky to find several places where I'm always able to learn on the go and not come with some lab portfolio or whatever. So I learned iOS while working on an iOS application. And both me and one of the other developers, we knew C Sharp.
We didn't know Objective-C and Swift did not exist back then. So we just, we wrote the iPad app in C Sharp and we used Xamarin back then. And it was a hybrid app because the editor, the part where you actually create the post, it needed to be based on the web technologies because we wanted to bring it to the web later. So it was a hybrid app.
We had to learn a lot about the breaches, that kind of stuff. So it was a lot of fun to build it. And when we released it, it was featured by Apple on the first day. And it stayed pretty, like it stayed featured and it wasn't top hunted for a while, for a couple of weeks.
But people didn't really use it in the ways that we hoped they would use it. And after the initial interest, it just fell like nobody remembered it. And so we stopped working on it and we started working on the web version instead because we figured that the people who have professionally looking beautiful content, they don't have this content on their iPads. And what they usually have on iPads are low-quality photos, which are not exactly the content people on it.
So we then created the web version and we had no idea how to build a web application. So we learned a little bit of Backbone and it kind of worked for some time until the application got dynamic. And we had these pop-ups and model windows, tabs inside them, and a complicated drag and drop post editor. And it was very hard to create a really dynamic, really interactive UI with Backbone.
So this is when we started looking at React and kind of played a little bit with it. And gradually we rewrote our app in React and Flux. And this is basically how I got involved in React community because it was still very young. And I mean, when we added React to Stemsy, I think the React router didn't exist.
So this was the time before React router. And when it finally came out, I was like, hey, it's time to switch from Backbone completely. So we switched to React and when we had a redesign, we had a change to switch to Flux. But later, and I mean, it was a great experience.
I learned a lot there. But I read from Stemsy in April 2015 because they ran out of funding. The numbers weren't good. People are using it.
There are many users, like, I don't know, maybe 40,000 or something. They posted their content, but it wasn't skyrocketing or something. It was just linear growth. And a couple of weeks ago, our founder died.
I've been through a situation like that where I'm working somewhere and your founder passes away, and it's a big shock. It's such an unusual thing to go through because not only do you feel lost personally, but you also feel lost corporately. And it's so rough to kind of share that with your comrades, you know? Yeah, yeah.
So that was by the time I wasn't working there anymore. I was doing open source stuff. And I kind of lived by doing some contacts, doing some contact work. And it worked pretty well, I would say.
But it's hard to switch between open source and contact work for me because I just hate switching contacts. It's hard for me to work on many things at once. So I was looking for a full-time job, and I spoke to Facebook before, and they were like, hey, you can come to U.S., but no, you can't because you can get a visa to U.S. Because I don't have – I dropped out of the college.
I don't have the degree, and I don't have – What, you dropped out? Yes, I did. So I can get a visa to U.S., and they said, hey, maybe you can get a visa to London later, but we don't have a team there yet, so let's keep in touch. And later in the conference, I was interviewed by the team.
It wasn't planned. I basically skipped to the second day of the conference because I was on the interviews. But this is how I got hired, and the past six months were just about preparing all the documents and passing English exam and all the kind of things you need to do to go to UK. And I'm here.
There you go. Well, congrats on that. I mean, it sounds like your trip to where you are now from where you came from is pretty interesting. I mean, just to kind of repaint it for the listeners, you came from a PowerPoint background.
I don't know if that's exactly accurate, but that was your first love, so to speak. And then you got into C Sharp because of just your natural regression and jQuery and backbone, and now we're at now. And you said you started your first job in anything at 18, now you're 23. So in five years, you've gone from someone who was just kind of fluent and maybe just getting started with native, as you mentioned, with Windows, and now look at you.
You're at boot camp at Facebook, which is awesome. Yeah, it's cool. Yeah, thanks to your grandma and your mom, too, for helping out your grandma bought you some books, which was, you know, who doesn't love their grandmas, right? Yeah.
And their mothers just to step in and support them whenever the time needs it. That's such an awesome thing. So I guess now that you're, in quotes, famous, you can give back. Yeah, exactly.
At least I hope to do that. I mean, I'm not doing a lot, but I open source myself. So maybe one more topic before we go into the break here. You mentioned that you weren't really...
piece together something I heard elsewhere and then something I heard here, which was React is what inspired you to contribute to open source. You hadn't really been doing anything around open source and you mentioned how it was hard to do a day job and open source together. Can you talk a bit about your first steps into open source and what that looked like for you as someone who came from a world where maybe you weren't contributing or doing much with it? Yeah, I think it's really about React being a young ecosystem.
So if you're an open source, if you're someone who considers maybe a contribution to open source, but you don't know where to start, you probably shouldn't create another HTTP library or something like that because a lot of those exist. But what you probably should do is find the ecosystem that is young but promising. And this is kind of how I got lucky with React because I needed to build some things for my job because they did not exist at the time and they were necessary. And React provided enough value so that we didn't want to give it up, but then we had to contribute to the ecosystem.
So this is how it started for me because my job demanded actually doing something around React that did not exist at the time. And on the other hand, I had this personal project called React Folder and I was really inspired by the idea of putting two and two together. There was React with declarative engine model and there was Webpack with its hot model replacement and I wanted to bring them together because it just made sense to me. Like, I want this kind of workflow that I saw in Brad Fitzgerald videos.
Although one of Brad Fitzgerald hates people like me probably because we only take the easy parts from his talks and not the really important and complex parts. But anyway, I was inspired by him and I wanted to do something of that sort and share it. And it was my personal project. I remember my wife was like, what the hell are you doing?
And it was 5am and I was in the bed and I made this ugly hack, like I changed React internal code to just get it to work somehow so I can record a fancy screencast demo in it. Wow. So I had a fancy demo that only worked for like a single file correctly and it was full of hacks, but it looked like it actually works. And I recorded this video and Christopher, Christopher, I'm not sure.
Yeah, he shared it. Instant fame, right? Yes. It was like 50 or 70 tweets and it was a lot for me when I had maybe 30 followers.
So this is how it started and I really felt that people want this. People want this to exist and I also want to exist. So when I went for a holiday, I swam a little. In the same way after that I would just go and vote for several hours to get this into shape where it actually works for more than one person.
And the feedback was amazing and I think this is what made me quote famous. It's an interesting story there too. It reminds me of the phrase and some of you have heard this before, Dan, by any means necessary. You know, you have to get somewhere.
And I can remember a talk I heard back at Lone Star Ruby Conference, the very first one, this guy was talking about just shelling out and how it was such a bad thing to do from Ruby code inside of a Rails app or Ruby app and kind of breaking what is considered the rules, so to speak. And it sounds like you're not down by rules. Yeah, I mean... To a degree, obviously, but if you have to get somewhere, you're going to get there.
Yeah. And it's also, I think, it's very important that even if you have a day job, if it's possible, you need to try to have a broad view of what's happening in ecosystem around you and different ecosystems around you. Because a lot of people get locked into a certain ecosystem like React ecosystem or Ember on Endler and they love the framework or they hate the framework, whatever, but they just don't talk to people outside their bubble and it's a big problem. But most really interesting projects, they're on the borders of the ecosystem.
Most interesting projects happen when one ecosystem collides with another ecosystem or when a person takes a lesson from one ecosystem and brings that to another ecosystem. So I think this is really important and this is something I'm trying to do in ways that I can just point people to some nice things that exist elsewhere and maybe people creating those things don't really care that much for us, but we need to get there are good solutions and find ways to figure out if these solutions will help us do. So there needs to be a healthy exchange of ideas even between competing frameworks. Yeah, I'm glad you said that because that's definitely a good point to bring up especially when you talk about your entrance into open source and react and how you look at the ecosystem and how it can bring value back but also not sticking inside that bubble.
A very important aspect to think about. That's a good spot to take a break. So we're going to take a quick break. We come back, we're going to dive deeper into Redux, React, and this journey you've been on.
So let's take that break. We'll be right back. Our friends at TopPal launched a scholarship program for female developers to support aspiring female computer scientists, developers, and software engineers to help achieve their goal through financial support and also mentorship. Each scholarship winner will receive a $5,000 scholarship that can be used towards education and professional development goals.
You can spend this money on anything you want from coding bootcamps to online programming courses, textbooks, you name it. You also get one-on-one mentoring, an entire year of weekly one-on-one mentoring with a TopPal senior developer and this person is going to help you with topics like project guidance, choosing an academic or career path, and also preparing for interviews. Head to top.com slash scholarship to learn more and also to apply. Alright, we're back with Dan Aramoff.
I'm going to say it again, the mastermind behind Redux, as Kevin McGee said. And Dan, you know, we're just in the break, we're lamenting about your story and what an inspiration it is to have that outlook. Even at a young age, just to be able to have such wisdom to look at the, you know, JavaScript, React ecosystem and say, how can I add value back in and then share that back with this, the audience here listening about how you came into open source and how you get back. It's really, really interesting, so thank you for sharing that with us.
Now it's time to dive a little bit deeper. Obviously, a lot of people come to this podcast thinking, I want to hear about the deepest parts of Redux when it comes to what Dan has to say about it. So, how do we begin this conversation? We just kind of dive in and talk about what Redux is or is there a better place to begin to start unraveling this story?
It depends on whether you want to come from technology or from history perspective, because usually when I explain Redux, I explain it from where it came from and what was I trying to solve when I started working on it. Let's begin with that. That's good. Yeah, okay.
So, I don't know if you know about Flux a lot, but Flux is like a Facebook solution to more to the data layer in React apps, and it's not the dominant solution anymore. Facebook is actually moving to Relay, which is a different framework they released this year. So, Flux is more, it's often described as a pattern and not a framework, but after Facebook released Flux, there were a lot of different takes on Flux architecture, and some of these takes actually lost some benefits of Flux, either intentionally or unintentionally, and they also added some value, like better support for server rendering, for example. But anyway, by the time, I started working on Redux in June 2015, and by that time, there was a lot of frameworks, a lot of Flux frameworks.
I think the most popular ones were Alt, Flamux, and Fluxable. So, these were the most popular ones. And of course, the vanilla Facebook Flux implementation, which I think all of them actually use internally. So, I did not want to create a Flux framework.
I tried to not do that for the longest time I could. I resisted it a lot. And I kind of liked Flamux, and I used it in some of my projects. But I had this conference talk that I needed to give, because in February, I signed up to give a talk at React Euro conference.
And the title of my talk was Posture Loading with Time Travel. So, the way I came up with that is that I wanted to talk about React Postloader and about this kind of workflow with Posture Loading and when you just edit a component and see the changes reflected in your browser without refreshing the page, without losing the current state. It's been a huge productivity boost for my workflow, and I wanted to share it. But I thought that people have already seen that.
And, I mean, there was a talk at React conference, the first React conference, that mentioned Posture Loading. Although we did not demo it, I still felt that I don't want to repeat that exactly. So, I was looking for more inspiration in Bradford Taurus videos, and he had this time travel kind of thing where you play a game, and then you can rewind to any moment, and you can change the code, and you can actually see how it's going to happen in the future, given the same actions. Like, in the game, you walk to the right and jump, and if you change the arguments through the jump function, you're going to see how that jump that has already happened is going to change life as you edit the arguments.
So, this was something that really excited me, and I wanted to incorporate that in my talk, but I didn't know how. And I made a very quick group of concepts of time travel with overwriting react set state method, the method on the component where you set the state. I did some kind of ugly hack where I placed a slider next to every component, and I overrided a set state method to record every previous state, and the slider would move between those states. So, of course, this is not useful in any real application because you have, I don't know, hundreds of components, and it's not useful to have a slider in front of every component.
But it kind of proved that this is possible. And I made a bet. I wanted to go to the conference. I would not have been able to afford the ticket if I went as a regular person, so I needed to become a speaker.
So, I submitted a proposal for my talk called How to Loading with Time Travel without actually knowing how to implement time travel. Nice. That's awesome. Yeah, I had a few months to actually do that, but I was busy with a different project called React D&D, a driving job library that I started writing at my job, but I wanted to rewrite it for 1.0, and I was busy with that.
And then it was June, and I only had one month until the conference, and I needed to figure out how to make a beautiful time travel demo somehow. And by the time, I had the feeling that how to Loading is a little bit useless in flux applications because most of the time you work on the store, on the logic of data mutations, and not on the components. I mostly had my designer friend work on the components correctly, but I was working on the mutation logic. And I could not how to Loading because the street is local, it's in local variables.
And if you execute this module, this kind of part of the script again, you're going to have the initial values for these variables. So you lose the state every time. And you also lose, the components are still subscribed to the old version of the store you're working on. So if you re-execute that module, if Webpack for model replacement rewires all the required statements to point to this new version, it's still not going to work because components are already subscribed to the old store that is not the one you're working on.
So this was a big problem for me. And I wanted to find a way to add FortuLaur into flux. And on the other hand, I wanted to find a way to add time travel to flux because I needed to demo time travel. So I tried to do this with Flummox, but I couldn't find a way to make it work with Facebook's dispatcher and Facebook's flux system.
So I tried to find another way. And I think sometime during this period, I read a document called Elm Architecture. And Elm is a programming language. It compiles to JavaScript, but it's different.
It's a functional programming language created by Evan Zablitsky. And actually, I didn't understand the document fully. And this is like a confusing moment because I know later Evan was a little bit angry about me not mentioning him in the talk. And he had every right to do that because indeed products architecture, a big part of it, is pretty much a repo of Elm architecture.
But in my defense, I would just say that I think I didn't fully understand Elm architecture. And it was just somewhere in my subconscious. And in fact, the first version of Redux, it was not like Elm. It was more like flux.
And it was Andrew Clark, actually the Flummox guy, who helped me figure out how to make it much better. I think he helped figure out the fundamental reducer composition pattern that we use in Redux for building scalable apps. And Andrew had a ton of influence in Redux. And this is another moment where I think it's not very common for a maintainer of a popular open source library like Flummox, which was very popular at the time, to just give up on it and say, hey, I'm going to join this competition project because I think that is better.
And I'm just going to tell my users that I'm making the final release. And now I'm going to work on that instead. So Andrew had a very large influence on Redux. He helped figure out how to reduce the composition, which made it more like Elm.
And he also designed the extension system for Redux, the middleware and store enhancers. It was his ideas. So initially Redux had a single author in NPM package, Jason, but I changed it to be as both because that's the truth. It's a nice example of what you were saying earlier about keeping your eyes open on these other ecosystems.
Here you are reading the Elm architecture. Well, you're not doing Elm directly, but you're taking ideas from there and bringing them over to the areas that you're trying to solve problems. So Redux comes out of this desire to have an awesome conference talk, basically. That's what I noticed, which is a new thing to me.
It's like upcoming conference talk, demo-driven development, basically. Yeah, conference-driven development. Yeah, there you go. It turns out it seems like it's generally useful for lots of things, not just wowing your friends at conferences.
You say it's inspired by Flux. Is the big differentiation between Redux and Flux, is this idea of a single store for your entire application state, whereas Flux has multiple stores? Is that the big differentiator? Or am I missing something?
Yes, that's the big difference. And I think it's in how we choose to separate the concerns. So in Flux, you separate the concerns with having different stores, but you also separate the event subscription because you have components subscribing to different stores, and you also separate the state because you have different stores managing different parts of the state. But in Redux, we actually keep the state and the subscription in a single place in the store, and to separate concerns, we create many reducers, which are just functions that tell how state is transformed.
And this is kind of similar to how React has one root component, but it's composed out of many components. So in Redux, you have one root reducer that tells how state is updated, but you can call functions from other functions, and you can have as many reducers as you want, and it's like a reducer tree managing your application state. So you manage the time travel by basically running those same reducers in the opposite order? Remember, the way it works is that there's a big difference that when people say time travel, they sometimes mean different things.
And in Flux, Time Flux frameworks actually support time travel, but not the way React supports it. So... What's more common is that you can travel between existing history and you can make your components render any point in time that previously existed. But this is not exactly what Redux does.
So what Redux lets you do is that you can go back to some previous state, like a couple of actions ago, then you can change the code of your reducers, and it's going to re-execute all actions after and before that so that you're traveling to a parallel world where the code was different and so all the states were actually different because you changed the code that computes them. And of course, it's not efficient to do that in production. This is only meant for development. But basically, we keep all the actions, and if the code changes, we re-evaluate them from the beginning.
Yeah, so the practical benefits of that seem, like you said, they're the best in development where you can try many code paths or many different reducers or functions and see what the differences are like. What other advantages fall out of this idea of being able to move forward and backward? Oh, it's not so much about moving forward and backward. I mean, it's very cool for impressing your friends and for debugging really weird state and mutation issues.
Like when you have some control that updates really fast and you have HX response coming in, and then you're not sure that in the middle state something broke, but you're not sure why. So you can step back and see, oh, I'm in this state. I'm going to edit the component. The component of render selected correctly, it's what results, and now you can go back to the current state.
And so you can see everything that is happening. And if, in some cases, the state was not updated correctly, you can see where exactly, because you have the whole history of every action and the state after that, and you can inspect it in a tree view. So you can see where exactly it went wrong. You can fix the code and make sure that now it is correct.
And if you make a mistake, if you make a reduce of crash in development, it's just going to say that there has been an error, like fix the code, and the error occurred after this action. So you fix the code and then it re-evaluates again. Hopefully you fix the error and it renders something different. So it's a whole, another different, more efficient developer workflow.
But this is just one of the benefits that slides out of this module with single state. So other benefits are that it's easy to replay user actions. So, for example, you can log every action that happens in case you're debugging some kind of issue. You can log every action, you can serialize them, and then you can replay them on your computer and reproduce the bug.
And this is possible with Flux, too. But with Flux, you need to be very careful to implement it in a very specific way. And in fact, some teams at Facebook don't implement it that way. But you need to be very careful to be predictable.
And I think Redux makes it easier by imposing more constraints. It also seems like it's a more simple mental model. The one thing that I noticed with Flux and started looking at it is, man, there's a lot of moving parts. There's a lot of things to think about.
And there's a lot of diagrams to digest here before I start building my application. And then it was choose your framework. Which, Adam, reminds me of one of my favorite parts in our recent Season 2 of BeyondCode was Jonathan Burkle's quote, where he said, we do not need another Flux framework. We have about 50,000 Flux frameworks.
No more. Yeah, no more, he says. That was kind of a shared opinion amongst JavaScript developers at that time. That was March of last year.
Or March of this year. At which time, yeah, we were being over one with a new Flux implementation. Felt like daily. But there's lots of complexity there.
It seems like Redux is just a simplified model. And having a single state object, similar to the way you think about your React components, right? Where you have a single root component, and it's just a tree of components now on your state. You just have one object, and that object is just a tree of other objects, and what have you.
Is that the biggest win in your opinion? I think another really big win is that the testing is so much easier. This comes up every time I ask people, like, what do you like about Redux? People say testing.
Because it's not convenient to test the Flux stores, because they kind of depend on the dispatcher. And, you know, it's like banana-gorilla problem, where you want the banana, but you get the gorilla in the whole world. I've heard of it before. Banana-gorilla?
Is that what it's called? Yeah. And this is a typical object-oriented problem. But in Redux, the reducer is not just your function, so you can just input a single reducer that manages some part of your tree.
And if you want to test it, you don't need any kind of, like, you don't need to set everything up to set up some mocks, or if you read the Facebook dispatcher kind of guide to test, and there's some stuff you need to do to make it work. But in Redux, you just call the function with some admins, and you make assertions on its return value. And this is testing Redux. And, of course, not all parts are tested as easy as this.
There are some parts that are harder to test, but most of your application logic lives in the reducers. And this is the part that is easiest to break, because it's dealing with a lot of speed. And this part is very easy to test in Redux. So this is another big win.
I think I've started seeing a lot more testing in open-source examples than I saw in Flux using application examples. Very good. Well, I think this is just the first principle of three core principles that you state about Redux. We're going to take a quick break.
And on the other side, we're going to dive more into the implementation and the principles of Redux, so our listeners can get a taste of not just the history and the why it exists, but even more of the how. So let's pause here, and on the other side, we'll talk about those three principles. We'll be right back. Braintree is all about making developer lives simpler with code for easy online payments.
If you're searching for a simple payment solution, check out Braintree. For mobile app developers out there, the Braintree V.0 SDK makes it easy to offer multiple payment types. Start accepting PayPal, Apple Pay, Bitcoin, Venmo, traditional credit cards, and whatever's next, all with a single integration. And it was simple, secure payments that you can integrate in minutes, and developers have got you.
Don't worry about taking days to integrate your payments, but Braintree is done in minutes. And if you don't have time, you have them a call and they'll handle the integration for you and walk you through it. Braintree supports Android, iOS, and JavaScript clients. They have SDKs in several languages, .NET, Node.js, Java, Perl, PHP, Python, and Ruby, and their documentation is comprehensive and it's easy to follow.
To learn more and for your first $50,000 in transactions, be free. Go to BraintreePayments.com slash changelog. All right, we are back. And Dan, I want to go through, have you go through some of these principles of Redux.
It's a small library, as you said, but it has a very intentional structure and opinions. And so I think the principles are very important. One we talked about, that's the single source of truth, which is that the whole state of the application is in a single object tree within a single store. That also is a big differentiator from other Flux implementations where you have multiple state stores.
You also have two other principles. State is read-only is your second principle. And the third one is changes are made with pure functions. Can you walk us through state is read-only and what that means?
Yeah, sure. So this is what I took from Flux, and I think Flux really cleared my mind about how to write predictable code. Because before Flux, I was using Backbone, and I had these modules that were calling methods on other modules. And if you can imagine a user object, and a user can follow another user, and when the user begins this operation, you need to make it optimistically.
You want to update the UI right away. So the method needs to change the count of followers and followees, and it needs to change the boolean fields on both objects, and then it needs to make the request. And if the request fails, it needs to roll them back. But if there is a concurrent request, you need to be careful to roll it back to correct value and so on.
So it's very crazy with traditional MVC. And what Flux gave us is that Flux said, hey, you don't have setters. You don't actually, you don't change your objects. You don't put methods on them that change them.
And instead, you've got this source of truth, which is multiple source and flux, or single source in Redux. And you've got these actions, which are objects, plain JavaScript objects, describing what you want to happen. Like user followed users, user followed user began. And you have two IDs.
So this is an object describing the change. And after that, when the request comes through, you dispatch another action that says that user followed user success or failure with the IDs of these users. And so every change in the application, every mutation that you want to make to the street, you express it as a plain object describing what happened, like a newspaper. So this is what Flux suggested, and this is also what I kept in Redux.
So you want to actually react to the actions, of course. And in Flux, you register a callback in the store, so it can change its internal state. But in Redux, you don't do that. In Redux, you just write a function that takes the current state, the action, and it returns the next state of your application.
And this is a function called the reducer. It's a pure function, so it cannot re-trade the previous state. What it needs to do is to create a copy of the state that is updated according to this action. So the state is read-only, and you have these action objects.
And the way that you change things is with pure functions, that's your third principle, which you call reducers. Can you explain reducers in more detail? Yeah, so the name reducer comes from array-reduce method that is on every array. It's pretty standard in most functional languages.
It's also called array-reduce method. It accepts a callback. So this callback is what we call a reducer because it's an argument to reduce. But what is reduce?
Array-reduce is an operation that lets you create a single value out of multiple values. So you can use array-reduce to calculate a sum of integers, for example, or to reverse at least, or to pretty much do any kind of accumulation over some kind of stream of values. And in case of Redux, the signature of the reducer is state and action. It accepts two arguments, state and action, and it returns the next state.
So it's very similar to the signature of this callback where it has accumulator value, and it returns the accumulator. So the state is being accumulated, and of course, in Redux, it is accumulated over time. You don't reduce really actions at runtime. But the conceptual model is very similar.
So this is why we call them reducers. And there is just one reducer you need to specify when you create this draw. And usually in the docs, we call it the root reducer. But in reality, you want to keep your code modular.
So you create reducers for every part of the state, and you can keep them nested. So you can have, for example, entities, reducers that manages all kinds of entities, like users, posts, whatever. You can have a reducer that manages authentication. You can have a reducer that manages routing.
And all different stateful parts of your app can be managed by different reducers, and they are just combined to create this single root reducer that you get to Redux. So you have the single state object, and with larger applications, obviously, you have more state to manage. Your reducers are returning a new version of that state. So it's an immutable state that returns a new version after the changes have been applied.
Any memory or performance issues with, you know, copying the same object, or just minor modifications to it that you found? Yeah, I mean, it really depends on your application because there are some downsides in terms of memory, but then there are upsides in terms of you being able to figure out what needs to be re-rendered and what does not need to be re-rendered. Because if you have immutability, you can do reference check, reference identity check. And this is, in Redux, it's enabled by default.
So if you use React Redux bindings for React, it's never going to re-render something that has not changed. And because re-rendering is usually more expensive than creating a few objects, Redux has good performance benefits compared to some blocks frameworks that are not, like, they don't have a favor of immutability. And this is exactly the reason OMAR is so fast. You know, there's the Clojure Street library called OMAR that pioneered the concept of a single state object and actually made people treat it seriously.
David Nolan is the author of OM and he wrote an article back then called The Future of JavaScript MVC Frameworks. And it's a pretty old post. It's been a couple of years since then. And David re-wrote OM a couple of times.
He's now working on OMNExt, which is kind of similar to Relay. So the world has since moved on. But it still explains why it's possible to have very fast applications despite immutability. And if you have performance problems, the first thing you can do is you can use a library like Immutable.js.
So by default, we don't suggest you to do that because it's just easier to work with regular objects. And a lot of people don't want to learn two APIs at the same time. So we don't use Immutable.js in examples. But if you have performance problems because of very large lists and hue dispatches like 10 actions per second, which is probably a bad idea anyway, like what kind of UI needs that?
But if you do that, it's fine. But Immutable.js gives you immutable data structures that have structural sharing inside. And this is like implementation detail that makes them much more memory efficient because it's not a monolithic object, but under the hood, for example, an immutable array is some kind of tree. And I'm really bad at computer science as I'm joked out, but it's a tree of objects that you don't really access.
But if you make a copy that just adds a new value at the end of the array, the whole array is not actually being copied. It's just any object that is created that points mostly to that existing tree and it has like another key that points to the part that you added. And they share the same memory. So they share the same tree when possible because they're immutable.
They're not going to change later. This is why they're able to do that without the performance problems. And this is how you can reduce memory usage with Redux. But really, you should profile your app.
You should understand the trade-offs. You should build a prototype with the kind of amount of memory and speed that you want and just stress test it. If it doesn't work for you, fine, you can use Flux or something else. If it works for you, it's great.
And again, we don't force you to use immutability. Like if you really want to, you can mutate things. It's just we don't encourage it until you know why you're doing it. And it's also possible to use many stores in Redux if you want to.
Because at this point, it works exactly like Flux, right? You just have many stores and you can subscribe to different stores that you care about. And again, this is doable. This is just not something we encourage until you profile your app and you know that this is something that will improve its performance.
Because usually it's not. Very good. So let's change face a little bit and talk about integrating a Redux into user interface libraries and frameworks. So obviously, it was built with React in mind.
So it plays well with React. Let's start there. Maybe give a brief story of how you use Flux or Flux. How you use Redux with React.
And then I'll ask some questions about some other popular libraries for user interface stuff. Yeah. So initially, when I first rolled the first prototypes of Redux, it had React support built-in independent on React. But early in the course, we decided this was silly because it is not related to React per se.
And we can just make a separate binding library. So this is what we did. And it was a good decision in hindsight. And we have a library called React Redux that is officially supported.
That is a performance and made specifically to connect React components to Redux stores with a specific philosophy approach to that. We used to call it smart to dump components, but people don't like to call components dump. So now we call them container and presentational components so that components don't get offended. And container components are the components that are aware of Redux.
They get the data from Redux Store. They are subscribed to the Redux Store. And usually they specify the behavior of your app, like what happens when I click that? And presentational components are usually not aware of Redux.
They receive all the data by props. And if you want to move from Redux to something else, you can keep them and just change your container components. And Freeout Redux actually provides you a helper called Connect that will generate the container components for you. So this is basically what React Redux offers.
Very good. So let's say I don't want to use React. Maybe I prefer jQuery or Ember. If and how can you work with Redux in these other environments?
So in case of jQuery, that would not be very useful because Redux assumes that it can give you the previous state of the app and the next state of the app. And here's somehow going to figure out how to re-render your app in response to the state change, no matter what changed. And if you write jQuery code, it's going to be problematic for you to actually check for every single field that might have changed and update the common response. But this is exactly the problem that React is solving.
So frameworks that have similar conceptual model to React work really well with Redux. And I know there's been an experiment to make it work with Ember, but I'm not sure if anyone supports it today. But I'm pretty sure people are using React, sorry, Redux with Angular, both the first version and the second version. And if you saw a post called Change Detection in Angular 2, which was like half a year ago maybe, it detailed that Angular is moving away from its previous model and it's going to be more like React with top-down data flow.
So this explains why Redux plays so well with Angular 2 and people are starting to use it together. Another advantage I think would fall out of having a single object for the state of the application is that if that object is serializable, which it probably should be, it seems to be pretty straightforward to be able to send that object from a server and basically boot your application into a state. Rehydration, I guess, is another term used. Is that something that Redux supports?
Yeah, this was one of the other things I wanted to make sure is fixed in Redux because a lot of flux, some flux frameworks made this complicated, in my opinion, in terms of you have to implement separate methods to actually tell the stores how to hydrate and how to serialize and deserialize the state. And I felt like it's not really good to force this on developer because it's hard for developers to keep this up-to-date and to remember to change these methods any time they change the state structure. So I really wanted to have this to be built-in. And this is really simple in Redux.
It is similar to how Elf framework does it. Although I think it's even simpler with a single store. But basically, you just create a store on the server for every request. You pre-fill it with the data you care about.
Like, you can dispatch async actions, make sure you fetch the data that is required for the first render on the server. And when it's done, you can just call it then, use that promise then. And in the callback, you say that, okay, I'm ready to render. I'm just going to render my app with this state.
And also, I'm going to pass this, I'm going to call store.getState method to get this state object. And yeah, and you pass it down to the client. And then in the client, you just pass this state object as a second argument to create store. And boom, you get the state you get from the server.
Very nice. That sounds pretty awesome. Let's see, what else? Any other major points of the architecture, the implementation, maybe even the ecosystem on Redux that you want to go into before we hit this next break?
I know you did mention that you seem to be very intentional with trying to create or spawn an ecosystem for tools and extensions. Can you maybe touch on that? Yeah. So what I realized is that I'm not going to have all the time in the world.
And when I was using Flux, I really wanted to have some kind of extensions like report and replay, that kind of stuff that is easily implementable outside the framework itself. But the problem was that either most Flux Live frameworks, they were not made to be extensible by default. So unlike Express Framework, which did a great job of being extensible, this is why it's so popular, and CoA on the server, on the client, Flux Live frameworks didn't offer compelling extension points. And they made decisions for you.
For example, some frameworks embrace promises. And there was a built-in way to support dispatch and async actions with promises, and the framework would know what to do. But then somebody wants to use channels or observables or some other async abstraction that the Flux framework doesn't handle. Or it's handling of promises in the way in some cases, and you don't want that.
So I felt like I don't want to make these decisions for the users. I want to make the decisions that the users might not have enough context to make. Like I want to enforce purity, even if the users are not sold on the benefits of the purity yet. And I want to enforce that all changes happen through actions, because this is important for me.
This makes a lot of nice things possible. So these decisions I want to make. But I don't want to choose the async abstraction because people just use different abstractions. And I don't want to be the person who gets assigned here.
I want to give the freedom to choose any abstractions complementary to Redux to the user. And we tried several ways of doing that. And this is exactly where Andrew Clark's help was so instrumental is that he designed the current API of middleware and story enhancers. And there's a lot of middleware for Redux.
And I would say that some of it is pretty complicated and I probably wouldn't do it that way. But people are still experimenting with what's possible, what makes sense. And there are some really nice examples of what I can do with middleware because it's just an extension point into Redux where you can override this for dispatch and action API. And you can do anything there.
Like you can catch errors inside producers and send them to error reporting service. Or you can support promises neatly. Or you can support observables for channels. Or you can lob every action with the middleware, with the locker middleware, and so on.
So it's pretty awesome that people are working on this, are experimenting, and creating a lot of user land solutions to become problems so we don't have to reinvent the wheel with every project. Very good. Sounds like a great place to take a break. On the other side, we'll talk about getting started with Redux.
And of course, we have a good chance to shout out your free video series there, Dan. We also have a theoretical question for you about perhaps the grass being greener on a different side of the fence. So stay tuned for that and we'll be right back. Our friends of Linode are huge fans of the show and they're excited to support what we're doing here at the ChangeLog and they want to invite every single listener of the ChangeLog to try out one of the fastest, most efficient SSD cloud servers on the market.
You can get a Linode cloud server up and running in seconds with your choice of Linux distro, resources, and also no location. And they've got eight data centers spread across the entire world. North America, Europe, Asia Pacific, and plans are just $10 a month. They've got hourly billing with a monthly cap on all plans and add-on services.
Get full root access for more control, run VMs, run containers, or even your own private Git server. Enjoy native SSD storage, four-year-end network, and Intel E5 processors on your servers. Use the code ChangeLog10 with unlimited uses. Tell your friends it doesn't expire until December 31st, 2016.
That's the next year. Head to the node.com slash ChangeLog to get started. And now back to the show. All right, we are back with Dan Abramov.
Dan, we're all excited. Redux sounds really cool. A lot of huge wins in using it. The question is, how do you get started?
And I'm sure many of our listeners are wondering, what's the best way? Of course, there's many ways you can start Googling, reading docs. But if you had brand new eyes and you're coming to Redux as a potential user, what were the first steps that you would take to get started on your way to success? Great question.
I think I was hard with watching my video series, which I created exactly for this purpose. I watched people learn Redux for a couple of months by now. And I've seen people making the same kind of mistakes or the same kind of misunderstandings of Redux, and people missed out on some powerful patterns that Redux offers. So I was contacted by the guys from AgHat, which is an awesome video tutorial site.
They've got free and paid videos. And I think initially they just contacted me to record something about culture loading, but I never got to do it. And they sent me the equipment. The mic I'm talking to right now is actually their present to me, so to say, their investment.
And AgHat was saying like, yeah, guys, I know, I feel so bad about it, but yeah, I'll get around to doing something. And later, Redux came out and a lot of people requested Redux tutorials. And Joel was, and a lot of people inside AgHat who work, who record videos for AgHat wanted to do Redux tutorials. But Joel insisted that, hey, we need to give Dan some time.
He's going to do it. Let him be the first. And I'm very grateful to Joel for this opportunity and for bearing with me for so many months. But anyway, it was November and I previously raised some money to work on React's folder and Redux for three months.
And I actually saved it up a little bit so I could work one more month without doing any full-time job before joining Facebook. And I decided to dedicate this time to creating a bunch of tutorial videos that are targeted at people who kind of, who know JavaScript, but they may not be experts and who know some React, but not much more than that. And who are curious how to build a simple application with Redux without prior Flux experience. So I recorded 30 lessons over the course of a month.
They are bite-sized, so like three or four minutes each. And they taught on the concepts I think are the most important. I'm very sorry, it's a to-do app. I'm building a to-do app during this tutorial.
But I actually, yeah, I know some people hated it, but I get a lot of great feedback. And personally, I think 3D app is the best medium for explaining how to structure state mutations in some kind of framework. And of course, my video series, it doesn't touch on asynchronous requests yet. And a lot of people were sad about it, but we really need solid foundations before you can jump to making asynchronous requests.
So if you're looking for a solid understanding of Redux fundamentals, of Redux patterns, and in fact, of how Redux is implemented, because in some lessons I just show how you can implement this Redux function in 10 lines, it's a great way to start. And these tutorials, they are free and they will be free. This is something I wanted to give back to the community before joining an entire company. So yeah, I think you should check those out.
And if you like them, feel free to buy a subscription to say thank you to the people who gave me the opportunity to actually work on that and host it for free and who gave me the equipment for us. So this is a good start. And after that, I think you're prepared enough to work through the docs. The basic spots of the docs is pretty much the same we cover in these video tutorials.
But there is the advanced section, it covers asynchronous, it covers middleware. So this is something you want to read after that. And you should check out some, I have an ecosystem page in the docs that links to great articles, tutorials, examples that I personally betted. These are really good.
So I recommend you look at them. And I want to highlight one example in particular. It's called Sound Redux. And this is just a SoundCloud client built by a guy called Andrew that is built on top of Redux.
And it's not a lot of code, but it gives a pretty good idea of how a real world Redux application is structured. The to-do applications are the same one that you use in the presentation for your, what was it before, Jerry? It was a conference talk as something development, basically, the hot reloading talk you gave at React Europe in 2015 this year? No, not exactly.
Not the same one? No, it's just, in the conference, I just wrote a part of the to-do app live at the conference, which is pretty great. That was really cool. I like that.
It was nice to see you break your own code and be like, where is it? Okay, here it is. And you kind of walk your way through this. You kind of see this, your mind and how you're pulling back the data from different objects and stuff like that.
It's pretty interesting. I like that. Yeah, but this one, actually, I think in the video tutorials, I show some things that I did not think about completely when I was practicing the docs. So tutorials are actually a better source right now than the docs because I changed the way I recommend to build React to Docs applications your name and then also Redux was very helpful and upon that journey, I stumbled upon this kind of pulling different ideas together that you shared.
It seems like you're all for functional programming in JavaScript versus something like Elm or ClojureScript. And it sounded to me like you're advocating more like good on the Redux path and functional programming in JavaScript versus these other functional languages. Can you talk a bit about your thoughts and opinions on that? I want to say that.
I mean, you really should, and this is me giving an advice that I don't follow, so you probably shouldn't pay attention, but I think you should go out of your way to use different things that exist elsewhere like ClojureScript and Elm just to get a sense of these ideas and how different constraints can make these ideas work because a lot of Elm's ideas work so great because in Elm, you have a completely static typing, it is completely pure, so it is a different environment from JavaScript, a very different environment. And if you want to enforce similar things, you start thinking like, can I bring these constraints in some way to JavaScript or even should I, or should I take advantage of JavaScript's powerful sites that these constraints eliminate? So you should definitely check out those projects with different languages and if you like them, of course, you should use them and collaborate them and there are many Elm enthusiasts out there, I know that, but what I'm saying is that please let us know. If you find some really neat pattern or some really nice way to build UI applications and you only share it with your language community and you don't really speak about it at JavaScript conferences, it is a problem for us and it's sad for us and I think you should go out of your way to evangelize the good things you learn elsewhere and maybe somebody will get inspired by your talk and build something cool in JavaScript even if you don't work in JavaScript.
And of course, people like David Nolan and Evan and pretty much everywhere in ClojureScript and Elm ecosystem are doing exactly that, so big thanks to them. Let me ask you this, so you've poked your head up from your Sublime Text and you're surveying the ecosystem and you're seeing cool things that Elm is doing and you're seeing cool things with Ohm in ClojureScript. These other... ...
... languages, functional languages, building very similar type apps that Redux and React are building. And do you ever think, well, maybe I should just go hop in that pool and see if the water really is warm? Or do you always come back to JavaScript?
And if the latter, why? What brings you back? Why aren't you saying, wow, Elm's amazing. I'm going to hop in all in on Elm.