XULRunner in large projects, part 1: What is that “XULRunner” thingy, anyway?

I applied to lead a session on XULRunner in large software projects at the Mozilla Summit. Unfortunately, that proposal was rejected, no talk for me at the summit. Yet there is apparently some interest in the topic, I got messages from two people who won’t be attending the summit asking for slides. I won’t create any slides but I decided to share my thoughts on the topics I wanted to discuss. Having spent the last three years building XULRunner-based applications (first TomTom HOME, now Songbird) I have some experience in this area. Still, this will be necessarily a one-sided view so don’t hesitate to comment.

So, what is that “XULRunner” thingy?

Mozilla has been investing much effort into creating the most powerful and flexible platform to build its applications upon (primarily Firefox and before it Mozilla Suite). This platform is usually referred to as “Gecko” or “Toolkit” and is among other things responsible for the unique extensibility of Firefox. And it is also fairly reusable: applications like Thunderbird or Sunbird use the same platform as Firefox despite being very different. Yet using Gecko in your application was a fairly complicated affair back in 2005, there was a stand-alone version of it with Gecko Runtime Environment but you had to write C++ code and compile you application against it.

There was much discussion about how to make reusing the Mozilla platform easier. The idea that won in the end was packing more code into the runtime, essentially everything required to run Firefox minus the Firefox user interface. New applications would only need to ship their user interface code and everything else would be provided by the runtime. With the user interface being primarily specified in XUL the new runtime got the name XULRunner. According to Wikipedia, applications could use XULRunner as their runtime starting with 2006 — and many did.

XUL and the flexible box model

XULRunner allows creating complicated cross-platform applications in a very short time as demonstrated by Daniel Glazman who created a full-featured Twitter client in a few weeks. An important factor here is XUL, the XML-based user interface language used. In some respects XUL is similar to HTML, in fact you can use XHTML in XUL documents. Still, being targeted at at user interfaces it uses the flexible box model to position elements. As a result XUL elements can easily be made to occupy all available space both horizontally and vertically and to adjust automatically in the correct way when that space changes.

Side note: Mozilla also supports the flexible box model in HTML via CSS styles, there is even an effort to standardize it. However, the flexibility of HTML makes it rather awkward for designing user interfaces IMHO.

The other advantage of XUL is the number of predefined widgets for the common tasks such as progressmeter or toolbarbutton. These widgets will usually have native appearance and same behavior on all supported operating systems, the developer doesn’t need to worry about details of the operating system the application runs on.

There is another language called XBL that allows you to create your own reusable XUL widgets. These widgets can combine some already existing XUL tags, expose JavaScript properties and methods to other code and react to events dynamically. All in all, XBL is again a very powerful tool with the main disadvantage being: it takes some time to learn it.

Controlling presentation with CSS

XUL looks pretty good by default. However, occasionally some aspects of the presentation need to be adjusted, some applications even prefer their very own look to the native one, and the instrument of choice is CSS — same as for web pages. This is particularly appealing to people who have web development or web design experience. It also encourages separation of content and presentation, XUL has no equivalents of HTML’s “b” or “i” tags.

Making things move — with JavaScript

The “real programming”, e.g. making the user interface respond to user input, is usually done in JavaScript. This is again something that particularly people with web development experience will value. Other people usually need some time to get used to some of the unusual concepts used. Still, as a high-level language JavaScript allows to write code that is both compact and easy to understand. Its performance improved drastically in the past few years and continues to improve. And with the mechanism of JavaScript code modules it is ready for large applications.

Below the surface: XPCOM

What I described above is merely the tip of the iceberg. The Mozilla platform is built on XPCOM, the cross-platform variant of Microsoft’s COM. XULRunner includes hundreds of different XPCOM components providing various interfaces. There are components responsible for networking functions (network protocol implementations, DNS service etc.), for file system access (file reading/writing, directory service etc.), preferences, application update and much more. Most of these components can be accessed and used from JavaScript code and often make writing own code unnecessary. A XULRunner application can come with own XPCOM components that can be written in either JavaScript or C++. The latter is particularly useful to implement low-level capabilities that the platform doesn’t provide yet.

What about the downsides?

The above sounds much like an advertising pitch. In fact, when you first look at XULRunner it seems to be a great platform (it certainly is) without real downsides other than the requirement to learn a new interesting technology. Unfortunately, when you use XULRunner in a large project over a longer time you have to deal with the details and things stop being so rosy. So details are what I want to discuss in the following blog posts. So far I have as topics: platform quirks, platform bugs/updates, localization, recruiting, application updates/security (not necessarily in that order).

Comments

  • Miff

    The reason I don’t want to learn the XULRunner platform is the same problem I have with nearly all JavaScript-based platforms: the lack of decent error reporting.

    Wladimir Palant

    What kind of error reporting do you expect? The Error Console that you have in Firefox is part of any XULRunner application – just specify “-jsconsole” on the command line. At that point you should see all errors and any debug output you might write to console. You won’t get the full stack this way but that’s something you can relatively easily add to your application (we’ve done it in TomTom HOME).

  • Jason Oster

    Very interesting article! I wrote a few of these with similar intent, myself. The first part of my article can be found here:

    http://www.kodewerx.org/wiki/index.php/A_Brief_Introduction_To_XULRunner:_Part_1

    Thanks for this, Wladimir!

  • pc1oad1etter

    Thanks for responding; I look forward to the rest of the series.

  • pc1oad1etter

    Wladimir,

    re: your title, “XULrunner in large projects” – do you pretty much mean, anything that is larger than what an extension would be well-suited for? We have a (large) xulrunner application, and one of the challenges that I am facing now is how to be (re-)organize the code. We have broken many of the discrete parts into separate extensions, that we then bundle together, but I have been re-thinking how to use shared code, shared libraries among my various extensions.

    We used subscriptloader for this, but I have been trying to re-implement code in code modules, having read that it would load the script only once. However, I have also learned that there are limitations with doing this, as some of the native, window/DOM-related functions are inaccessible (or perhaps, just a pain to access, via xpcom functions).

    That may be too narrow of a topic for you to address, but if you do have any suggestions, I would love to hear it. Again, I’m not just asking “where do I put my JavaScript in the application folder to make it work — I’m asking how to best modularize/organize the code that would be especially beneficial for a large xulrunner application. This blog post got me thinking more about this: http://www.softwareishard.com/blog/planet-mozilla/firefox-extensions-global-namespace-pollution/.

    Thanks again!

    Wladimir Palant

    I’m basically meaning “a project that requires continuous effort from more than two people” – that should be the area where you are certain to start hitting non-trivial issues.

    JavaScript code modules run in their own context, not the context of any single window. Usually you would still keep a little code in the overlay to work with the current window – but it would mostly call utility functions in a module (and pass the window or document as parameter if necessary).