diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 77629ef9f37f599fd58150b92482f60e0a589d12..cac081f60345b661aa76bacac878c493e1ad3b59 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -41,16 +41,16 @@
     - unless @landing_page
       = include_javascripts :main
       :javascript
+        App.user({
+          current_user: #{current_user.person.as_api_response(:backbone).to_json}
+        });
+
         Diaspora.I18n.loadLocale(#{get_javascript_strings_for(I18n.locale).to_json}, "#{I18n.locale}");
         Diaspora.Page = "#{params[:controller].camelcase}#{params[:action].camelcase}";
 
-    - if @backbone
-      :javascript
-        window.useBackbone = true;
-
     = yield(:head)
 
-    -unless Rails.env == "production" 
+    -unless Rails.env == "production"
       :css
         .translation_missing {
           color: purple;
@@ -60,8 +60,7 @@
     - if @person
       %link{:rel => "alternate", :href => "#{@person.public_url}.atom", :type => "application/atom+xml", :title => "#{t('.public_feed', :name => @person.name)}"}
 
-  - metadata = user_signed_in? ? CGI::escape({:current_user => current_user.person.as_api_response(:backbone)}.to_json) : ""
-  %body{:class => "#{yield(:body_class)}", 'data-current-user-metadata' => metadata }
+  %body{:class => "#{yield(:body_class)}"}
 
     - unless @page == :logged_out
       - flash.each do |name, msg|
diff --git a/config/assets.yml b/config/assets.yml
index 57f9ec65e8801753cb8c729f433ce03f46ad8a0c..1ea2c607b814b213535edfed362a70e454f79777 100644
--- a/config/assets.yml
+++ b/config/assets.yml
@@ -20,6 +20,9 @@ javascripts:
     - public/javascripts/collections/*
     - public/javascripts/views/*
 
+    - public/javascripts/routers/stream.js
+    - public/javascripts/routers/*
+
     - public/javascripts/rails.validations.js
     - public/javascripts/rails.js
     - public/javascripts/vendor/jquery.hotkeys.js
diff --git a/public/javascripts/app.js b/public/javascripts/app.js
index d5f3b767b4f8bed90e425c2071d813eb029aeac6..2d01dbef03dafd260dcdc88ffa84a2e95a23b983 100644
--- a/public/javascripts/app.js
+++ b/public/javascripts/app.js
@@ -1,9 +1,25 @@
 var App = {
   Collections: {},
   Models: {},
+  routers: {},
+  Routers: {},
   Views: {},
 
-  currentUser: function() {
-    return $.parseJSON(unescape($("body").data("current-user-metadata")));
+  user: function(user) {
+    if(user) { return this._user = user; }
+
+    return this._user;
+  },
+
+  initialize: function() {
+    _.each(App.Routers, function(Router, name) {
+      App.routers[name] = new Router;
+    });
+
+    Backbone.history.start({pushState: true});
   }
+
+
 };
+
+$(function() { App.initialize(); });
diff --git a/public/javascripts/collections/stream.js b/public/javascripts/collections/stream.js
index 4a2534cafa09f0c0ffbe11869d923987c92a7ceb..6f8e22be1bab0a33277b4e2365e7a2d5d4115a04 100644
--- a/public/javascripts/collections/stream.js
+++ b/public/javascripts/collections/stream.js
@@ -1,13 +1,10 @@
 App.Collections.Stream = Backbone.Collection.extend({
   url: function() {
-    var path = document.location.pathname;
+    var path = document.location.pathname + ".json";
 
-    if(this.models.length) {
-      return path + ".json?max_time=" + _.last(this.models).intTime();
-    }
-    else {
-      return path + ".json";
-    }
+    if(this.models.length) { path += "?max_time=" + _.last(this.models).intTime(); }
+
+    return path;
   },
 
   model: App.Models.Post,
diff --git a/public/javascripts/routers/comment-stream.js b/public/javascripts/routers/comment-stream.js
new file mode 100644
index 0000000000000000000000000000000000000000..adac3d891179e6c8717b5b3594bd3b5d50697231
--- /dev/null
+++ b/public/javascripts/routers/comment-stream.js
@@ -0,0 +1,5 @@
+App.Routers.CommentStream = App.Routers.Stream.extend({
+  routes: {
+    "comment_stream": "stream"
+  }
+});
diff --git a/public/javascripts/routers/mentions.js b/public/javascripts/routers/mentions.js
new file mode 100644
index 0000000000000000000000000000000000000000..32ccf50e453a4bf86c2b9c2ea5f3b33b70508bed
--- /dev/null
+++ b/public/javascripts/routers/mentions.js
@@ -0,0 +1,5 @@
+App.Routers.Mentions = App.Routers.Stream.extend({
+  routes: {
+    "mentions": "stream"
+  }
+});
diff --git a/public/javascripts/routers/stream.js b/public/javascripts/routers/stream.js
new file mode 100644
index 0000000000000000000000000000000000000000..220e501b13c7a85da757605ca76f6401c5dd0e31
--- /dev/null
+++ b/public/javascripts/routers/stream.js
@@ -0,0 +1,9 @@
+App.Routers.Stream = Backbone.Router.extend({
+  routes: {
+    "stream": "stream"
+  },
+
+  stream: function() {
+    App.stream = new App.Views.Stream;
+  }
+});
diff --git a/public/javascripts/views/stream.js b/public/javascripts/views/stream.js
index f7ea0632d987cb585e9ea0acf1cf405484fb6f6d..ee4f6201baf8f9d3513b953fc74c10e21422e291 100644
--- a/public/javascripts/views/stream.js
+++ b/public/javascripts/views/stream.js
@@ -1,55 +1,47 @@
-$(function() {
-  App.Views.Stream = Backbone.View.extend({
-
-    el: $("#main_stream"),
-
-    template: _.template($('#stream-element-template').html()),
-
-    events: {
-      "click #paginate": "loadMore"
-    },
-
-    initialize: function(){
-      _.bindAll(this, "appendPost", "collectionFetched");
-
-      this.collection = new App.Collections.Stream;
-      this.collection.bind("add", this.appendPost);
-      this.loadMore();
-    },
-
-    appendPost: function(model) {
-      var post = $(this.template($.extend(
-        model.toJSON(),
-        App.currentUser()
-      )));
-      $(this.el).append(post);
-      Diaspora.BaseWidget.instantiate("StreamElement", post);
-    },
-
-    collectionFetched: function() {
-      this.$("time").timeago();
-      this.$("label").inFieldLabels();
-
-      this.$("#paginate").remove();
-      $(this.el).append($("<a>", {
-        href: this.collection.url(),
-        id: "paginate"
-      }).text('more'));
-    },
-
-    loadMore: function(evt) {
-      if(evt) {
-        evt.preventDefault();
-      }
-
-      this.collection.fetch({
-        add: true,
-        success: this.collectionFetched
-      });
+App.Views.Stream = Backbone.View.extend({
+  events: {
+    "click #paginate": "loadMore"
+  },
+
+  initialize: function(){
+    this.el = $("#main_stream");
+    this.template = _.template($("#stream-element-template").html());
+
+    _.bindAll(this, "appendPost", "collectionFetched");
+
+    this.collection = new App.Collections.Stream;
+    this.collection.bind("add", this.appendPost);
+    this.loadMore();
+  },
+
+  appendPost: function(model) {
+    var post = $(this.template($.extend(
+      model.toJSON(),
+      App.user()
+    )));
+    $(this.el).append(post);
+    Diaspora.BaseWidget.instantiate("StreamElement", post);
+  },
+
+  collectionFetched: function() {
+    this.$(".details time").timeago();
+    this.$("label").inFieldLabels();
+
+    this.$("#paginate").remove();
+    $(this.el).append($("<a>", {
+      href: this.collection.url(),
+      id: "paginate"
+    }).text('more'));
+  },
+
+  loadMore: function(evt) {
+    if(evt) {
+      evt.preventDefault();
     }
-  });
 
-  if(window.useBackbone) {
-    window.stream = new App.Views.Stream;
+    this.collection.fetch({
+      add: true,
+      success: this.collectionFetched
+    });
   }
 });
diff --git a/spec/javascripts/app-spec.js b/spec/javascripts/app-spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..958cd5b95eaf0e50d74a63249b064842df7901fe
--- /dev/null
+++ b/spec/javascripts/app-spec.js
@@ -0,0 +1,11 @@
+describe("App", function() {
+  describe("user", function() {
+    it("sets the user if given one and returns the current user", function() {
+      expect(App.user()).toBeUndefined();
+
+      App.user({name: "alice"});
+
+      expect(App.user()).toEqual({name: "alice"});
+    });
+  });
+});