[Discussion] The future of Ghost's admin UI #2144
This discussion is driven by a number of problems that are present in the existing implementation. Any discussion around solutions needs to carefully to consider all the problems that we face in the admin:
Discussion point 1: What other problems does the admin suffer from? Can you help us better quantify any of these problems?
It would be great to develop a set of principles / statements that need to be true for any new solution like:
Do you have examples of bits of the admin UI that you think are particularly dire? Are their problems you anticipate we might have if we moved from Backbone? Etc..
Discussion point 2: What is the best structure for a complex client side app like this?
This sort of depends on the tool used to build it, but also has implications for choosing a tool.
Is the Ghost admin a single page app, or a collection of single page apps? If you take the dashboard into consideration, I believe that alone is a single page app. The editor is probably the same.
Do you have ideas on how to structure the admin UI, and how to ensure it works as a whole?
Discussion point 3: Is backbone the best framework for the job?
There are many other potential tools we could use, and there are a few main solutions that we consider to be on the table:
Do you have some relevant experience with one of these solutions that you can tell us about? Are you able to put together a code example or demo that shows what it might look like, or specifically how a problem is solved?
Do you have time to implement a more complete demo / example of one of the key features, like the editor, or the post-settings menu?
Discussions on topics like these can be hard to keep objective, so I'm going to lay out some ground rules. Comments on this issue should contribute something of real value to one of the above discussion points:
Please do not post subjective comments suggesting which is your preferred framework, and although we all know the hamster IS a valid reason to choose ember, please keep those sorts of comments to IRC (please)! I have the power to delete comments, and for this thread, I may make use of it without warning
This is a call to action for our community, a place to come to put your thoughts, ideas, examples and other contributions. We will then use one of the public development meetings to discuss this further and come up with a decision. I propose that we aim for the meeting on Tuesday 25th February.
update: moved back from 18th to 25th
The text was updated successfully, but these errors were encountered:
Read an interesting article comparing the three frameworks yesterday. Gives an even handed survey while still giving an opinion based on what you're trying to build. I'm interested in what other people think about it.
I think you've named most of them. I think the problem is a lack of clear guidance on what client side developers should be doing and organizing their code; which is exacerbated by not having a more opinionated underlying framework.
But, to be more specific to the two items you mentioned; if we stick with Backbone (more opinion on that later) we should use Stickit for binding and our routing can be refactored to instantiate "controllers" to handle navigating from/to same pages on a controller and to other controllers. I really like Chaplins implementation of a router, but Marionette looks to do about the same type of thing.
I think the best structure is a client side single page app (more like a collection of single page apps like you say, except no refresh between apps) with fine grained modular code using something like requirejs or es6 loaders that will let you dynamically require code as you go between the different areas of the site. The admin side doesn't have to worry about SEO concerns and the requireJS optimizer can build a first page bundled script to keep initial page loading fast. Combined with something like rendr you can get a great fast loading experience with the snappiness of a single page app.
I think Backbone is not a framework, when using Backbone you have to build a framework from the primitives it provides. This can be powerful or a burden and it mostly comes down to how much control you care to have.
I help build a large web app by most standards at Sprout Social (150 files and most having thousands of lines of code). We use raw Backbone and I feel like we've been through the full life cycle with it. We started out just using primitives and writing a lot of boilerplate code over and over, then we started doing the standard abstractions like TemplateView and CollectionView and now we're starting to really build a framework that is customized for our app and it's getting to be great. But, it took a long time to get there and we still have a lot of old code that is not converted left in our wake.
Like I said earlier, I think we've just not been confident enough to tell people what the app should be structured like and what patterns we should be using. We're probably going to have that same problem with other frameworks we choose unless we nail that kinda stuff down.
I think Ember is a good choice for Ghost because it's opinionated
I've done a fair bit of research on the topic in the past and while subjective, I'd say It's a choice between AngularJS/Backbone, if for no other reason than market penetration and popularity. Ember has been around for quite some time, and last year finally became somewhat stable, but from what I can tell, doesn't really have anything unique or unusual that wouldn't be easily done with another system.
Backlift.com has an interesting poll of some startup companies and what they're doing for the frontend dev work. The summary is Backbone is king, with AngularJS a fast growing but far second.
In terms of actual library size, Ember looks to be the largest, most feature rich of the pack and comes in at roughly twice the size of Angular, which again seems off to me as I'm not seeing where the added size adds much in the way of functionality. Perhaps I'm missing something?
After some further research, I found an AngularJS vs Ember article from an Ember dev pretty much slamming Angular and while the article itself is too biased to be worth much, The Reddit discussion is very enlightening. I'd like to point out comments by SubStack and davemo as being particularly useful.
I don't think there's a winner, but I see two real choices.
I'm leaving Ember out of this list as honestly I'm not seeing what it brings to the table. It's a monolithic system that has been around for three years without major uptake, looks to be the largest system under discussion and doesn't really seem to excel anywhere. Again, Please note that I have not used it and this opinion is purely from digging through their docs, blog articles and a handful of projects using it, so I may be missing something important, but as it stands I really don't see this as a strong option.
There's also a rather dated but still probably relevant Backbone vs AngularJS article that should be considered. Basically the argument is Backbone is larger than Angular once you're done adding additional plugins and systems to fill the gaps you need. Which is something to remember, if not obsess over.
It's also worth noting that I'm a slight Angular fanboy, but at the end of the day I think Backbone with a databinding system or possibly Marionette would serve Ghost better in both the short and long term.
Hopefully this is at least some useful food for thought. If It's helpful, I'll see about digging up info about what other major projects/sites use since that seems highly relevant to the discussion.
I get the hype around Angular because it is easier to get started with than ember.js and that is thus easier to hack something working together more quickly. But I honestly believe that this is not an advantage for an ambitious open source project. Also I get the notion that Angular like Backbone is not a complete framework. They even state that on their homepage:
That also may be great for a smaller project where you need to get started quickly and include some stuff that you are already accustomed to but Ghost ist not a small project.
All of the problems @ErisDS mentions in the initial posting of this issue are easily manageable with an Ember.js-codebase and are solved by the framework itself without the need for workarounds.
Plus Ember.js has very good abstractions around important parts of web-applications so it's easy to change/extend one part of the app without breaking the whole application.
Also I guess it may be important to the core team that new contributors can join the project easily and be productive pretty quickly. That is where convention over configuration shines. Everyone familiar with Ember.js could easily grasp the code and contribute in a meaningful way right from the start.
Of course there might be some people that know a lot about angular and how to build up a big application with it. But can the core team guarantee that these people will contribute code to the project till the end of the lifetime of the project when they started on an angular code base for ghost?
Especially in open source there might be times where some people have the time and passion to contribute to a great project like ghost and after some time leave the project because of multiple reasons (a new job, children, a new relationship etc.).
If the ghost core is build around conventions over configuration it will be much easier to compensate the loss of an experienced contributor than in a situation where a small number of people built up a framework with a toolset for building a web application development framework, contributed code and then left the project.
That is also I think the reason why a lot of big projects are built upon ember.js already. There are some examples of bigger open source projects that are already using ember (for example Discouse and TravisCI) and a lot of big companies are also using Ember on their important projects (Zendesk, Square, Bustle, NbcNews, Runtastic).
I have not heard about a big angular project. That my be my own fault but I don't think Google is even using it on their apps?!
Again, I get why Angular is popular. It seems to be easier to get started with than Ember. But the learning curve is only one decision criterion. Also this is not an issue if you have got some people around that already know ember. Also google trends also may not reflect the whole story about popularity.
I encourage the ghost core team to use ember.js. And I would be happy to help porting the admin ui to Ember
I've been using AngularJS for about a year on a reasonably sized product (feature wise) and I've had no issues with it. The databinding is great, you can test everything due to dependency injection, directives encourage components and there's a reasonable community. Google do appear to be using it too http://builtwith.angularjs.org
Ultimately though any of the frameworks will do the job, one way or the other, so in the end it comes down to a personal preference...
Just wanted to say thank you to everyone who has contributed so far - this is excellent and exactly what we need. Please continue
To add a few points to what has been said:
I personally have started to play around with ember, and intend to do the same with angular and backbone, having a go at recreating key bits of Ghost and seeing how the solution fits. However, I'm very keen to see this also done by others and particularly people who are experienced with each solution.
To give some background before I jump in:
I sadly have had no experience with EmberJS so I am unable to give a completely rounded impression of which of these three frameworks would be most suitable for Ghost.
That being said let me talk as to the strengths of AngularJS and how it could benefit Ghost.
AngularJS has made sure that all of its code is testable. It's a priority that is clearly visible through the tools that currently exist to test AngularJS code.
Each type of testing is available with AngularJS: unit and e2e. Because AngularJS makes use of Dependency Injection, all of these tests are easy to mock up. Creating a unit test for AngularJs is is straightforward and similar to our backend tests. That harmony is advantageous.
You can also unit test test code that modifies the DOM. For example being able to unit test code that is responsible for creating modals would be very nice.
Encourages modular design
To understand directives it's important to understand that a main aspect of AngularJS is its HTML compiler. It's how it accomplishes 2-way data binding and how it knows how to amend the DOM according to your code.
A directive is allows you to extend the functionality of AngularJS HTML compiler. In a directive you can give the compiler knowledge of the
Due to directives just looking like HTML it enables greater involvement from folks who would otherwise be put off by mucking with templates.
There are five key parts of AngularJS, which when learned everything is built on them. I have actually already written an article about these five components on my blog if you'd like to delve a little deeper.
Past those 5 components all APIs that exist are ones you create, allowing everything to be domain specific to Ghost.
Browsing EmberJS it seems that its API footprint is large, requiring more blunt memorization of what does what. However EmberJS does go for naming what is most intuitive (similar to Rails) however it's close to impossible for one's intuition to be the same as everyones.
This is absolutely a result of the un-opinionated nature of BackboneJS - which is by design.
AngularJS doesn't truly have an opinion of how you should organize your code. AngularJS doesn't really approach large-scale application design from a top down view, i.e. here's a page, here's a controller, here's a view, here's a sub-view, sub-controlle etc. It mostly deals with one controller to a page and each page that requires more advanced behavior is comprised of directives.
EmberJS is absolutely the most opinionated of all three options discussed.
In my opinion Ghost is a client-side application that is always entirely rendered in the browser. It supports routes so that you can reach aspects of the application directly.
On every page of the admin the server should return the same initial HTML structure. After it reaches the browser it'll inspect what the URL is and depending on the route will render itself.
This is what AngularJS and Ember recommend and are built to do.
Unclear what you meant exactly by smaller here @jgable but I'm going to focus on just raw sizes of the library.
I've done this estimation many times in the past as the answer always surprised me. Not going to delve into specifics here, welcome to do your own napkin calculations as well.
EmberJS has always clocked in as the largest library in terms of raw KB. EmberJS depends on jQuery and Handlebars. If you're using Ember Data then that as well.
Backbone.js depends on jQuery and underscore.js. Depending on if you use Handlebars or Mustache.js that size is also included.
AngularJS has no dependencies. You can optionally include jQuery if you desire, but to get an AngularJS application running all you need is one file.
Still, it's something to be aware of.
Of particular note is that AngularJS powers DoubleClick Campaign Manager, part of their ads product, their biggest money maker.
A clear stamp of approval and adoption from Google.
Hopefully I've been as informative as possible while not being inflammatory.
It seems that Ember's opinionated approach will help with a larger group of contributors... However AngularJs encourages code reuse and modularity that is critical for collaboration. Also, you will be able to re-use code if / when building native mobile apps. Here are some interesting articles that may help:
Full disclosure: I don't currently use Ghost (mostly because I also don't blog) and am a Ember.js core team member. Although I'm on Ember.js's core team, don't think I'm not also a huge fan of other tools and frameworks: I've used Backbone, Angular, and Ember in anger and play around with React.js quite a bit. Based on that @jgable asked me to come weigh in on the discussion.
Having built stuff in all three, I totally agree with @jgable:
and his assertion that
Backbone is not an application framework. Every Backbone app I've worked has only been a
Sprout Social took this route. Most of the apps at my job (Groupon) have taken this route. Making this decision has one of two outcomes: you end up with a codebase that is totally unstructured and patternless but maybe bound together by a beefed up routing layer or you eventually build a custom, internal framework that you now need to document and provide training for.
If the pain you're feeling with the admin UI is really a lack of proscribed structure, I don't think this will ease your woes.
A better option, if you want to stick with Backbone, is adopting a tool like marionette or chaplin. But, given the number of times community size/adoption has come up in this discussion, that's probably a poor fit too. You won't really be building "a Backbone application" anymore, you'll be building a Chaplin, etc application – Chaplin even let's you drop Backbone as a dependency – and the community of those developers is much smaller than the superset of Backbone developers.
Angular.js is also great a great tool, but will suffer from some of the same problems you might experience with Backbone. Angular itself is not an application framework: it's an HTML compiler (hence terms like "directives" and "transclusion").
Like @hswolff noted:
If your problem is lack of application structure Angular doesn't provide tools to help resolve this. That's still all up to you.
This is also why Angular has a larger community than Ember: it's a lower-level tool and can be applied to more styles of development. The best pattern I've found for Angular is the mix of client/server rendering that you currently use. Serve a page whose HTML is an
Managing long-running, wide/deep view hierarchy apps with Angular still requires custom application structure code.
Addressing some of the Ember.js-specific comments in this discussion:
Don't mistake large or proscriptive for monolithic. Ember is made up of a bunch of smaller libraries that people use standalone and some external dependencies:
There are a sizable number of deployed, large production apps built on Ember from major and minor companies. Just some ones from well known companies:
We hit 1.0 in August 2013, use SemVer, and have a Chrome-style release cycle. So we've had five point releases with lots of bug fixes and new features without breaking backwards compatibility. Both Backbone and Angular have had post 1.0 breaking changes (granted: they've been small).
Not sure how much more stability you can ask for.
Functionality Ember uniquely offers for doing browser applications that you probably won't find elsewhere all in one package:
So, should Ghost use Ember as a framework for the admin backend? Not sure. I just don't have sufficient domain expertise with both to say, but it sounds like Ember is designed to specifically address many of the pains you're feeling building a larger app.
If someone with more Ghost chops wants to pair on a spike, I'm happy to make time (or connect you with someone) and generate real data to help make the best decision.
Terrific comment @trek, really appreciate the insight.
The stark contrast that I seem to see between Angular and Ember is the nature in which the application is conceptualized. Please correct me if I'm wrong.
In Ember the application, for example the Ghost admin, is built as one whole, as everything that occurs inside of it is part of the Ghost admin. The application runtime is designed from the top down. When visiting a page the code path begins in a route, which passes a model to the controller, which then constructs the view and wires up the page.
In contrast AngularJS applications also have routes and controllers and views yet the emphasis is not there (although those are handsomely used). AngularJS encourages through it's directives to break up your application into smaller components where the functionality and behavior are isolated and specific to that area.
Those are, in broad strokes, the conceptual difference in approach between AngularJS and Ember, as I understand it.
Both allow for building massive and complex client-side applications, yet the approach to arrive at that product is different.
Two additional notes:
I'm aware that Ember.Component is designed to allow you to perform similar functionality as an AngularJS directive, however from what I've seen does not seem to be as big of a focus for an Ember application as a directive is in an AngularJS application.
AngularJS is starting to address this issue via giving guidance on best practices. They wrote a blog post yesterday where they shared a document titled Best Practice Recommendations for Angular App Structure.
Ember provides behaviors for both top-down application organization (the routing, controller, data fetching stuff) and the bottom-up view organization (components). Both are a big focus of the framework.
Directives are a bigger focus in Angular that components are in Ember because Angular doesn't intend to solve these for you. Angular – and React.js for the curious – are both view layer libraries. Layers above and below are left up to the developer.
These both help you structure the files in a project, not the code. Not dismissing this – file organization arguments are the purest form of bike shedding – but this isn't the application structure I was suggesting Ember.js provides.
Although there is a file organization pattern that has emerged in the community (projects like Ember App Kit ) Ember doesn't care how your files are grouped or pulled into the final application.
Ember's application structure answers the "where, in code/flow control, does behavior X belong?"
This is helpful for two reasons: a) you can easily identify when an incoming PR has behavior in the wrong place b) anyone who knows Ember will understand the structure of your application letting them go directly to where they'd like to add or change behavior.
Even with a common file organization pattern, you'll still need to decide how flow control works at layers higher and lower than the view layer patterns Angular provides. You'll have to answer the question "Where does behavior X go? How does it interact with other behaviors?" Answer these and eventually you build a custom framework specific to your needs that uses Angular for views. Committers will need to learn this framework before being able to participate smoothly.
Obviously, if you went with Ember, they'd also need to learn Ember before being able to participate smoothly. There's a whole ecosystem of resources already made to help with that.
One thing I value about any open source project is the community that participates in the life of the project. In addition to evaluation of framework/library features... I would suggest connecting with the communities that support the framework/library. People are far from perfect, but its great when you find a community that is very supportive as well as produces quality software. I have not tried Angular, but can speak for those who use Ember on a day-to-day basis. The support from other developers in the Ember.js community is pretty darn good, and there are many active Ember.js meetups.
I've snagged four passes to Code School's Ember.js course for any Ghost developers who haven't used Ember.js and would like to evaluate it. I'm holding one for @ErisDS if she wants it and will pass the other three onto the whoever replies here first asking for them.
Only prerequisite is at least one Ghost.js commit.
I follow Trek on Twitter and his comment of "if you have something to add, chime in" pulled me in.
The general problem with Backbone apps is what I call the idempotent update problem. Backbone works great when you can get the change event, call
Switching your view layer to React solves the idempotent update problem. By rendering the entire template into a virtual dom, diffing the virtual dom against the actual dom, and applying the minimal set of changes, React actually delivers on the promise of the Backbone change pattern. While I have not used Backbone in years, I believe the transition would be the easiest for your codebase and there are quite a few blog posts chronicling successful transitions from Backbone to React. Many include glue code samples.
I believe that the key to building large client side apps lies in controlling your application state.
Angular provides two way data binding to solve the state coordination problem and correctly designed directives allow you to fully isolate your app model from the dom to achieve state control and the reasoning/testing benefits that go with it.
Ember provides the same benefits but as a framework, comes with proscriptions on how to use those pieces. This makes it easier for people to achieve state control (it's easy to NOT attain state control in angular) at the cost of having to buy-in to the framework, which makes transitioning into Ember harder. Both Angular and Ember have comparable complexity with different learning curves (early hump with ember vs the cliff wall of angular directives) and any large project WILL have an implementation of all of Ember's pieces.
Ultimately, any of these will probably work for you. The most important feature is getting ALL your application state out of the dom and solving dom/model state coordination. I mostly felt compelled to post because I'm a fan of Ghost, nobody's made a case for react, and I think it's likely to be your easiest transition. FWIW, I generally use Angular for new projects I'm working on because non-directive angular is super easy for designers and I don't mind dealing with the complexity of directives.
Co-Founder of Discourse here and author of one of the most popular Angular vs Ember articles on the web (called "too biased to be worth much" in this very topic!
It warms my heart that you guys are taking the time to consider such a large decision for your admin section and are discussing it publicly.
Discourse has had a lot of success with Ember, and I would love to see another large open source project use it so we can trade code and grow in the ecosystem together. Having said that, the really important thing is that you impose structure on your codebase.
It's been mentioned above that Ember is more opinionated than Angular, and I'd like to echo that sentiment. I keep asking Angular developers I respect, if you were to go to another company and open up your IDE on their Angular project, would you know how the code is organized? They always respond "no."
That's not to say Angular projects can't be organized and well designed with established conventions, it's that you have to roll it yourself. And some developers like that!
If you have a particular structure in mind you'd like to establish and enforce, Angular might be for you. If you want to work with a pre-established and battle tested structure, Ember might be for you.
One final thought about popularity. It is undeniable that Angular is more popular than Ember in terms of search engine traffic and such. But two points about that:
I am giving an "Ember Intro and Concepts" talk at the stahlstadt.js meetup in Linz on February 19. I will try to implement a short demo using Ember for the ghost editor and use it as code example for the talk. I will post a link to the repo when done. @sebgie and @JohnONolan feel free to join us again at the meetup!
Thank you to everyone who has come here to add something to this discussion
It seems to me we have reached a point where the conversation has become about angular vs ember, and backbone has fallen into a clear 3rd place - although nothing is certain yet ;) It does seem that our community is keen to take a leap and try something new and that is exciting to hear. React.js has been mentioned to me a couple of times, and I do believe it is worth consideration.
I am not sure how much weight a particular library's popularity or marketshare/adoption should impact our decision. The question on my mind is, if we switch to ember / angular / react are Ghost's contributors going to be onboard with the change? From the reactions so far, it seems everyone is keeping an open mind about getting behind whatever solution we determine is best, which I feel is really wonderful. Even more interestingly, by switching, will we find more people getting involved? I have to say I have been impressed with the contributions and keenness I've seen from people active in the emberjs community.
I have one lingering question / issue that I didn't mention in the initial post, which is the fact that currently a couple of our handlebars helpers are duplicated server and client side. As Ghost develops, that body of code will get larger, and so looking at ways that code can be shared might ought to be considered as part of this discussion.
Moving forward, I think this discussion warrants a little more time and discussion, so I think we are probably looking at the 25th Feb meeting, rather than this week. Largely this is to give us time to try out each of the frameworks. I think running some spikes would be very worthwhile at this stage - I have raised one for all 4 of the solutions mentioned:
I will try to make time to personally try out each potential solution before we have a meeting to make sure I can guide the discussion appropriately.
the (in)famous ng-embereño: comparison of ember and angular -> https://docs.google.com/presentation/d/1e0z1pT9JuEh8G5DOtib6XFDHK0GUFtrZrU3IfxJynaA/preview#slide=id.p
Apologies for speaking out of turn. But for one thing, a rewrite in React will gain you more support from the OSS community. But you'll need to be ready for a barrage of support issues from n00bs, and potential artchiectural slips due to relative inexperience in the React community.
@zeppelin is that a rethorical question? Or are you just being defensive? In my opinion Ghost, with the funding received, should have been much further along by now. No offense, but I've seen unfunded open source projects with more forward momentum. Not to discredit Erin's work, but Ember was the wrong choice.
@jhabdas I think Ghost has been running for a while now on Ember and have had no problems with it, why switch to something else if what they have is already working? Plus this is a closed case, they have chosen, I don't think they will change unless they find a limitation in what they have chosen.
Argumentum ad Ignorantiam. If it's not broke don't fix it isn't valid. And two- going on three-year old decisions don't cut it in the development world, which demands continuous improvement in the face of illegitimacy. Given that point, I'm not a stakeholder. Just here to drop some candid feedback. Sometimes the fastest way forward requires taking two steps back.
Oops... pressed send to early.
I'm assuming feature pairity would be a minimum requirement. There are no guaranteees that the PR would be accepted however because Ghost team knows Ember already. They'd need to learn a new tool because you think that it would attract more contributors.
All in all, Ghost team made a pragmatic decision 2 years ago that resulted in a good app that's maintainable and the team seems to be happy with it. Pragmatic decision at this point seems to be to keep what exists and works.
I hope you understand that not every team is bound by the same endless urge to rewrite their working applications in latest popular tech.
I am locking this down. I'm surprised and disappointed at this conversation - this is a 2 year old issue, which was until now, a stand out example of open source in action. There were 100 comments, all written with great depth and care, which helped us to overcome a major challenge in our growth and capabilities.
I didn't open my inbox this morning because I was busy planning a talk - in which the awesome work done in this issue and since feature heavily. I will be exercising my power to delete non constructive comments. If anyone wants to talk about this further, you're welcome to join our slack channel.
I had a response to this half-typed before I had to take a phone call. I'm not going to add a great deal here now, but I do want to clarify why Hannah was 100% right to lock this issue:
@jhabdas you, specifically, were being a dick.
There are multiple people here who are huge fans of React, myself included. There was nothing wrong with the content of your argument. But the second you started shitting on our momentum, accusing people of obtuse logical fallacies, and spouting meaningless drivel such as "If you're running a serious open source project" -- you lost all credibility.
Try being friendly and respectful next time instead of arrogant and dismissive. It doesn't matter how good of an engineer you are if nobody wants to work with you.
All of this is also covered in our (extremely liberal) code of conduct.