SproutCore: JavaScript Applications

    Andrew Tetlaw
    Andrew Tetlaw

    Revealed by Apple at the recent WWDC as the basis of the MobileMe web applications, is the newest member of the JavaScript framework fraternity: SproutCore. I’m pretty sure that if I told you SproutCore was yet another JavaScript framework for creating rich browser application interfaces, you’d prefer to scrub your eyeballs with steel wool than keep reading. Don’t head off just yet though, because SproutCore is quite different from other frameworks and worth taking a look at.

    SproutCore is an open source framework for creating desktop-style applications that run in the browser using only HTML, CSS and JavaScript. You first create your application within a local development environment and then use the SproutCore build tools to compile the application in to a set of static files you can place on your web server. The term ‘thick client’ has been coined by SproutCore’s lead developer, Charles Jolley, to describe SproutCore’s approach. SproutCore applications are totally independent of any server-side technology. The whole application runs in the browser; the only interaction with the server is to save or load data via Ajax.

    When I say, ‘creating applications’ I mean sophisticated, Model-View-Controller based application design, inspired by Apple’s Cocoa. In practice it feels like you’re building a full featured Ruby on Rails application — the build tools are written in Ruby and use Rails-like features such as generators. Models and controllers are written in JavaScript and views are written in Erubis, a high performing implementation of Embedded Ruby.

    Here’s a very simple demonstration of how it works. I recommend doing the hello world tutorial on the SproutCore site if you want to see more.

    After installing the build tools via the RubyGems system, you begin a new application by typing the command: sproutcore hello_goodbye, replacing hello_goodbye with the name of your application. This will generate a directory with the same name as your application and in it, all the required files to make your application run locally.

    To be able to do anything interesting you’ll need a controller — a JavaScript object that manages your application logic. You can use the built-in generator by typing in the following command from your project’s root directory:

    sc-gen controller hello_goodbye/app

    This will generate the application controller called HelloGoodbye.appController.

    You wire up the interface elements of your application using bindings and observers. Let’s modify our controller by adding a greeting property:

    HelloGoodbye.appController = SC.Object.create(
      greeting: "Hello World!"

    Then we’ll add some view helpers to the default view file: a label view and a button view:

    <%= label_view :my_label, 
        :tag => 'h1', 
        :bind => { :value => 'HelloGoodbye.appController.greeting' } %>
    <%= button_view :toggle_button, 
        :title => 'Change Greeting', 
        :action => 'HelloGoodbye.appController.toggleGreeting' %>

    Starting the included Mongrel web server by entering the command sc-server from the project’s root directory, will allow you to load the project in your browser at http://localhost:4020/hello_goodbye. You’ll see a h1 element with the text “Hello World!” and a “Change Greeting” button.
    A screenshot of a simpleSproutCore app

    The text content of the label view has been bound to the greeting property of the controller. If you change the value of greeting using the SproutCore API:

    HelloGoodbye.appController.set('greeting', 'Goodbye World!')

    the text within the heading will miraculously change as well.

    The :action property of the button view indicates the controller method that will be called when the button is clicked. We’ll add that method to our controller:

    HelloGoodbye.appController = SC.Object.create(
      greeting: "Hello World!",
      toggleGreeting: function() {
        var currentGreeting = this.get('greeting');
        var newGreeting = (currentGreeting === 'Hello World!') ? 'Goodbye World!' : 'Hello World!' ;
        this.set('greeting', newGreeting);

    If you refresh the page in your browser, clicking the button should toggle the text within the h1 element between “Hello World!” and “Goodbye World!”. You may notice this is achieved without us having to write any DOM manipulation code in JavaScript at all.

    Once you’re ready to deploy, all you need to do is run the following command from within your project’s root directory:sc-build. This will create a directory containing static files that you can move to your web server.

    Our trivial example above is converted to the following html:

    <h1 id="my_label" class="sc-label-view my_label"></h1>
    <a title="Change Greeting" id="toggle_button" 
        class="sc-button-view button regular normal toggle_button">
      <span class="button-inner">
        <span class="label">Change Greeting</span>

    In addition to the HTML, you’ll also find all the JavaScript code required to run the application.

    Looking at the generated source, it’s clear SproutCore is an application framework in the truest sense: ignore the generated HTML, the end product will look and feel like a desktop application. For a web standards fan like myself, browser-based, desktop-style applications are always a hard sell. I prefer the restful, semantic-markup based, document-centric approach that lets browsers act like browsers. You know: bookmarks and history, right-click > Open in new tab, the sanctity and purity of the hyperlink. It seems inevitable though, that the browser, as an application platform, will be pushed as far as it can go. I can’t help recalling Joel on Software predicted something like this might come along.

    As a JavaScript fan I’m impressed; the interface performance is excellent. SproutCore raises the bar for what JavaScript can do in the browser. On a recent Audible Ajax Jolley talked about how a SproutCore application has only 6 event handlers. SproutCore uses event delegation to determine which element in the body was the target of the event. I’m certain that there are many JavaScript gems to be mined from the SproutCore codebase. The SproutCore blog already contains some great posts.

    What about accessibility? How will assistive technologies treat the HTML generated by SproutCore? I doubt screen readers that are compatible with standard HTML forms, but otherwise designed to interpret a web page as a document, will have any chance of making sense of it. Perhaps, in the future, standards like the WAI Accessible Rich Internet Applications specification will eventually come to the rescue. I’ll be interested to see the approach Apple takes for MobileMe.

    Despite my concerns, I can certainly appreciate how Apple has chosen an open source technology that is browser based and requires no plugins as the basis for their online applications. In my mind, this beats the pants off the alternative technology stacks from Adobe and Microsoft.