text:
Latest Shows:
JSJ 374: CosmosDB with Steve Faulkner LIVE at Microsoft BUILD —
EMx 060: Property-Based Testing, Dialyzer, & Inaka with Brujo Benavides —
MAS 086: Brad Green —
VoV 070: Live from Vue Vixens Workshop with Jen Looper —
MJS 116: Jeremy Fairbank —
RR 421: Scaling and Shopify with Kirill Shatrov —
RNR 126: Native Web Apps with Florian Rival —
RRU 070: Drawing the Line Between 3rd Party and Custom Code with Glenn Reyes —
TFS 337: Breaking the Cycle of Indefinite Engagements —
Dev Ed 021: Learning Through Storytelling —
AiA 248: Perfume.js with Leonardo Zizzamia —
JSJ 373: What Do You Need to Do to Get a Website Up? —
RNR 125: Performance with Anna Doubkova —
iPS 264: Pitching to Swift with Igor Kulman —
RR 420: Stimulus —
JavaScript Jabber
Ruby Rogues
Adventures in Angular
Dev Ed Podcast
My JavaScript Story
My Ruby Story
My Angular Story
React Native Radio
React Round Up
Views on Vue
The Freelancers' Show
iPhreaks
Elixir Mix
The Dev Rev
Retired Shows
Teach Me To Code Screencasts
Teach Me To Code Podcast
Rails Clips
Web Security Warriors
Support the Podcasts
189 RR Choosing a JavaScript MVC Framework with Craig McKeachie
Mute/Unmute
02:20 - Help Support The Ruby Rogues and DevChat.tv
Join Parley
JS Remote Conf
Pick Up Podcasting
03:16 - Craig McKeachie Introduction
Craig McKeachie: Choosing a JavaScript MVC Framework
The JavaScript Framework Guide by Craig McKeachie
CodeMash
04:42 - Page Loads
MySpace vs Facebook
XMLHttpRequest (XHR)
09:44 - jQuery
18:32 - MVC Framework Features
Haml
23:49 - Template vs View
25:19 - Are Different Frameworks Consistent in their Approach to MVC?
Marionette.js
29:36 - User Experience
35:16 - How Do I Choose a Framework?
37:34 - "The Pit of Success"
Scott Guthrie
@scottgu
38:59 - (From Parley): Why Would Anyone Ever Use AngularJS?
Adventures in Angular Episode #16: NG 1.3 and 2.0 with Brad Green, Igor Minar, and Miško Hevery
46:01 - Single-page Application (SPA) Accommodation & Client-side Architecture
Techniques for Wrapping up your jQuery
Brandon Hays
JavaScript Jabber Episode #112: Refactoring JavaScript Apps Into a Framework with Brandon Hays
51:00 - Ember vs Angular
53:28 - Other Frameworks, Libraries
pjax
JavaScript Jabber Episode #13: Knockout.js with Steven Sanderson
JavaScript Jabber Episode #31: history.js with Benjamin Lupton
Sammy.js
Portability of Code
59:17 - Getting Started Programming and JavaScript Frameworks
Timeless Skills
Craig McKeachie: Anatomy of a JavaScript MV* Framework
01:04:40 - The React Framework
Craig McKeachie: React.js and How Does It Fit In With Everything Else?
JavaScript Jabber Episode #73: React with Pete Hunt and Jordan Walke
01:06:38 - Full Stack Frameworks
JavaScript Jabber Episode #76: Meteor.js with Marcus Phillips and Fred Zirdung
comet.io
CanJS
Rob Eisenberg: Leaving Angular
ClojureScript
JavaScript Jabber Episode #107: ClojureScript & Om with David Nolen
Flux (a Framework built on React)
Get Craig's Book, Choosing a JavaScript MVC Framework for 20% off for a Limited Time Only!!
CHUCK: We've tried everything else. Active Directory will be back in about ten minutes. [Laughter] CORALINE: Just jiggle the handle.[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on Ruby developers, providing them with salary and equity upfront. The average Ruby developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. It's totally free for users. And when you're hired, they also give you a $2,000 signing bonus as a thank you for using them. But if you use the Ruby Rogues link, you'll get a $4,000 bonus instead. Finally, if you're not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/RubyRogues.]**[This episode is sponsored by Codeship.com. Don't you wish you could simply deploy your code every time your tests pass? Wouldn't it be nice if it were tied into a nice continuous integration system? That's Codeship. They run your code. If all your tests pass, they deploy your code automatically. For fuss-free continuous delivery, check them out at Codeship.com, continuous delivery made simple.]**[This episode is sponsored by Rackspace. Are you looking for a place to host your latest creation? Want terrific support, high performance all backed by the largest open source cloud? What if you could try it for free? Try out Rackspace at RubyRogues.com/Rackspace and get a $300 credit over six months. That's $50 per month at RubyRogues.com/Rackspace.]**[Snap is a hosted CI and continuous delivery that is simple and intuitive. Snap's deployment pipelines deliver fast feedback and can push healthy builds to multiple environments automatically or on demand. Snap integrates deeply with GitHub and has great support for different languages, data stores, and testing frameworks. Snap deploys your application to cloud services like Heroku, Digital Ocean, AWS, and many more. Try Snap for free. Sign up at SnapCI.com/RubyRogues.] **CHUCK: Hey everybody and welcome to episode 189 of the Ruby Rogues Podcast. This week on our panel, we have Jessica Kerr. JESSICA: Good morning. CHUCK: Coraline Ada Ehmke. CORALINE: Coming to you live from my secret lair in cold and wind swept Chicago. CHUCK: Awesome. Avdi Grimm. AVDI: Hello from Pennsylvania. CHUCK: I'm Charles Max Wood from DevChat.TV. And before we get going, I just want to, I hate asking for help but this is one of those situations. I have a few shows, not this one and not JavaScript Jabber, that I've been supporting on my own. And it's gotten a little bit tight these days. So, I'm asking for a little bit of support if you can do it. If you go to DevChat.TV/donate you can donate. If you want an actual something for your dollars, I'd feel better about that. You can go sign up for Ruby Rogues Parley which helps support the show and the hosts and stuff. You can also sign up for forums for the other shows. And you can sign up for JS Remote Conf which both Jessica and Craig will be speaking at. And all of those help put money in my pocket so that I can put shows out on the internet. So anyway, I had to swallow my pride a little bit. But yeah, I would appreciate the support. We also have a special guest this week, and I already mentioned him, Craig McKeachie. CRAIG: Hi. CHUCK: Craig, do you want to introduce yourself really quickly? CRAIG: Sure, sure. I'm a web developer for 15, 20 years depending on how you count things, mostly on the Microsoft stack, so a little foreign being in the Ruby Rogues podcast land. But I do listen to the show. I always try to keep an open mind about all technologies. And basically, always had a Rails MV for years working on the Microsoft stack. [Chuckles] CRAIG: Until we got ASP.NET MVC, the close twin. Been a consultant for most of that time, I worked at startups as well as bigger companies. Always been interested in writing and teaching, so about a year ago I wrote a blogpost now that was on choosing an MVC framework. And it was very popular on the internet, shared over thousands of times, hundreds of comments. So, at that point I decided to go a little crazy and quit my job and write a book. So, I figured it would take me maybe three months and seven or eight months later I finished it this summer. So, that's the JavaScript framework guide. CHUCK: I like what you said. When you think about Ruby, you have to keep an open mind. CRAIG: Definitely. I think just technology in general, right? One of my favorite conferences is CodeMash. I don't know if you guys are heading that way in the Midwest. And one of the great things about it is that it's open to lots of different technologies. So, you can learn a little bit about everything that's going on. CHUCK: Mmhmm. So, we brought you on to talk about choosing a JavaScript frontend framework. And before the show we were talking about the basis of this in a lot of cases is Ajax. So, we thought maybe we'd start there and then talk about what these frameworks offer maybe on top of that or in addition to jQuery. And then move along and talk about some of the other aspects of this with relation to some of the Ruby frameworks. JESSICA: Craig, when I was reading your book one of the things I liked was you made a point about how you liked Facebook when it first came out better than Myspace, which dates you by the way. CRAIG: Yes, I was just thinking that. CHUCK: [Chuckles] CRAIG: I think, "Oh, did she just bring that one up?" JESSICA: [Laughs] Right. But it's an important point that one of the things you liked about Facebook that made it more appealing than Myspace was the page loads, or lack thereof. Myspace and all the sites back in the day, I certainly remember working back when every time you clicked on anything the page went blank and eventually the entire page was redrawn. Nobody does that anymore, maybe Wikipedia. But there's very few sites anymore that are just straight out, you click on something and an entire new page loads. Tell us [what] happened, how that happens behind the scenes with the difference is there. CRAIG: Right, well you know most developers are familiar with this, but some aren't, the whole Ajax concept that under the hood in browsers you can make requests synchronously and load an entire HTTP page. But you can use the XHR objects that are built in to the various browsers and make a request either for HTML or for some JSON data. And… JESSICA: What's XHR? CHUCK: XML HTTP Request. It's built into the HTTP spec, I think. JESSICA: Oh. Is that the X in Ajax? CHUCK: Yes. CRAIG: Thanks Chuck for helping me out. CHUCK: No problem. CRAIG: I wasn't sure I could come with that abbreviation off my head. I'm just so used to being in Chrome Developer Tools and seeing that abbreviation. But that's a good question too, because a lot of people when I'm training ask that same question when I throw out the XHR abbreviation. But I think the key point is that the page, there are technologies built into the browser and they've been there for years that allow you to load partial pages. And whether that be you load HTML from the server or you load data from the server and then in JavaScript bring your page together, bring your HTML and your model together. One common thing I bring up in the book as well is the whole, where does your model data and your HTML come together? Does it come together on the server? Or does it come together in your browser with these frameworks? And I know I'm jumping a little bit ahead. But when you make that mental leap to when you're working with one of these JavaScript frameworks you're committing to bringing your data together with your templates on the client. But yeah, so I'm not sure I did a great job teaching the basic Ajax stuff there. But the idea is that the full page doesn't reload. It's a native browser feature that allows you to make a request to the server for some data. And asynchronously behind the scenes so there isn't a page refresh, you get this different user experience. And I think what's important further than the technology behind the scenes is the idea that you're getting a different user experience, something more akin to a desktop experience. CHUCK: Yeah. It's really interesting, too. I remember way back in the day I would just use jQuery to make a request to the server and it would give me back some HTML. And I would just stick that into the page and that was pretty much the extent of it. But these things have become A, much more common but also much more versatile to the point where you're not returning XML or HTML which is a subset of XML. And so, you then have these systems that are built up around making these requests and then making it easy for you to manage whatever data you're getting back. CRAIG: Right. And I think what's happening is I think we've all pushed jQuery to its limits or whatever client-side library, Prototype or script.aculo.us back in the day. Now most people are settled on jQuery. But we've all pushed it to the limit where we want to do more and more in JavaScript because of the kind of experience we're trying to create for people. And at some point, you need a little more help than just DOM manipulation and the ability to make Ajax calls and piece everything together. And that's when these JavaScript frameworks come in, is when you get past that point where more and more of your code is moving into JavaScript. And you're spending more and more of your time there. Perhaps your back button is starting to break because you've done some fancy Ajax things but haven't thought about the flow of the application, that sort of thing. CHUCK: Yeah and there are a lot of utilities to solve those. JESSICA: That was a lot of letters. What exactly is jQuery? Why is it everywhere and what are its limitations? CHUCK: So, I can take this. So, jQuery it initially I think, or the way I thought about it when I first encountered it was that it was a set of utilities for managing your page. But what it really comes down to is, and I'm going to use another three-letter acronym, is a way of managing the DOM. And the DOM, the D-O-M, DOM is the Document Object Model. And the document is your HTML webpage and the Document Object Model is basically a programmatic way of representing the HTML. So, it represents… AVDI: It's a tree. CHUCK: It's a tree. And it's the way that your page is effectively laid out. And so, if you change the DOM, if you change that object model, then it's reflected on the page in the HTML. JESSICA: The DOM is the model that the browser is using to render the page. CHUCK: Yes. JESSICA: jQuery is a way to manipulate that model which your browser then translates into manipulations on the page itself. CHUCK: Yes. AVDI: Right. And you can do all that in raw JavaScript. That's what it's there for. JQuery just came along as a way to do it without wanting to bash your brain against a wall. [Laughter] CRAIG: Well put. CHUCK: Right. And the problem that it solves was that many of the browsers implemented things a little bit differently. Also, many of the browsers had bugs in them that would cause them to behave differently even though it was specified that they should behave in a certain way. And jQuery normalized all of that. They made it so that if you told something to disappear, no matter which browser you were in, it would disappear. Or if you use some of the animation features with slide up or slide down and it would be at least reasonably consistent whether you were using Chrome or Internet Explorer or Mozilla Firefox or something else. JESSICA: So, is it a little bit… AVDI: It also layered a much nicer API on top of, or at least more concise. CHUCK: Yup. JESSICA: So, in that sense jQuery is a little bit like the Java Virtual Machine which abstracts the hardware. You don't care what hardware you're running in. You just speak Java at it and the virtual machine translates it. CRAIG: I think that's a really good analogy. JESSICA: Yeah. JavaScript is the bytecode of the web these days, right? CHUCK: Yeah, pretty much. JESSICA: Writing raw JavaScript is painful because yeah, you have to have that hardware abstraction where here the hardware is the browser. CHUCK: Yeah. And there's a lot of nuance to this. One of the, what some people see as a drawback of jQuery is that it also hid some of the implementation details of JavaScript itself from you. And so, you didn't realize how JavaScript works with its own scoping and hoisting and all of the other things that come with it. And because it worked so much differently than most backend systems, once you got out of jQuery then you wound up in a world that you didn't understand. JESSICA: Oh yeah, I've had that experience of, "I'm a great Java programmer so JavaScript should be trivial. Oh my god, this is painful! I can't make it go." CHUCK: Yup. But it's also a very powerful set of tools in your browser. So, it's nice to have these power tools that sit on top of it that allow you to do all of this work fairly easily. And that's where a lot of these frameworks come in. JESSICA: So, where does jQuery stop cutting it? When is it not enough? CHUCK: So, jQuery really does well with manipulating the DOM or manipulating the webpage if that's the way you want to think about it. But let's say that you had a framework and all it was really good at was the presentation layer. What do you do when you need to access the database? Or talk to an API? Or there are a lot of other things that jQuery doesn't really do except on a very basic level. And so, you need something that really thinks about, "Okay, how do I organize my code? Where do I put the logic bits as opposed to the webpage layout manipulation bits?" CRAIG: Right. I think a good analogy for this would be thinking about why did we need Rails? Why wasn't it just enough to have dynamic scripting on the server like in ASP language, classic ASP, or a JSP language? Why didn't people just want to work in those frameworks? Why did they put these MVC frameworks on top of that? And it's what Chuck's hitting at there with the idea that you need something that helps you do that stuff you do all the time in the application. JESSICA: That stuff you do all the time in the application, separating the business logic from the presentation logic? CHUCK: I think the separation of concerns is more of an artifact of solving those problems than actually solving those problems, because it makes your code easier to reason about. But it's really the toolkits that are provided in there that Craig pointed out, that do the common things that you're doing all the time. I think that's the real power in a lot of these frameworks. And then being able to do the separation of concerns and think about these problems separately is just a way of helping people organize their code, and organizing their thoughts around how they work. AVDI: One of the places where I first started seeing the need for these on website where we were just using jQuery were situations where we were starting to do a fair amount of Ajax. So, we're making requests from the page without actually reloading the page, just to load little things into the page for a nicer user experience, doing the kind of thing that we call progressive enhancement where the page loads but then we add little niceties to it. And we can interact with it in ways that, little things, loading lists. You pick lists to pick from without actually reloading the whole page and stuff like that. But where I started seeing issues was as soon as you start loading little bits of information from the server without actually refreshing the whole page and as soon as you start referencing the same bit of information in multiple places on the page, for instance the name of a task. Let's say you're making a to-do list. The name of a task might appear in multiple places on the page. If you're not refreshing the whole page and pulling a whole new view back from the server, it's easy for that stuff to get out of sync. And once you have a few things that can get out of sync on a page because of little in-page reloads and you start trying to handle that with jQuery, it just, madness lies down that road. JESSICA: Spaghetti. AVDI: For just plain jQuery in JavaScript without any kind of model to back it up. CORALINE: I think it's analogous to using Sinatra to build an application. You end up recreating Rails. If you're using jQuery to build an SPA, a single-page app, you're going to end up building lots of pieces of a framework that solve that problem of reusing components and reusing data. CHUCK: Yup. The other issue with not reusing data, besides the consistency issues on the page, is that every response is stored in a different place in memory. So, if you request the same data three times then it's going to store it in three different places and unless you have a mechanism for saying, "This is the same data as that." And so, you can also cause memory issues in your browsers. It's less of an issue with modern browsers. But in the past, you get enough objects in memory and you start causing problems where your page freezes or doesn't react properly because it doesn't have the memory it needs. JESSICA: So, these frameworks allow you to have different places on the page that reference the same data. And that data really is the same data in memory and in the request, the single request that went back to the server for it. CHUCK: Yeah. Once you get far enough down the road where you have multiple components that need to, yes it does solve that problem. When you first get started like Avdi was saying with the progressive enhancement, you just start filling in select boxes. And so, you select something in one select box and then it fills in, for example you select United States and then it fills in the next select box with all of the states in the United States. And in those cases, the data consistency really isn't that important because you're going to be dealing with the same data one way or the other. But once you get to the point where you are moving large amounts of data, and that's the way that the web has gone these days, then yes, you need that kind of consistency. But the other thing that they provide and this is something that came out of Rails, was they provide you with a standard way of getting that information in the first place. So, because you have the convention, and I'm assuming that most Rails developers are familiar with the idea of a convention which is basically just a standard way of doing something, once you have those conventions then you can do things in a similar way across your entire app. And they start behaving, your app starts behaving in a consistent way. And you don't have to think about the way that you're building your app in those instances anymore. CRAIG: Right. And to make this more concrete it might be good to talk about what features does an MVC framework bring to the table. And what you'll find is they're very similar to the same features that say Rails is bringing on the server or any server-side MVC framework is bringing. But they're happening in JavaScript in the browser instead of on the server as part of that language. So for example, routing. Everybody's familiar with the router in Rails I assume. So, it basically maps a URL to some code at its minimum ability. And so, when you make this transition to wanting more dynamic interactions, having a more native feel to an application and having it run, most of the code, run in the browser, then you start needing that same mapping of URLs to a given set of code on the client side so that your back button continues to work. And you don't get into this position where, let's take some common thing you might do in jQuery is load a list of items and then pick from that list a subset of those items. Well, if you do this operation and then you hit the back button a lot of times the back button will end up broke depending on how you do things, because it'll go back to the previous page you were on, not the previous unselected item from the list that you might expect it to be, to have done. What you wanted was each one of those states possibly moving an item in the list from one list to another list to be a specific action. That's what you'd expect on the server. If you hit the back button, you'd be undoing whatever you just did. So, there's… JESSICA: This is the back button in the browser? CRAIG: Correct. JESSICA: Which used to work very easily back in the Myspace days because every time you clicked you got a whole new page. So, when you hit back, you went to the previous page. How do we fix that in single-page apps? Do we override the back button? How does that even work? CRAIG: Basically what's going on is when, what would make a normal request like a click on a link or any action that would change the URL, gets intercepted in the JavaScript world, so natively in the browser. And at that point, whatever needs to happen, whatever data needs to be gotten from the server for example in one of these frameworks, there's an Ajax request that's made for the new set of data that you might need. It comes back down and it fills in the page. And you add in an event to the history of the browser. And this gets a little more complicated on how this is done. It depends on whether your browser supports HTML5 push state or not, which still quite a few browsers do not. So, in those cases, there's usually the equivalent of what appears to be like a query string, which is the hash tag with additional parameters on the URL. And after that hash, it makes a virtual page in the web browser and records that in the history. JESSICA: Wow. So, we're actually changing the browser's history so that when it hits back, we're controlling what happened. CRAIG: Right, because what you did was basically make a virtual page change. Virtual, I'm using this virtual term to mean you've changed some data on the page but you didn't actually reload the whole page. So, you have this thing I call a virtual page load happening. Maybe it's a whole section of the page. Maybe it's just one item being moved from a list to another list. And in those cases, you're tracking in JavaScript, changing the browser's history to reflect that state that your application has moved from one state to another state and transitioning it. JESSICA: Wow. That's helpful for the user because then when the user asks for one thing, they still have access to everything else for the page. It doesn't go blank for them. But holy cow, I can totally see why you would want a framework to do this for you. That's a lot of moving parts. CHUCK: Yeah, and it comes down to the same advantage that you had with jQuery in that it's pretty much consistent across the browsers. They solve a lot of these problems for you. JESSICA: Who's 'they'? CHUCK: The people who wrote the framework. JESSICA: Like Angular, Ember? CHUCK: Angular or Backbone or Ember or Durandal. There are a whole bunch of them. Knockout. CRAIG: And it's not just this routing problem that they're solving. CHUCK: Right. CRAIG: It's also its templating. So, the templating that usually goes on the server, so you guys fill me in here, Haml, what's the… CORALINE: ERB. CRAIG: ERB. What's the current favorite nowadays? It depends on who you talk to, right? CHUCK: Right. CRAIG: On the server. There's this idea that you merge data together with a templated view and it happens right now on the server. Well, if you need that to happen on the client side, then your framework needs to do that same work in JavaScript on the client side. I'm not saying this is always a good idea. But if this is what you need in your application, if it's this native feel that you need and you bought into it, you would like some help doing that templating on the client. JESSICA: Is the template the V in MVC? CHUCK: Yes. CRAIG: It is. And some people get confused between when people say template versus view, what's the difference? I think if you actually want to mentally say, "Well, what's technically the difference here?" The template is the static HTML with the placeholders there, with the dynamic pieces there, but not replaced. And the view is after it's been rendered with the data in it then technically I believe that's the view. JESSICA: Ha, so what's the difference between parameters and arguments? AVDI: Correct me if I'm wrong here, but there are also some different ways of handling this with different frameworks, too. Rails conflates templates with view even though that's arguably not exactly what the original MVC architecture was. You see stuff like that but you also see things where there's actually an explicit view model, which is separate from a data model. And the view model is associated with templates but it's a separate thing. I think Backbone does some of that? CRAIG: Yes, definitely. Good call, because a lot of people get confused with the Backbone framework. There's something called a view but it's more of a code based JavaScript object as opposed to being this fragment of HTML, right? So, in that case the view is something different. So, it depends on which framework you're talking about, what the view usually means. But generally you can think of templates as fragments of HTML and that you're doing templating. You are dynamically loading data into that. But Backbone is a clear exception to that. CORALINE: This further raises a question for me. And that is are the different frameworks consistent in their approach to MVC? Do they even call what they're doing MVC across the board? CRAIG: That's a really good question. And the answer is, definitely not, right? They are not consistent. JESSICA: [Laughs] CRAIG: And then other thing that's funny is this was a problem with me naming my book, because I didn't not want to call it the JavaScript MVC framework guide or whatever, because I would have had to explain over and over again that even though I called my book the MVC guide, these are not actually MVC frameworks. But to answer the question more specifically, to give some detail, like Angular calls itself a model-view-whatever works for you kind of framework. So, they go on the record saying there's a model and there's a view. And then there's this 'whatever' concept. So, they're coming right upfront in saying, "I am not an MVC framework. I am a model-view-whatever framework." CHUCK: Which is funny because… CRAIG: It may look close to what you know as an MVC framework but it's not exactly what you think of it as, I think. Ember is probably the most confusing in this area but also the most robust in this area where what they have is close to maybe the original MVC concepts that were before even the web came about. And they have lots of, I think like I said it's very, very robust in how it handles things. I don't want to open a whole can of worms, but there's a route and a router and a controller. And the controller, what's strange with the Ember framework is the controller is essentially a presentation model, which for people who are familiar with the server-side world this can be mind-bending until you figure out where you're supposed to put things in this world. CORALINE: That's a problem that I've had in developing with some of these frameworks is just knowing where to put things, because it seems like in a lot of ways there's so much freedom and flexibility and a lack of established patterns that it can be very, very confusing to know exactly where to put a particular kind of code in a framework that's very loose like that. CRAIG: I think that's definitely a challenge and one of the cons I've mentioned of a couple of frameworks. Backbone even goes so far as to, this is an advertised thing that people love about Backbone is this idea that it's very un-opinionated. But without that opinion, without that convention, sometimes it leaves you wanting for a little bit more structure. But it depends on I think personality of developers and your style and so forth. If you're a person who likes to invent things from scratch, is really comfortable in raw JavaScript, this freedom can be quite liberating. For someone closer to my background, it's not really liberating at all. I found it harder to warm up to, despite its merits. CHUCK: Well, and you're not the only one. People have built systems on top of Backbone, like Marionette for example, which makes it act a lot more like a traditional MVC and gives you a whole lot more convention regarding where to put code and how to think about your problems. CRAIG: Right, and this is something I recommend in the book, is that if you're going to take something like Backbone on, if that ends up being your choice, definitely use something like Marionette or the other, Thorax I believe is the other competitor in that space. Because Backbone is a smaller library as opposed to being a larger framework, which is more what Ember and Angular are. So, if you need more functionality, if you need more of a path to help you build your applications, you'll be wanting more. And that's where Marionette comes into play. Frameworks like Marionette come into play and give you those pieces that are sort of missing from the un-opinionated Backbone world. CHUCK: So, we've wandered all the way up to, "Okay, here's what a framework is. Here's what it does." I have to questions. I'm not sure which one we should answer first. So, I'm going to throw them both out there and we can decide which one we want to tackle. The first one is we've talked about the user experience being better when you do work rendering, whatever, on the front end. But we didn't really talk about why, why it really makes a difference other than that it has to redraw the entire page or it doesn't. And then I think there are some things that we could dig into there. The other question though is, and this is the whole crux of this conversation, how do I choose which framework? How do I know which one's going to fit my problem? Or does it matter? CRAIG: Right. I think the how to choose a framework, it's a big topic. The first one, Chuck, can you repeat that first one real quick again? Maybe we'll try to tackle that quickly before we get into that. CHUCK: Right. So, the question is, why is it a better user experience when I'm doing these single-page app kind of things where I'm making Ajax requests and then modifying the page as opposed to hitting the page and loading the whole page again? CRAIG: Right. I think it just comes down to: does your application have a need for being more akin to a desktop application, to having that experience where things are so responsive? If you think about when you're using a web application sometimes, as much as we all love them, there can be times when the page repaints where you lose your place. Like you might be going through a wizard or something and the page takes a few seconds to go to the next step in your wizard, and we do all kinds of UI things to guide us along that wizard path, for example including top navigation and saying, "You're here in this process." When you have something that's more a desktop application, the screen isn't constantly repainting, you don't really lose your place per se. You just kind of always know where you are because nothing is sudden. There's not this jerky experience where your whole world is ripped out from underneath you and then replaced every once in a while. And not that this is always the experience with a server-side application. There were other ways of approaching this to make that better for the user. But it is pretty common that this can happen in an application. So, that's one thing. I don't know if anybody else has some ideas along this route. And I always say you don't necessarily need a client-side application. The way I view it is, do you need a chair from Ikea or do you need a handcrafted wood chair for the kind of requirements at task you're approaching. And if you need that handcrafted wood chair, then at that point you might be looking at things like JavaScript client-side frameworks to improve that experience and maybe get that handcrafted experience for your users. CORALINE: It's really about creating the illusion of responsiveness. Because if it takes a component half a second or a second to refresh or to even appear on the page, and I'm looking at you Google Plus… [Laughter] CORALINE: We have that illusion of responsiveness. But really, what's happening is that we're maintaining context between state changes. JESSICA: Is there a cognitive science sort of user experience? I feel like I've read somewhere about how if something moves from once place to another on the screen in a continuous fashion, your brain can process that much more easily than if it's a jerky sort of appearing and disappearing. CHUCK: I have no idea. [Chuckles] JESSICA: Well, I think there's something about that somewhere but I don't have a link. [Chuckles] CHUCK: Yeah. JESSICA: It's like on the Mac how the windows zoom down and they zoom out and there's this continuity of movement that you can achieve on the desktop or in a single-page application that you can't get when the page goes blank and reloads and comes back. CHUCK: Yeah. CRAIG: And some of this manifests itself in animations transitioning you between views so that there's this perception that it's all one common thing that's just transitioning between states as opposed to it being separate things that you're taking it, your brain is having to process over and over again. JESSICA: It's like the single-page app is a video call and the regular Myspace style is text messages. CHUCK: Yeah. One other thing is that for complicated pages that have a lot of data in them, and we've kind of alluded to this, if you have to render all of that on the server-side, it can take some time. And so, it's not just that it goes away and then comes back and redraws itself. But if there's a lot of data that has to pull in and put together and things like that, it can slow the page down to the point where you're looking at a blank screen for a second or two seconds or three seconds. CORALINE: Ugh. CHUCK: And with a lot of these frameworks, you at least get the frame of the page loaded in and then it can go and load the rest of the stuff in. And so, that creates a different user experience. JESSICA: Ooh, then it can load the ads first. CHUCK: That's right. CRAIG: [Chuckles] CHUCK: Because those are the most important. That's why people are coming to your page in the first place. JESSICA: [Laughs] CHUCK: But the other thing is that, and this is something that I've found interesting. I don't have a good source for this, but there's not just that disadvantage of time when you're rendering on the server. But if you can push some of the rendering to the client, then I believe that your load can be managed better, because it's managed in smaller, discrete requests that get data that then populate the page. And so, we're moving back out to distributed computing. In this case, we're distributing some of the load back to your client. CRAIG: Right. And to kind of move on to the second question and at least start us off with that sort of discussion, the original article I wrote, choosing an MVC framework, you could probably Google that and I'll come up close to first. My blog is FunnyAnt.com so you can pick it out pretty easily from that. But I talk about a lot of things that people don't always think about when they're choosing a framework. A lot of people talk about say, size for example how big is the library. But I think there are other more important things like the leadership of the library, who wrote the library, the philosophy of that leadership, their inspiration, interoperability, things like that. And we can dive into any of those. One that usually resonates pretty well with people is this idea about inspiration. In other words, when you look at each of these frameworks, who inspired these authors of these frameworks? Was it Rails? Was it jQuery? That sort of thing. So, for example just to give some concreteness to that, in the AngularJS world these are people coming from a Java background who are familiar with inversion of control containers and dependency injection. And so, there's a really great testing story to AngularJS because of this background that they come from. If you take something like Backbone, this is clearly coming from a jQuery type influence largely. And then something like Ember really is heavily, heavily influenced by the convention over configuration ideas in Rails and so forth. So, just a couple of things to throw out there where if you understand the people who are writing these frameworks and what they really value, then you can know that those same values will be in these frameworks. CORALINE: You consider testability a core value of these frameworks? CRAIG: I'd say of Angular in particular. I think all the frameworks are testable. It's the pit of success is hit a lot faster and a lot easier in the Angular world than with some of the others. But it doesn't take away from the fact that I wouldn't say that some of these are not testable. They're all, I've seen big test suites on all of these applications written in all these ways. AVDI: You use that phrase in your book, 'the pit of success'. What does that mean to you? CRAIG: It probably comes from my Microsoft background. Scott Guthrie who many people know is the head of the dev area at Microsoft, been promoted lots of times. And he used to say he wanted to lead developers into the pit of success. And so, this is where I bring it from. But the idea is basically that the default, it's like reasonable defaults in a 37signals Basecamp world or whatever where you want the developer experience, the default thing they do to allow them to succeed. So, an example would be you start a project and it immediately asks you, do you want to add a test project? It doesn't require you to, or creates on for you. It doesn't require you to go remember to add it and do it. And that's a funny example in the Rails world, but in other development areas, this sort of thing, it's having a directory structure that makes sense so you don't have to make decisions about where to put all of your files. The framework gives you that path. Those are the kind of things I think about, those convention type things a lot times. JESSICA: So, you're in the pit of success when doing the right thing is also easy? CRAIG: Right, when doing the right thing is very easy. It's the default. It's the thing that you would do if you couldn't figure out what else to do. AVDI: I would like to throw some dynamite on the fire, if I could. CHUCK: Yay. AVDI: [Chuckles] CRAIG: Release the dynamite. AVDI: And also bring this home a bit to the listener community, because we have a community bulletin board or forum called Parley that a lot of the listeners are on. And we have a lot of great conversations on there. And one of them that caught my eye recently, and I thought it was very timely. Somebody posted a thread entitled "Why would anyone ever use AngularJS?" A few highlights of this message: at a previous contract position, the main product I was working on had the frontend written with AngularJS. It was the most convoluted code I've ever seen. There were chunks of code all over the place. Some in controllers, some in directives, some in application.js. And I can't find any rhyme or reason as to what goes in what file. The homepage displays nothing but a footer until Angular kicks in and renders the contents of the homepage, search engines be darned. I searched for hours for ways to simply be notified, presumably be a callback when the template has finished rendering. As the last time I searched for it, you can't do it. To me, Angular is like what a Java developer who has spent the last eight years being made fun of by the Ruby and Python communities would come up with so they could feel comfortable writing JavaScript. [Chuckles] AVDI: [Chuckles] Now, and obviously this person might have just worked on a particularly lousy example of an Angular application. But I was interested that it became a very active thread. And a whole lot of people actually piped up with similar experiences. And I'm curious what your take on that is, of some of the criticisms of Angular, since we're talking about comparative frameworks. CRAIG: You know, I felt like most of the stuff you said there was true of Angular. But it was almost like the person just expected it to be like Rails and didn't embrace. Somebody moved their cheese and they didn't embrace that new world. I don't mean to be… but it's like nothing you said there was like, "Oh my gosh, that's horrible except for maybe the SEO concern." It seemed like they said, all their code was in files that made sense and were named what it should be named. You know what I mean? I'm not trying to defend Angular but I'm looking for what, just take an outside perspective, what of those statements from you guys made you say, "Oh, I never want to touch that framework"? Was there a statement in there that made you say, "Wow, that sounds so wrong"? JESSICA: It sounded like a disorganized application, but you can get that in any framework. AVDI: Well, the follow-up thread, and it's difficult for me to summarize the whole follow-up thread but it had a lot of people piping in with their own experiences. And one of the things that I drew from it was that Angular had a lot of cruft to it which a lot of stuff that they've started deprecating. And then now there's Angular 2 which apparently basically deprecates everything and is completely backwards-incompatible. CRAIG: Yeah. To address the Angular 2 thing, Angular 2 is not out. It's not going to be out for a year or something. AVDI: Oh, so like Perl 6. CRAIG: [Chuckles] Right. [Chuckles] CRAIG: So, I think it's not a great legitimate argument to say, will it be wrong? It's good to have concerns about a migration path that people have. I think there are legitimate concerns about the syntax that people brought up and so forth, for the 2.0 version of this. But it's just, the conversations that are going on, on the internet are not about things that I feel like they need to be about for that framework. There are concerns with the new version of framework but they're not about the kinds of things that actually make sense with the 2.0 framework, because it doesn't exist. It's a year off from even existing. AVDI: Right. CRAIG: And people are saying, "Oh, I'm going to have to rewrite my application and it's going to be this way and it's going to be that way." And it's more like, people trying to get feedback. The SEO concern where search engines be damned, it's a pretty valid concern but it's valid across all of these frameworks. So, you really can't give one too much of a nod right now. They all have, I think Ember has a slight advantage for a couple of reasons I could get into in this SEO world where a page is rendered without much content and you want that not to be the case for search engines. I would say in general, I generally see this for internal business applications. If I were building a product catalog on the internet despite all the time I've invested in learning these technologies, I would really think hard before I built something that SEO was important to in this. Now that said, if you've got a shopping cart or a checkout experience that you really want to hone, these frameworks are great for that sort of thing. But I don't know that a lot of the apps, how many apps do you know that need, that are public-facing that need to be indexed by Google? How many applications do you build that need to be that way? And if the answer is a lot, then I would seriously consider not using these frameworks for those use cases. You can make it work. But that goes across the board for all the frameworks. CHUCK: I want to chime in on this a little bit, too. First off, regarding Angular 2, we actually talked to Brad Green, Igor Minar, and Misko Hevery on the Adventures in Angular podcast about this. And the episode's almost an hour long, which is long for that particular show. And so, if you have questions about Angular 2.0 versus 1.3 or whatever, I highly recommend that you go check that out. And regarding SEO, I have to also point out that if you go look at the Google information regarding JavaScript, their crawlers now do execute the JavaScript on the page. I don't know that that makes them necessarily good at this, but… CRAIG: Yeah, I've definitely seen people's websites who have been crawled by, they attempted to go into the web master tools and get their website properly crawled by the Google's JavaScript engine. And I know they'll get good at it, right? They're going to get good at it. But right now, I would not bet my business on this. CHUCK: Yeah. CRAIG: [Chuckles] I would not depend on that. But I think if you're honest with yourself, a lot of the business applications that at least I've built over the years, and I worked at several interactive firms so I did work on a lot of public websites as a consultant, there's still a large percentage where perfectly fine as long as you can send a bookmark to somebody, they could get back to the state they needed to be in, in the application. And so, that's still possible. It's just this search engine crawling thing that's a bit of an issue with these frameworks. That is an issue. CHUCK: So, you could essentially build your marketing and about and landing page copy in static or semi static HTML. And then do the rest of it. So, if you have an admin panel in the background or something or Facebook where you don't necessarily need to crawl all of that kind of user framework and no one will care. CRAIG: Correct, yeah, yeah. And there are exceptions. I'm sure someone could come up with ones and say, "Hey, I'm working on this project." CHUCK: Yeah. CRAIG: "And SEO is utmost importance," and yes, yeah I agree. But it's not as prevalent as I think. Sometimes we act like it is. CORALINE: I've had experiences with single-page apps where they want to be the only face of the application. And making that blended view of traditional server-side rendering versus JavaScript rendering can be really, really tricky sometimes. Or if your application is particularly complicated and you essentially want to have multiple single-page apps within a single web application, that can be really, really difficult. Do any of the frameworks accommodate that or is that more of a backend framework question? CRAIG: I think none of the frameworks do a better job than the others that I've noticed in allowing you to have half your app be a server-side rendered app and half of it be a client-side app. Is that what you're asking? I want to make sure I'm answering your question. CORALINE: Yeah, exactly. If you have a complicated app where maybe you want a particular workflow to be an SPA, a single-page app and you want a different workflow to be handled in a different way, maybe you have different data. Instead of making a JavaScript monolith, how easy is it to break those up into different applications? CRAIG: On the one hand, in Angular there's an ng-app directive and that says, "This is the part of the DOM on this page that I own," and there are similar things in Ember. And Backbone is so open-minded that you could easily build things in. I guess one piece of advice I give a lot of people is if you've got a project where you've got a lot of a server-side app there already and your jQuery is getting a little out of control. It's getting more and more complicated. It's becoming a lot of code. Your back button is breaking in lots of places. You find yourself constantly looking for a given ID in the DOM and then updating that. And you want to get that code less spaghetti-like, then I think Backbone is an easy in-roads to this world because it's so light and small. It's a library and less of a framework. And it's so familiar to jQuery developers. So, it sort of has in some ways has a better interoperability story there. And it's simply because the other frameworks are trying to do more. So, it's almost easier to interoperate with a server-side application if you're trying to do less and just trying to help the developer on the client-side. So, I'd say a slight not do Backbone in that case. But if you start doing any substantial amount of client-side work in a section of your app, the other ones are ones I would lean towards. AVDI: I want to put a little not of warning on that. I actually watched a project go off the rails that way. It was a typical Rails project with a fair amount of front-end jQuery going on, actually quite a lot. And someone made the pretty sensible observation that if we're going to make it any more complex it really needed to have some sort of model abstraction on the client side. And it was time to get some Backbone in there. But it turned out to be one of those things that was like pulling on a thread and it stretched out to weeks and then months because you update one thing to be Backbone-y and then it's out of, off kilter with other things on the page that it now interferes with or that interfere with it or that are out of sync with it or something like that. Or you need some new endpoint on the server to service it or whatever. I don't know. Just be careful. I've seen these trying to sprinkle a little bit of Backbone in, I've seen that go way off the rails. CHUCK: I think there are definitely techniques for wrapping up your jQuery. They don't always work with all apps. But there are some terrific ideas around how to do that. Brandon Hays has given several talks on this and he was also on JavaScript Jabber to talk about it. So, if you just do a search on YouTube you'll probably find one of his talks about refactoring JavaScript apps into a framework. Now, he uses Ember in particular. But the techniques translate pretty nicely I think to the others as well. CRAIG: Right. But I think the caution is worth heeding simply because… CHUCK: Yes. CRAIG: You're basically at that point, you're building two applications. And it's like you can't decide between which architecture you're committing to. And that can be challenging. So, I can definitely see it taking a turn for the worse if you aren't clear that the shopping cart is Backbone and the rest of the app is, the product catalog is a Rails app or something like that. I keep using the same example, but you get the idea. You don't want to be duplicating your work and very un-DRY. And when you're doing both the client-side architecture as well as the server-side architecture it's really hard to stay very DRY. AVDI: Yeah. I think one of the big, big issues we ran into with that was templates, because naturally we almost immediately started wanting to share templates across both the server and the client side, because otherwise we'd be repeating them. And that turned into a bit of a rat hole because a lot of the templates were very tied to the Rails application and yadda, yadda, yadda. So yeah, it can get more complicated than it sounds. CHUCK: Mmhmm. You mentioned that if you're trying to organize some jQuery spaghetti, Backbone can give you a lot of structure. And it may do that better than the others because it doesn't make as many assumptions about your code and allows you to have a little bit more freedom with how you manage that. Are there things that Angular or Ember are better at? For example, are there certain types of applications that you would look at and immediately go, "Yeah, that would be better as an Ember app," or "That would be better as an Angular app"? CRAIG: Yeah. I think that if you are committing to a full client-side architecture, in other words your templating is going to be done on the client and so forth, I think Angular and Ember are clearly a generation beyond in maturity to Backbone in terms of productivity and the number of features in the frameworks and so forth. So, anything that you're really starting more greenfield or brownfield and you don't have a huge legacy codebase, I would lean towards the Angulars and the Embers of the world in general. In terms of apps that fit really well with them, I think it all comes back to how important is it for the app to basically have this desktop type experience to it? And if you can see that this is very important to the end result for the business in the application, then you really want to be leaning into the Angulars and Embers of the world. If, I think it's a big conversation to talk about a lot of the other pros and cons. But if you were to pick one or two things, if your really big priority is testing I think Angular wins that battle basically. It's really a first-class citizen in the framework and forward-thinking. If you want to say something that's really awesome about Ember, it's that they did the router in a much better and robust way than any of the other frameworks had ever seen when they first came out with it. Ember has other projects. The Angular UI project that is catching it up. And they're currently porting back into the latest version 1.3 version of the router that does nested routes, basically routes within routes so you can more of a composable UI story. And so, that's a big strength of Ember's, is the router. CHUCK: What about frameworks that aren't Backbone or Ember or Angular? There are a ton of them out there. What if I wanted to evaluate one of those? So, Knockout or Durandal or, there are probably ten other ones. CRAIG: Right. I think when you first asked the question I was thinking about, well what about, are you talking about these Turbolinks type frameworks like pjax and… CHUCK: Yeah, we should dig into that, because many of our developers are using Rails. And Turbolinks is built into Rails and Turbolinks is something I turn off and just use Angular. I'll admit I'm an Angular fan. But you know, it is a unique or a useful thing. So yeah, let's talk about that for a minute. CRAIG: Yeah, I think it's worth considering how much interactivity, how much of that responsive experience do you need in your application? If it's only a couple small areas, those type of solutions, and if it's largely a read situation where you're not writing data, I think those solutions are certainly getting you a lot of bang for your buck without splitting your codebase like we just spoke about. And they're worth an evaluation. But it's a commitment to go to one of these other frameworks. But sometimes it can be worth it if you're doing a lot. You're really building what you would consider an application and not a website. And it has tons of forms and tons of data and you're not so worried about the SEO world. And you need that desktop experience. It's definitely worth looking at one of these. So, that's the criteria I use, is if it's not a ton of functionality in the app, I would look at these Turbolinks, pjax type solutions. I would love to see somebody come with more of a framework from that perspective. So, just to explain what that perspective is, this is the perspective that, instead of all these other frameworks that we've been talking about, the Angulars, the Embers, the Backbone, assume that you're going to send data down via JSON. You can send it via other means. But generally, you're going to send your data down via JSON. You're going to send HTML templates down to the client. And you're going to bring those two things together on the client. The idea with pjax and Turbolinks and so forth is more this I'm going to replace portions of the page but I'm going to send HTML, basically. I'm bringing together pieces of HTML. And I think, particularly in read scenarios like I said, there's not a lot of downside to those. And you can make the forms and the data scenarios work. But it can be more challenging. But if it's just small pieces of your app that need that interactivity, those are really good things to consider as opposed to forking your application and having this whole different MVC architecture on the client in JavaScript. Anybody else have some thoughts on that, experiences? CHUCK: Your experience lines up with mine. I don't have anything to add. CRAIG: And then to answer your second question, as far as evaluating the other frameworks, I think Durandal is, how do you do it and so forth. I mentioned these in the book. I talk about just some things to be aware of. Like in the Knockout is really, up until recently has been, it took more of a best of breed approach. So, its main feature is the data binding feature. And it does this very well. But it doesn't attempt to be as framework-y or as broad as some of these other solutions. So, just know what you're getting out of the box. If you're using I think recently there was some new versions of Knockout that came out. But this is within the last month or two. But up until then, you're really just talking about getting data binding. And there are libraries that do the routing feature we talked about and some of the other things that you need to build a single-page app. And these libraries are standalone, so like History.js and Sammy.js. And these libraries are very good and robust. But what you're doing is you're basically bringing best of breed features from multiple JavaScript libraries and then bringing them together yourself in your code, as opposed to getting one package that cohesively, hopefully works a little better together when you're talking about the Angulars and the Embers of the world, and the Backbones. CORALINE: What impact does that have on the portability of the code that you write? CRAIG: So, if you take, yeah if you take something like Knockout I think you're depending on a lot more libraries that aren't moving in unison. So, it could be challenging for you to keep those libraries in sync with the latest versions of all three of those. Is that kind of what you're hinting at? CORALINE: I'm thinking about what happens, and I've seen this happen on a production project that was near to me where the team went down a path with one particular framework, decided it was slowing them down and wanted to switch to another framework. And a lot of the code was so tightly coupled to the framework that it wasn't really portable and there was a lot of rewriting happening. I'm wondering if you composed your application based on these different libraries, is that better or worse for portability than building your app within one of these individual frameworks? CRAIG: You know, I can't speak from experience on that. But my gut tells me I would not want to be figuring out the migration path for three libraries. I would rather be figuring out the migration path for one library. I think none of the libraries really abstract themselves away from, you're committing to the library and you're going to have a rewrite if you switch libraries entirely. I can't imagine a scenario where that might be made easier. But maybe I'm just not being open-minded enough about it right now. JESSICA: If you are learning programming and you want to be a web developer and you want to be a really good web developer, your objective is not just to get this one site up and running but to really understand what's going on and learn how to do this well. Would you start with any of these frameworks or would you try to put it together from the ground up? CRAIG: I could take that one first. I'm sure everybody has an opinion on that. I think there are certain skills that are timeless and that those are the kinds of things I would focus on. I'm thinking writing SQL in general is a timeless thing, not that everybody does it. They have abstractions like Active Record and so forth, ORMs. But having that base knowledge there, JavaScript is in that camp I think. Knowing JavaScript as a language itself, knowing several server-side programming languages as a foundation, I think is a good thing to focus on that is never going to go away. There are other timeless things like regular expressions. No matter how much I want them to go away sometimes, I think there's skills like that. I think being new to web development, these kinds of timeless things are the things I would really focus on at first. AVDI: Let's move on past that and focus down a little bit and say, let's say somebody is at the point, wherever the point is, that they should be learning a JavaScript framework. They're at that point. Is there one of these frameworks where you would say, "Okay, you're a newbie. You don't have a job yet that's forcing you to use one particular framework. Here's the best one for you to learn"? CRAIG: Yeah, I kind of answered this on another interview I did. And I think what I came down to was Backbone is not a bad choice because it's so close to, let's say you're going to make that evolution as a web developer. You probably went from raw JavaScript to jQuery. And I think the next baby step to make that is not in any way throwaway, I don't think, because it's such a small leap is the Backbone world. I actually learned the frameworks in, I learned Angular then Backbone then Ember. And I wish I would have picked up Backbone first because it's hard to appreciate the kinds of things you're learning when they're done for you by a framework like Angular or Ember. AVDI: Yeah, that was one of the things that I picked up from reading your book, is that in the Backbone examples it felt like the guts were exposed a bit more. It felt a bit like deconstructionist building where you can see the ductwork and things like that more than the other examples. CRAIG: Definitely. It's a lot just to be, to hold no punches, it's a lot more code. And a lot of people know this who've really looked at the frameworks. But if you look at any code examples, it's just a lot more code in Backbone. But as far as a learning exercise, it's a very valuable thing, I think. JESSICA: That's really useful. Yeah, the frameworks like Angular, there's a lot of magic. There's a lot of code executing that you don't see. And when you don't invoke the spell correctly, figuring out what you did wrong is incredibly difficult. CRAIG: Indeed. CHUCK: Yeah. JESSICA: I know at my company, at Outpace we use Angular. And it was very painful until one of us who's a fantastic developer figured out how to find the pit of success within Angular, told everybody how to use it, and then it was much better. CRAIG: Yeah, sometimes I've been doing this for so long so I do forget how daunting it could be, this whole new world. But I think one thing I encourage people to do is there's one article, my blog, that's called the 'Anatomy of a JavaScript Framework'. It shows you the features that make up a JavaScript framework which we touched on briefly. But it shows you them in each one of these frameworks. So, you can see what just routing looks like, what it would be like to set up a simple website with two pages and do a route in each of the three frameworks. What does data binding look like in each of the frameworks? How much work does it take to get one-way data binding and two-way data binding to happen? What does, the other features, what does a model look like in each of these frameworks? And I think that's very important because the important thing if I was learning about this is the concept of what are these frameworks all trying to help you with? What are the jobs these frameworks are trying to help you with? Not the syntax that they're trying to help you with, but what is that job that they're all trying to, in what way are they trying to help you? What value are they trying to bring to you? And I can drop a link to that in the show notes. JESSICA: Great. Yeah, the why is always much harder than the how. CRAIG: Because once you see through the frameworks you start realizing that despite all this debate on the internet about how different these frameworks are, they're actually all trying to solve the same problems, right? So, they're not that different. They all have their, people prefer this one over that one. But it comes down to the same kind of differences that you see in a style guide or something. They're differences that may not be the end of the world. What's really important is do you get it? Do you get how the architectures of these new frameworks are trying to approach the problem? And why they're there, and that sort of thing. JESSICA: There's always a lot more arguing when both answers are correct. That's really useful. Thank you, Craig. CRAIG: Sure. Another thing people like to wonder about out loud is the React framework from Facebook. I didn't include it in the book, but about the time I published the book React was really gaining ground. So, I did write a blogpost about React and how it figures into all this. The website clearly advertises itself as: we are just the V in MVC. But they definitely have some novel different approaches to building applications. And at first it looks spaghetti-like. I'll just come out and say it. But performance-wise and complexity-wise, it can be refreshing to work in React in what little bit I have. I think one key difference is that they basically don't do data-binding. They just say, more like our traditional server-side frameworks do, there's just some data and we're going to bind it to the view. But we're not going try to do this two-way data binding thing. And this frees you from a lot of problems that can happen with some of these other frameworks. In particular, with Backbone there are a lot of events being thrown from component to component that can get quite confusing. What order are the events being thrown? Which ones, where is this event coming from? That sort of stuff. So, React is an interesting new technology to look at. I think particularly what validates it is I know that the Angular team for version 2.0 is seriously considering dropping two-way data binding. This is not a decision that they made by any stretch of the imagination. But it's something that's actually on the table, which if you've used Angular or Ember or so forth, this sounds kind of jarring. But it shows the influence that React has had on the web development paradigm and people are reconsidering, "Is this helping us or hurting us more?" that sort of consideration CHUCK: So, the other question that I see and hear discussions about is the full stack frameworks. And Avdi asked about this in the chat, too and then we moved on to something else. So, there's Meteor.js, there's comet.io, there's Volt, which is a Ruby Opal setup. What are the advantages of those versus some of the other ones? CRAIG: Right, so I'm just looking back through the notes here while you were talking. So you're saying, these more full stack frameworks, Meteor is the only one I'm really that familiar with. I can see that React is just the V. But now you see frameworks being built on top of React. CHUCK: Right. CRAIG: And I think that is a really interesting thing. But honestly, I have not caught up to that world yet. But I do think it's interesting because it clearly wasn't enough by itself. But the foundation was there, the performance foundation was there in React with their virtual DOM and so forth. As far as Meteor, people… I have very little experience with it. But my experience was an extremely productive experience in that when I worked on it, I played with all the other frameworks. And the amount of an app that I could build in the amount of time that I spent on it was, I was very productive basically. And I think it has to do with that full stack experience. I had a similar sort of experience with Ember considering that they actually have a little bit more of a data story, a little bit more of an ORM story where they have Ember Data even though it still continues to be in beta. A lot of people use it. And just having a story there for, it's like imagine Rails without Active Record. It's a decent amount of the story. So, that makes it be productive and so forth. So, when I look at these full stack frameworks like Meteor, I immediately found myself being more productive when I had a data story there, a story about communicating to the server that was integrated in persistence and so forth. Anybody else have experiences with these? CHUCK: I've played a little bit with Meteor, but not enough to comment on it. AVDI: I haven't actually played with them. The one thing that scares me off a little bit is that the ones that I know of, Meteor and the Ruby world Volt, they're both pretty, at least currently from what I understand they're both pretty tied to MongoDB. And I really like Postgres for a lot of reasons. And I like to know that my data is in Postgres or something, or at least I like to have options. Put it that way. I like to have options with my data backing. CRAIG: Right. AVDI: And so, that tight integration with the data backend gives me the willies a little bit. CRAIG: And I definitely had to draw the boundaries with the book, just to be clear on… and I drew the boundaries that if it's more of a full stack platform that's like these Meteors and so forth, I said I'm leaving them out. And Meteor was very young when I started to write the book. It's come a long way. I also drew the line at those three frameworks that actually have the most traction and so forth, even though there are plenty of other frameworks out there. Or there's nothing wrong with them. It's just half the battle I think, the community sometimes, just knowing… AVDI: Oh, absolutely. CRAIG: Knowing that something's there. One particular framework that I really liked was CanJS. I don't know if anybody's heard of that one. It used to be JavaScriptMVC back in its days when it was more tied to the jQuery world. It's by a consulting company in Chicago, Bitovy, that does a lot of JavaScript development. And so, they really have used this thing every day and a lot of people I heard saying good things about that. Durandal, you know I didn't really come back around to that Chuck, but clearly Durandal has some merits when the Angular team hires [chuckles] the guy away who wrote Durandal. CHUCK: Rob Eisenberg, yeah. CRAIG: Rob Eisenberg, to come on to their team. I think Rob Eisenberg has left the Angular team again. CHUCK: Yeah, he wrote a long blogpost about that, but yeah. CRAIG: But clearly there's some architectural merits to the Durandal framework, particularly the router is pretty robust. And he worked on the new router. The Durandal author worked on, Rob Eisenberg worked on the new router for AngularJS that is being ported back into 1.3. It is not there yet as we speak and will be available into the 2.0 version of the framework whenever it is released. And we've got mention on Om on top of React, right? ClojureScript. It's a never-ending list of… JESSICA: Right. We use ClojureScript using Om and React. And it is not for the faint of heart. CHUCK: Yeah, but Om is pretty cool. It's got that, how do I want to put it, it's got the immutable stuff going on. And it's also, just the way that it solves some of the problems, it's really unique. JESSICA: Right. It's got the one-direction data flow going on. CHUCK: Yeah. JESSICA: On top of React, as opposed to the two-way data binding, saying that [inaudible]. AVDI: Wait, so it writes pop songs? CRAIG: [Laughs] CHUCK: [Chuckles] JESSICA: There's a song about that? I'm so [inaudible]. AVDI: There's a boyband One Direction. JESSICA: Oh. Yeah, I think one of my kids have them on their toothbrush. [Laughter] CHUCK: Awesome. JESSICA: Right. CHUCK: Alright, well I think we're getting… JESSICA: [inaudible] with one-way data binding that says reading and writing are separate concerns. Don't conflate them. CHUCK: I think we're getting toward the end of our time. Is there anything else that we really ought to cover that we haven't talked about? JESSICA: Picks. CHUCK: Picks. CRAIG: Sounds good. CHUCK: Before we do that though, Craig how do people get your book? How do people find you? CRAIG: Yeah, so my blog is at FunnyAnt.com. That's funny A-N-T dot com. There are a lot of articles I wrote while working on the book for that period of time that are there as well you could check out. If you're interested in the book, the easiest way to get to it is I set up a page just for the Ruby listeners on here. And I've got a discount code out there for people. So, if this is something, a topic you're interested in learning more about, you feel like you got behind on all these JavaScript frameworks and what's a resource that's… I try to be open-minded about the merits of all these things, as we have in this conversation today. You can go to FunnyAnt.com/Ruby. And there's a 20% coupon there or discount off if you buy through that page that I'll leave up for 30 days or so when we publish the podcast here, when you guys publish the podcast. JESSICA: And it's not just a book, is it? There are videos and interviews. CRAIG: Yeah. I definitely was lucky to talk to a lot of different people who worked with different frameworks and to be able to interview them and talk about their experiences with each of the frameworks, talk about the data story. How do you talk to a database? I was lucky enough to talk to multiple people. So, Nathan Barry talked to me about single-page applications from a design perspective. Ari Lerner who wrote probably the most popular book on Angular to date, it's the ng-book. A lot of people are familiar with that one. He did a short interview for me. So, there are several different interviews. You can just get the book. It's 270 pages. I definitely put six or seven months of my life and focus into this. So, it's not something I wrote in the evenings while working. I definitely committed a lot of time to it. And so, I hope some people find it valuable out there. And so, that's pretty much it. So, FunnyAnt.com/Ruby. Or if it's been a couple of, a while, you can also go to JavaScriptFrameworkGuide.com if you can't… it's a little easier to remember. JESSICA: Awesome, thanks. This is totally material that the community has really needed. And we are indebted to you for taking those seven months to write it up so well. CRAIG: Thank you, thank you. I definitely tried to look at it from, I kind of get frustrated at times with people on the internet just making statements like I saw on that forum. I understand people get frustrated. But I like to hear concrete things about what it is about this that developer A doesn't like or developer B doesn't like. And I think there's really a dearth of people who've actually worked with all the frameworks and can compare the merits of them. CORALINE: Are you saying facts are more important than opinions? [Laughter] CRAIG: Nonsense, no. CHUCK: Alright. Avdi, do you have some picks for us? AVDI: Yes, yes I do. First off, I'll make a hardware pick here. I've been needing to replace my video editing machine for quite a while. I was using a pretty dated machine for it. And one day I jokingly posted on Twitter a set of impossible specs for the perfect video editing machine. I wanted something that was a laptop that was slim and light so I can just carry it around to coffee shops and stuff like that. But I also wanted it to have a really heavy-duty four physical core i7 processor and serious graphics card muscle and a touchscreen. And obviously this is not a thing that exists. But I posted it. So, Nick Gauthier replies to me, basically says, "Dude, that's the Razer Blade." So, I looked it up. And if you're not familiar, the Razer Blade is basically the gold standard in gaming laptops right now. It's the MacBook of gaming laptops. It actually looks a lot like a black MacBook. And I checked it out and sure enough it had everything that I had just listed including the touchscreen. The latest version has the touchscreen. CRAIG: [Chuckles] AVDI: Because that's the thing that Windows laptops do these days. And so, [chuckles] yeah, I was like, "Holy crap. That is actually the exact thing that I just described." So, Black Friday I ordered myself a new video editing machine. So, I actually have a gaming laptop that I have barely played any games at all on. I use it to edit videos and it's actually working out very well. So, I can at least provisionally recommend it. This is not a long-term review. But so far, the Razer Blade has worked out pretty well. Another pick for me is going to sound like something old and done. It is GTD. It is the Getting Things Done system. This is a system that I was introduced to years ago. I read the book by David Allen probably back around when it first came out. And now more recently I hadn't really been practicing any kind of GTD system. And in fact, I put a lot of energy into getting my life to the point where I didn't really need an organizational system where I could be disorganized and it wouldn't hurt things in any way. But various things came together to force me to need to be much more organized, at least for a period of time. And as a result, I realized that I was letting things slide and things were falling off the top of my head. And I really, really needed a system because of my newfound need for organization. And I was able to fall back on the stuff that I'd learned from GTD. And there are lots of organizational systems out there. It is one of them. It's no worse than any others and probably better than a lot of them. But the most important thing I think is just that it is a system. And if you're an engineer like me, it's always a temptation to, "Okay, I need a system. So, the first thing I need to do is to invent the system." [Chuckles] AVDI: And that leads nowhere good. So, just having the system and just doing it even if it's not perfectly optimal is really nice to have. And if you're going to just pick a system and do it and not think too hard about it, I think GTD's probably one of the better ones to do that with. So yeah, that really helped me out, having that to fall back on. JESSICA: Right, because these days we don't invent our own JavaScript frameworks. We google them and [inaudible]. [Laughter] AVDI: And okay, one little fun pick. I was reminded the other night of the movie Gross Pointe Blank. Somebody in the house had it on and I sat down and started watching it. And I was just reminded of what a well-written movie it is. It's a lot of fun. So, if by some chance you have not yet seen the movie Grosse Point Blank, I think it's on Netflix. Give it a watch. It's a lot of fun. And that's it for me. CHUCK: Awesome. Coraline, what are your picks? CORALINE: I've got a couple today. The first is a site called CodeMontage, CodeMontage.com. It's a site that was built by Vanessa Hurst and some of her team members who some of you may recognize as a cofounder of Girl Develop It. Basically, it's a site for connecting developers with open source projects that have a positive social impact. So, you register as a developer, put in what technologies you're interested in or competent with. And it's almost a dating service for finding open source projects that suit your technological and social good needs. The second pick I have is actually a conference talk called 'On the Outside Looking In' by Cindy Backman who works at ConFreaks.. And ConFreaks is a company that does video of a lot of different Ruby conferences. She attended 40 conferences in two years, there to videotape them. And she gave a talk on her experience and what she learned about the Ruby community as an outsider looking in. So, her talk was actually at Ruby Conf this year and it's a really interesting perspective on what our community is and how it all comes together based on different personalities involved in the community and the way we like to participate in the community, and the relationships we have with people who are very visible and also behind the scenes. So, I thought it was a great talk and it's definitely worth watching. CHUCK: Awesome. Jessica, what are your picks? JESSICA: I have two picks. One is a programming pick and it is optional typing. I'm writing Clojure these days and I have finally learned and started using Prismatic's Schema, which is, it's implemented so it looks like you're doing optional typing. Behind the scenes it's doing contract verification but only when you tell it to, so only in test. But it's beautiful. I can finally document the parameters and return values of my function, which as Stefik told us has been proven to improve developer productivity. I think optional typing has a lot going for it. It keeps you from having to write a whole bunch of types when you don't feel like it. But it lets you write them when they're useful for documentation and verify them. Oh man, it was so nice to have a test that's failing and I don't know why, turn on verification. Oh look, I passed the wrong thing into this function. Oh, it's so beautiful. Okay, so my second pick is a book. And it is Strunk and White's 'Elements of Style'. It is a tiny little book. It is an ancient book. It may have been your grammar textbook in elementary school but you've probably forgotten it. I know I have. It's a tiny little book with basically the rules of English grammar. But not just grammar, also good writing. And good writing is essential to doing any job well these days. So, I recommend it. It's like a quarter inch thick. And very small book, very useful. Get it, read it. You'll like it. The end. CHUCK: Awesome. I have one pick this week. And it is the talk given by Scott Hanselman. I posted it in the show notes earlier but I never actually got the chance to mention it. It's angle brackets and curly braces and he talks about the tradeoffs between frontend and backend work. And it's really good. And that's the only pick I have. I do want to point out, I think Ryan Florence said this, but he basically pointed out that these days you're either choosing a JavaScript framework or you're choosing to write your own. So, as your applications become more rich on the frontend or require more data management, you're either going to wind up building it yourself or you're going to wind up using something that helps you do it. So, just keep that in mind. Craig, what are your picks? CRAIG: Yeah, well I'm kind of in the startup community like Chuck is somewhat, or the bootstrapping startup community. So, my first pick is, a lot of people are familiar with Rob Walling from SoftwareByRob.com. But what I'm picking is his most recent SAS product is Drip. It's email marketing software. And I'm picking, he published the interviews. Basically he and the lead developer for the project recorded weekly or biweekly conversations every week. And then they edited them all down to about two hours and have published them online as a one-time podcast. And it's at StartupStoriesPodcast.com. And it's really worth a listen. It gives you insight into what it's like to really build a legitimate software as a service business and all the work and pain and hard decisions that are involved as you develop the product. So, I think that's great. Also going to pick, even though I believe he was just on the show, was John Sonmez on the show last week… CHUCK: Yes. CRAIG: Or the week before? I am currently reading 'The Software Developer's Life Manual' by John. I got an early copy of it. I actually paid for it, yes, as opposed to, he's giving a lot of them away free there for a while to get some good reviews. But it is definitely a good resource. So, if you haven't checked that out yet, check out 'The Software Developer's Life Manual'. I guess it's called 'Soft Skills' is the main title of the book. CHUCK: Yeah. CRAIG: It's very, very good. It's a lot of… CHUCK: It sold out on Amazon day one. CRAIG: Wow. I've definitely, a lot of the stuff I know but it's so well organized and it took me so long to get it. So, I wish this would have been there five years ago in my career or something like that. So, definitely worth a read. My last off the map pick here is last night I finally got a chance to check out the documentary called 'Time is Illmatic'. So, I'm a closet hip-hop fan from my youth. And if you google what is the best rap album ever, inevitably in the top ten there's an album by an artist named Nas that came out called Illmatic. It was actually his first album. And there's a documentary on the making of it that's been on Showtime lately. And you can get it on Amazon Prime and they'll reduce, I think the DVD comes out in a couple of months. But it is a really awesome watch if you're at all into hip-hop. And those are my picks. CHUCK: Very cool. I just want to remind everybody to go check out Craig's book. And if you can just give us the URL one more time so that people can get that discount. CRAIG: Sure, that's FunnyAnt.com/Ruby. CHUCK: Awesome. Alright, well thanks everyone for coming and we'll catch you all next week.[This episode is sponsored by WatchMeCode. Ruby and JavaScript go together like peanut butter and jelly. Have you been looking for regular high-quality video screencasts on building JavaScript done by someone who really understands JavaScript? Derick Bailey's videos cover many of the topics we talk about on JavaScript Jabber and Ruby Rogues and are up on the latest tools and tricks you'll need to write great JavaScript. He covers language fundamentals so there's plenty for everyone. Looking over the catalogue, I got really excited and can't wait to watch them all. Go check them out at RubyRogues.com/WatchMeCode.]**[This episode is sponsored by MadGlory. You've been building software for a long time and sometimes it's get a little overwhelming. Work piles up, hiring sucks, and it's hard to get projects out the door. Check out MadGlory. They're a small shop with experience shipping big products. They're smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter at MadGlory.]**[Hosting and bandwidth provided by the Blue Box Group. Check them out at Blubox.net.]**[Bandwidth for this segment is provided by CacheFly, the world's fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]**[Would you like to join a conversation with the Rogues and their guests? Want to support the show? We have a forum that allows you to join the conversation and support the show at the same time. You can sign up at RubyRogues.com/Parley.]
087 RR Book Club: Practical Object-Oriented Design in Ruby with Sandi Metz
131 RR How to Learn
124 JSJ The Origin of Javascript with Brendan Eich
Sep 3rd 2014
146 JSJ React with Christopher Chedeau and Jordan Walke
Automate the Pain Away
Get Ruby Rogues in your inbox
You are friggin' awesome!
JSJ 375: Are You Hurting the Web?
JSJ 374: CosmosDB with Steve Faulkner LIVE at Microsoft BUILD
EMx 060: Property-Based Testing, Dialyzer, & Inaka with Brujo Benavides
Join our newsletter and get updates in your inbox. We won't spam you and we respect your privacy.
Contribute to this site on Github
© 2019, Intentional Excellence Productions, LLC. All rights reserved


