Yaogang Lian

Muffin Series 1: Introducing Muffin

Over the last few years a new trend in webapp development has emerged. A growing number of prominent webapps are now built upon client-side web frameworks, most notably Backbone.js and Ember.js, instead of server-side web frameworks such as Rails and Django. This trend is gaining momentum, as manifested through the fast-growing list of real-world projects built on Backbone.js.

There are many factors behind this shift. But the primary reason, in my opinion, is the recognition of JavaScript as a viable programming language for the Web. This recognition has broad ramifications — browser vendors poured resources into making JavaScript run ever faster, core JavaScript libraries such as jQuery are widely adopted, and client-side web frameworks sprang up to push the trend even further. All these advancements, in turn, strengthen and reaffirm JavaScript’s role as the workhorse for modern webapps.

However, tooling for creating the new generation of webapps is still severely lacking. Don’t get me wrong — there are a lot of options out there — but none solves the problem particularly well. Some tools add extra layers of complexity on top of the elegant but unopinionated Backbone.js, some try to mimic behaviors of server-side frameworks such as Rails, and others try to support a large variety of development workflows but end up not supporting any of them remarkably well.

Muffin is a tool that tries to solve this problem better. It is designed with a clear goal in mind — helping the developer be more productive without getting in the way. To this end, Muffin focuses on addressing a few key issues, such as the build process, module loading and package management, without adding extra layers of complexity on top of existing frameworks. It encourages a component-based approach to webapp development — building large, complex webapps from small, reusable components. It doesn’t try to cater to every project or every developer’s needs, but instead concentrates on perfecting a carefully-selected, highly-opinionated development process featuring CoffeeScript and Backbone.js. Finally, Muffin is self-contained, written in succinct yet readable CoffeeScript, and has significantly fewer lines of code than other tools.

History

Muffin started as an internal tool while I was working for Axonify. When I left the company, Axonify was kind enough to open source Muffin so that it can release its full potential in the wild.

In the early days Muffin was mostly a build tool — it compiles CoffeeScript into JavaScript while watching for file changes, supports live reload in the browser, and prepares files for production.

However, I believe Muffin can do much more than that. I think Muffin’s goal is to make it significantly easier to develop the new generation of highly interactive, real-time, client-side webapps, maybe even easier than creating a static website in the 1990s. I think this goal can be achieved with two parts: a solid core that focuses on key issues, and a vibrant ecosystem that extends Muffin’s capabilities.

The Core

A vibrant ecosystem cannot be built without a solid foundation. That’s why Muffin has a small but powerful core, which focuses on solving a few key issues pertaining to all client-side webapps.

Such issues include:

  • A development build process that supports file watching, live reload, debugging, etc.
  • A production build process that supports file concatenation, compression, cache busting, etc.
  • A module loader that supports asynchronous module loading, automatic dependency loading, etc.
  • A package management system that provides easy installation and updates of packages, including both modules and traditional scripts.
  • An automatic dependency management system that doesn’t require manual configuration.

It’s important to note that all these issues are highly correlated. For example, the build process can wrap a CommonJS module into an AMD-compatible module while automatically setting up module path and dependencies, thus significantly reducing the complexity of the module loader. Also, module dependencies can be automatically inferred from package dependencies or module content, thus eliminating the need for manual configuration.

The highly correlated nature of these issues suggests that it’s most ideal to let one tool handle all of them in an integrated manner. This would maximize the synergy among various pieces of the system — the build process, module loader, package management, dependency management — and make each piece considerably less complex. This would also give the developer a much better experience since he doesn’t need to hunt for several tools and constantly switch between them.

The Ecosystem

The ecosystem extends Muffin’s capabilities by providing plugins, components, themes and more. Some of these packages are Muffin-specific, for example, a Muffin plugin that compiles LESS into CSS.

However, the majority of packages in the ecosystem are small, reusable components that can be utilized by other package management systems as well. For example, Muffin’s logging support is provided by the muffin/Logger package, which is simply a CommonJS module that can be easily used with other package managers such as TJ Holowaychuk’s Component.

On the other hand, Muffin apps can also make use of lots of packages from other package management systems, as well as vanilla GitHub repositories. Muffin’s module loader and build process are capable of loading traditional scripts just as easily.

A Full-stack Workflow

By combining the powers of a solid core and a vibrant ecosystem, Muffin can provide a complete yet flexible workflow for developing the new generation of webapps. Muffin can provide valuable help to the developer at every step of the process, from project setup, data modeling, generating client models and views, creating server APIs, all the way to production deployment.

A common challenge for developing client-side webapps is that the developer still needs to set up a server stack, even just to test the simplest features. Running a dummy web server doesn’t really help — most data-driven webapps are completely unusable without a functional server API.

For a big company with deep pockets this may not seem like a problem at all — a dedicated server team implements the server APIs — but ask yourself this: why is webapp development still so damn hard that it requires TWO teams of developers? Rails already made web development significantly easier that a single developer can create a fully functional webapp in a weekend, so why are we going backwards with client-side webapps?

Luckily we can do better than that — I will explain the details in another post — now I just want to assure you that developing client-side webapps can be even faster and more fun than with Rails!

Muffin provides a full-stack workflow. The front-end is based on Backbone.js and CoffeeScript, while there are two preferred server stacks — Google App Engine and Node.js/MongDB. Of course you can use any other server stack if you like — one great benefit of building client-side webapps is that the front-end and back-end are completely decoupled — but Muffin could save you tons of time if you use one of these preferred server stacks.

For example, Muffin supports Rails-style generators that can automatically generate client models and views, as well as server models and RESTful APIs. You can have a fully functional prototype right away. This makes the development process much easier and faster. You can see even more benefits when you deploy the app to production — both Google App Engine and Node.js/MongDB stacks can save you lots of headache when it comes to scaling.

Recap

It’s worth reiterating that Muffin’s goal is to help the developer be more productive without getting in the way. By providing a solid core, a vibrant ecosystem, and a full-stack workflow, Muffin can help you build real-world client-side webapps in record time.

Yaogang Lian

An iOS, Mac and web developer. Focusing on building productivity and educational apps.