Why Aspen?

By Chad Whitacre
March 26, 2013
Full disclosure: I am the author of the Aspen web framework.

I started Aspen in 2006, and in 2012 I built a site with it called Gittip. People looking at Gittip are wondering what Aspen is all about, so I wrote this post to explain the history, the design philosophy, and the current status of Aspen from my perspective.

Ah, the heady days of Python web programming in the early aughts! Everyone had their own framework, with almost-forgotten names like Quixote, jonpy, and Spyce. Ian Bicking looked at ten of them in a web framework shootout at PyCon 2003. Back in those days Zope was the big player in the Python world, along with its wild child Plone. Then we started hearing rumblings about a web shop in Chicago with an attitude of its own and a killer project management app. Ruby on Rails dropped in 2004. Django followed in 2005, and by the end of 2006 Guido himself had pronounced Django the winner of the Python web wars.

My own contribution came comparatively late, in early 2006. When I presented at ChiPy in April, it was called httpy. By November, it was called Aspen. Django was all the buzz at PyCon that year. I button-holed Guido and pressed him to tell me why he thought raising Response objects was a bad idea. “It violates the principle that you should return from only one place,” he managed, before excusing himself. “I have to go. I don't want to miss Adrian's talk about Django.”

Then web 2.0 happened.

Then social networking happened.

Then mobile happened.

The whole time I couldn't shake Aspen. Like a ball and chain, or a dog on my ankle, I dragged it from one gig to the next. The Curse of Aspen.

Now here it is, 2013, and I've got this site called Gittip that is starting to see some traction. Gittip is implemented in Aspen, and naturally people are scratching their heads. Why use this quirky also-ran instead of Rails or Django?


Aspen has a design based on principle, whereas Rails and Django inherited a design pattern from the Java world that was never meant for web programming. This makes programming with Aspen much more rational.

The two principles to Aspen's design are:

  1. URLs map directly to the filesystem.
  2. Files are split into pages.

Everything in Aspen's architecture flows from these two principles.

The first principle is what keeps Aspen close to HTTP. The path is the primary mechanism for picking out a resource on an HTTP server, and, clearly, the path used in HTTP is derived from the paths used on filesystems. Therefore, using the filesystem for routing is the best way to go with the grain of HTTP. All other routing mechanisms—pattern matching, decorators, object traversal, etc.—all introduce friction between the application and HTTP. Question: How do you do URL routing in Django? Answer: Regular expressions. Now you've got, as they say, two problems. ;^)

Of course, non-filesystem-based routing mechanisms were developed for a reason, and that reason is that CGI and PHP landed us in a morass of unmaintainable spaghetti. By the late 1990s we were flailing, looking for anything that remotely resembled order and sanity. “HAS ANYONE EVER ORGANIZED ANY SOURCE CODE EVER BEFORE EVER!?!?!?” we cried. And Trygve Reenskaug calmly replied, “Sure, I invented this pattern called MVC at PARC back in the late 1970s. It's for desktop GUIs, but maybe check it out?” So we did. Sun introduced its so-called Model 2 architecture in 1998, and, in a 1999 article for JavaWorld.com entitled, “Understanding JavaServer Pages Model 2 architecture,” Govind Seshadri recognized it as an implementation of MVC:

In this article, I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.

The problem is that web servers are not desktop GUIs. Using MVC for server-side web programming is, to be honest, a kludge. Yes, it looks sane compared to spaghetti PHP, but that's not saying much. With Aspen I've tried to design an application architecture that is native to web programming.

With Aspen, URLs map directly to files called “simplates,” and these consist of one or more pages. In the simplest case, with one page, a simplate is served as a static file. When you add another page at the top of the file, then the first page is programming language syntax, and the second page is templating language syntax that can use the names from the first page. Simplates use the ASCII page break (^L) for page breaks.

program = "Aspen"


Greetings, {{ program }}!

Aspen's second principle, that files are split into pages, is what saves Aspen from the spaghetti mess of PHP. You can't arbitrarily mix code and content. You can only have code in the first page, and only content in the second page. Aspen brings code and content as close together as possible without mixing them. It steers you toward well-architected apps, without the friction that comes from fighting HTTP.


The past seven years of use have demonstrated that Aspen's principled approach works. From these two principles, we can derive all of the common use cases of modern web development:

The Aspen architecture is suited for a whole range of applications, from short-lived static file servers, to service layers and internal dashboards, to consumer-grade web applications. Furthermore, the Aspen architecture is language-agnostic. Versions of Aspen exist (with varying maturity) for Go, JavaScript, Ruby, and Python. There's no reason in principle that a single server process couldn't serve simplates that use different programming languages.


The biggest practical problem with simplates right now is tool support. Text editors, linters, code coverage tools, and the like don't know about simplates yet. We do have a Vim mode, but it's very young. I don't use it, actually. I find myself manually calling set filetype=html in simplates to switch from Python to HTML syntax highlighting. It might be necessary to adopt a simplate-specific file extension to make it easier to write and configure tools. Obviously the tool support is good enough that I and others are productive with Aspen. You can drop into the Python debugger directly from simplates, for example. If Node has shown us anything over the past few years, it's that we can build fairly robust ecosystems pretty quickly if we want to. Tool support for Aspen is occasionally a little frustrating, but I'm not too worried about it in the long run.

The biggest strategic challenge to Aspen I see is Meteor. Aspen optimizes for HTTP, Meteor abstracts away HTTP altogether. If Meteor falls short of its ambitious goal to be the next UNIX, I expect it to be because HTTP is too leaky of an abstraction. I'm also not sure that full-stack JavaScript will carry the day as solidly as Meteor seems to require. Other languages aren't dead yet! We shall see.

The current framework players aren't going anywhere soon either, of course. What if Rails or Django added filesystem dispatch as an optional routing mechanism? That'd be a huge win, in my book. Aspen has already inspired one new framework, Keystone. If the wider web programming community takes filesystem routing to heart in whatever form, I'll chalk that up as a success. In the mean time I'm seeing enough promise with Aspen on Gittip that I'm content to keep going with it.

Future Directions

So where is Aspen going? First, we're going to keep using it with Gittip. I want Gittip to be for Aspen what Basecamp was for Rails and LJW was for Django. If you want to see what a real Aspen app looks like, go look at the Gittip source. Maybe even clone it and send us a pull request. :)

Second, I really want to push Aspen in this multi-glot direction we've started in on. The Python version is obviously the most mature. Paul Jimenez has been helping me run that project for a couple years now. I started the Ruby and JavaScript ports during my first Ruby and Node meetups a few months ago. The Ruby version is still waiting for the right person to come along and own it. The JavaScript version has seen greatly cleaned up by Fabian Faßbender, however, and the Go port from Dan Buch is more than a bare hack. What we really need to do is write up a language-agnostic definition of Aspen, and then we can revisit the aspen.io website and discuss each language implementation in context.

If you want to give Aspen a try, then your best bet is to download the Python version from aspen.io (the other versions aren't actually published there yet!) and go through the Quick Start. If you want to contact me or get involved with Aspen, the place to start is Twitter (@whit537), or the #aspen channel on Freenode.

Thanks! :)