Walking in the old streets and alleys of Lijiang, the radiant stone roads, the voices of the murmurous stream, the wrinkles on the dark face of Naxi's old man engraved with the traces of the years, as if they had stopped for time, they were all quiet. Everywhere is peaceful... This property is located at the entrance of Lijiang Ancient Town. It is located at the entrance of Lijiang Old Town. It is 100 meters from Mufu and 50 meters from the entrance of the ancient city. It takes an 8-minute walk to reach Sifang Street and Dashuu. The style of the house is hand-painted and it integrates with Lijiang. Local customs: There are beautiful scenery of Lugu Lake, there are thousands of styles of the Mosuo girls, thousands of miles of snow and ice in the Yulong Snow Mountain, exotic customs of the Naxi people, and years of frost and rain in the ancient city of the millennium... Each room is designed A strong artistic atmosphere was revealed. In order to eliminate the fatigue of the guests during the trip, some house types in the houses are equipped with fully automatic massage chairs so that guests who are tired of the day can enjoy the relaxation brought by the massage after returning; in order to allow guests to enjoy the needs of watching movies, they can not go out. The inn designed a Philips 43-inch super smart TV, which can simultaneously watch 1,000 large-scale movies for free globally. The ultimate comfort experience has won recognition and praise from countless guests; in order to bring guests deep sleep, the hotel The use of star-rated mattresses is extremely comfortable and has been enjoyed by friends who have experienced it.


Brown boxy-fit leather jacket from Z Zegna featuring a ribbed collar, a front zip fastening, long sleeves, a ribbed hem and cuffs and two front pockets.
Black lambskin leather bomber jacket from Z Zegna featuring long sleeves, a ribbed hem and cuffs, a front zip fastening, side pockets and a lining.
Black and brown boxy-fit leather jacket from Martine Rose featuring a spread collar, an elasticated hem, patch pockets and button cuffs.
Blue wool slim fit jacket from Z Zegna featuring a v-neck, notched lapels, long sleeves and a front button fastening.
Black wool blend fitted bomber jacket from Z Zegna featuring a round neck, a zip fastening and two front pockets.
Brown and blue lambskin and cotton two-tone bomber jacket from Z Zegna featuring a ribbed collar, a front button fastening, long sleeves and a ribbed hem and cuffs.
Brown linen and cotton knee-length fitted shorts from Z Zegna featuring a button fastening, a knee length, a rear pocket and a slim fit.
Blue cotton hooded jacket from Z Zegna featuring a zip fastening and two front pockets.
Dark blue wool bomber jacket from Z Zegna featuring a ribbed stand up collar, a front zip fastening, side zipped pockets and striped trims.
Navy blue wool lightweight jacket from Z Zegna.
Black cargo denim jacket from Z Zegna.
Black nappa leather zipped bomber jacket from Z Zegna featuring a ribbed collar, a front zip fastening, long sleeves, side pockets, a ribbed hem and cuffs and a straight hem.
Black wool blend textured hooded jacket from Z Zegna featuring a zip fastening and two front pockets.
Grey cotton blend zipped hooded jacket from Z Zegna featuring long sleeves, side pockets, a ribbed hem and cuffs and a logo print to the rear.
Washed blue cotton blend casual hooded jacket from Z Zegna featuring a front zip fastening, a ribbed hem and cuffs, a relaxed fit and side slit pockets.
Dark blue cotton quilted bomber jacket from Z Zegna featuring a fabric mix, a ribbed hem and cuffs, a stand up collar, side zipped pockets, a front zip fastening and a contrasting grey trim.
Dark blue classic Technique jacket from Z Zegna.
Blue plain bomber jacket from Z Zegna featuring a high standing collar, a front zip fastening, side pockets, long sleeves and a ribbed hem and cuffs.
Black cotton hooded zipped jacket from Z Zegna featuring a hood, a front zip fastening, long sleeves, side pockets and a slim fit.
Black wool blend striped print jacket from Z Zegna featuring long sleeves and a button fastening.
Grey silk logo bomber jacket from Z Zegna featuring a band collar, long sleeves, side pockets, a ribbed hem and cuffs and a relaxed fit.


Since the age of 11.
A good hose and a great brush.
Where are your favourite locations to ride?.
UK in general, Cwmn Carn is only 35 minutes away.
Ridley custom built, and team issue Cube.
Use chain checkers on a regular basis to show and check wear.
I have been using the Weldtite chain degreaser for over a season, at events from Bike Radar, to Mountain Mayhem. The machine is very easy to use, and with a little practice, easy to fit. I have found the device works well on slightly soiled chains as a hands free device, but when working with heavily matted chains, it is worth holding the device as you turn the chain through.
I have had the park version of this tool sat in my tool box for around 10 years. I last used it when I was working on mass market bikes with wire beaded rims and it did the job perfectly.
I have used Dirtwash extensively for the last 6 months, prior to becoming one of your brand ambassadors. I have found that it works well on both road and mountain bikes, giving a fantastic finish and not leaving any smears or stickiness to the parts sprayed. I have found once used and then hosed off, using the silicon polish adds a smooth surface, keeping the bike cleaner for longer. I would strongly recommend Dirtwash to anyone, and it is the only cleaner I use when working on my bikes or any demo event.


Dongguan Daerxing Plastic Packaging Co., Ltd.
Foshan City Nanhai Nanrong Plastic Printing Co., Ltd.
Kazuo Beiyin Paper And Plastic Packing Co., Ltd.
Shenzhen Xuchen Package Product Co., Ltd.
And you need to do customs clearance at your side. Those are widely use at the gift packing, electronics product packing,powerbank packing,wine packing,sport product packing etc. Those are widely use at the gift packing, electronics product packing,power bank packing,wine packing,sport product packing etc.
Shenzhen Guangshunda Packaging Co., Ltd.
Shenzhen Luda Packaging Material Co., Ltd.
( Any size could be customized) Logo: Silk screening printing, emboss, hot stamping, embroidery, woven label, paper label etc. MOQ 300 pcs More Material Choose: Muslin Cotton, Jute, Burlap, Linen, Velvet, Satin, Polyester, Canvas,hessian , hemp , Non-woven etc. Q2: Where is your factory located9 How can I visit there9 A2: Our factory is located in Shenzhen City, Guangdong Province, China, about 1 hour from Shenzhen airport .
Shenzhen Yitong Packing Product Co., Ltd.
Talent (Xiamen) Industrial Co., Ltd.
Guangzhou Hair I Need Trading Co., Ltd.
Shenzhen Lion Packing Product Co., Ltd.
We have Silk screen printing; Embroidery; Embossing; Silver stamping; Gold stamping; Heat tranfer printing etc. 2. Can you send me a sample for check quality9 Re:Stock samples are free,shipping cost you collect. For more informations,pls do not hesitate to send inquiry to us, We will offer warm-hearted service to you.
Sampling time:3days 2. Samples charge: Need. 3. Good Service: We treat clients as friend. 4. Good Quality: We have strict quality control system .
Shandong Ziri Industry & Trade Co., Ltd.
2) Q: would you put my logo on the bag9 A:The logo print on the bag is no problem. l We have about 100 professional workers and strict inspection rule so we can guarantee the quality. We have various print method such as hot stamped,embossed,print,heat transfer and so on.
The specific issues can be negotiated, pls confirm the details with us before payment. 2)On Time Delivery On time is guaranteed through our standard process management system. 3)Quality Gurantee From RFQ to PI, from raw material to final products, from delivery to documents,every step are reviewed by our well trained quality control staff to make sure for your satisfaction.
Shenzhen Dazhan Gift Co., Ltd.
Qingdao Huasheng Print Co., Ltd.
Shanghai Chenhuan Industrial Co., Ltd.
Yiwu Huikai Packaging Co., Ltd.
Shenzhen Shengrui Package Product Co., Ltd.
Qingdao Tongchuang Evergreen International Trade Co., Ltd.
Alibaba.com offers 18,746 hair packaging bags products. About 14% of these are gift bags, 8% are packaging bags, and 6% are packaging boxes.
A wide variety of hair packaging bags options are available to you, such as zipper top, hand length handle, and shoulder length handle. You can also choose from laminated material, pet, and cotton. As well as from free samples, paid samples.
There are 18,767 hair packaging bags suppliers, mainly located in Asia. The top supplying countries are China (Mainland), Pakistan, and Hong Kong, which supply 99%, 1%, and 1% of hair packaging bags respectively.
Hair packaging bags products are most popular in North America, Western Europe, and South America.
You can ensure product safety by selecting from certified suppliers, including 1,641 with ISO9001, 1,439 with Other, and 253 with ISO14001 certification.