Apps Articles

Sort by:


  1. Creating a mobile app from a simple HTML site: Part 2

    Or: Making our simple app work for others

    In the first part of this series, which began late last year, we worked through the process of developing a school planner app. At this point (see the final code from Part 1) we’ve got multiple school plans displayed at once, and we’ve got Web, iOS and Android support via Cordova.

    Stage4 Result Screenshot<br />

    Let’s imagine that others have seen the benefits and would like to use our app as well. Creating an app tailored to them should be possible by simply replacing one file (let’s name it www/app_data/plans.json) with their family’s data and making a few other tweaks. This is where we will focus in the beginning of this part.

    Our eventual goal is to create an app to display data (school plans) stored on a server, so every user can view their own data from any computer. In this tutorial, the server part will be minimized to avoid distraction from the main goal — the database of plans is going to be written into a JSON file. If you wish to extend it into SaaS please do so, and let us know in the comments section below.

    What will be built

    A mobile application which will:

    1. Display school plan(s).
    2. Work offline.
    3. Work on many platforms.
    4. Use school plans stored on a server/in a JSON file (our goal for next parts of the series).


    If you haven’t worked through the first article then we suggest you do so now. You should at least go through the part 1 prerequisites and make sure you are familiar with them.

    Then follow the steps below, updating your code example from the previous article. If you don’t have this code example, (i.e., if you’ve not gone through the previous article), follow the instructions on how to load any stage in this tutorial. Use stage4 as a starting point.

    You should also make sure you have NodeJS installed.

    Adding an icon

    In Part 1, I omitted the icon, so Cordova added a default one. Let’s make the app look more professional with a custom icon. I’ve downloaded a backpack icon from resized it and copied to www/img. In the app directory (school-plan/ — created after running cordova create) — edit the config.xml file and add the following:

    <icon src="www/img/backpack-128.png" />

    If you wish you can add more specific information – for example, more image sizes for each desired platform. You can find more information in Cordova docs. Here is the special definition for Firefox OS:

    <platform name="firefoxos">
    	<icon width="128" height="128" src="www/img/backpack-128.png" />
    	<icon width="64" height="64" src="www/img/backpack-64.png" />
    	<icon width="32" height="32" src="www/img/backpack-32.png" />

    Due to an error in the Firefox OS part of Cordova, please also create the www/icon directory using the following command.

    mkdir www/icon

    Modifying the data code

    In this stage we will modify the school plan app to work with data instead of plain HTML (see finished stage 5 code on GitHub.)

    Before we had all school plan’s data hard coded into index.html. Now we will separate the data from its visual representation. To do so, we will remove the old data from www/index.html, leaving only the minimal structure behind.

    Empty both the <brick-tabbar> and <brick-deck> elements in your index.html file, so they are left looking like so:

    <brick-tabbar id="plan-group-menu" selected-index="0">
    <brick-deck id="plan-group" selected-index="0">

    The most common data structure used in JavaScript projects is JSON; we will therefore add our data in this format. For now it’s OK to distribute the school plan together with the app (later on we will probably serve it from a server instead, for greater flexibility). Our JSON contains an Array of plans. Plan is an Object containing title, id, optional active field and week. The latter is itself an Array of lesson plans.

    Note: use jsHint to check the quality of your code.

          "title": "Name of the plan",
          "id": "id-of-the-plan",
          "active": 1,  // should the plan be active now?
          "week": [
              "first hour of Monday",
              "second hour",
              // ... and so on
            [],  // no activities on Tuesday
            ], [
              "Wednesday is starting on third hour",

    You can find a sample file on Github. Copy this into your project at www/app_data/plans.json.

    Now we need to read this JSON file from the app’s directory.

    As the cards and tabs do not exist at the moment of loading the JavaScript file we should now remove the part where these were linked together from www/js/index.js. Go to this file, find the assignTabs() function, and remove it completely, along with the call to it just below.

    The application will show nothing without the data. Data needs to be loaded just after the app is ready — find the onDeviceReady method and just inside it at the top enter the following lines of code:

    var request = new XMLHttpRequest();
    request.onload = app.renderData;"get", "app_data/plans.json", true);

    Note: Previously I planned to use Cordova’s FileSystem plugin, but it only made the code more complicated.

    After the request successfully returns our JSON, it is passed to app.renderData (seen below). It parses the text in JSON format to JavaScript and sends data to app.createUI so the necessary DOM elements will be created to form the UI.

    Add the following code block below the onDeviceReady method:

    renderData: function() {
        var plans = JSON.parse(this.responseText);

    To create the UI we will need weekday names. The best option is to use Cordova’s Globalization plugin. To add this plugin to the application simply run the following command in your terminal, making sure you are inside your root school-plan directory:

    cordova plugin add org.apache.cordova.globalization

    Next, add the createUI() method we referenced earlier underneath the renderData() method. It looks like so:

    createUI: function(plans) {
        var deck = document.getElementById('plan-group');
        var tabbar = document.getElementById('plan-group-menu');
        navigator.globalization.getDateNames(function(dayOfWeek) {
            // render UI in the callback
        }, function() {}, {type: 'narrow', item: 'days'});

    Week days are retrieved using the navigator.globalization.getDateNames method. dayOfWeek will hold an Array of week day names, for example (Polish in my case) — ['Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'Nd']. If you’d like to use full day names, just change type: 'narrow' to type: 'wide'.

    Now we need to create DOM elements for individual plans. This time brick-tabbar-tab and brick-card elements are created using JavaScript. Tab refers to the corresponding card using its target parameter. It has the same value as the card’s id in each case. Brick will parse this value and create a tab.targetElement, which will link to the card element. Inside the callback of getDateNames, enter the following code (in place of the “// render UI in the callback” comment seen above):

    for (var i = 0; i < plans.length; i++) {
        var plan = plans[i];
        // create card
        var card = document.createElement('brick-card');
        //create tab
        var tab = document.createElement('brick-tabbar-tab');
        // link card to tab
        card.tabElement = tab;
        card.addEventListener('show', function() {
        // create plan table
        var table = document.createElement('table');

    Unlike when writing plain HTML, we will create the table body now and then the header. This is because table.insertRow() either creates a new tbody and tr inside or adds a row to any existing HTMLTableSectionElement (thead if already created). We could also call table.tBodies(0) instead but it would complicate the code.

    We don’t want to display days which don’t have any lessons. Let’s copy the plan with only non-empty days to new cleanPlan array. Place this code after the line that creates the <table> element (see above listing):

    var numberOfDays = plan.week.length;
    var cleanPlan = [];
    for (j = 0; j < numberOfDays; j++) {
        if (plan.week[j].length > 0) {

    There is a problem that needs to be solved before we can create the other DOM elements (<tr> and <td>) — we’re representing the plan in a JSON file structured as humans understand it — hours inside days. Unfortunately tables in HTML are created row by row (days inside hours), which means that the array representing the plan needs to be flipped over.

    For example our array stored in JSON will look like this: (dXhY represents day X and hour Y):

    d1h1 d1h2 d1h3 ...
    d2h1 d2h2 d2h3 ...
    d3h1 d3h2 d3h3 ...

    But our <table> structure will look like this:

    d1h1 d2h1 d3h1 ...
    d1h2 d2h2 d3h2 ...
    d1h3 d2h3 d3h3 ...

    Add the following code block right after the last one, to start performing this data transformation for us:

    var daysInHours = [];
    for (j = 0; j < cleanPlan.length; j++) {
        for (var k = 0; k < cleanPlan[j].length; k++) {
            if (!daysInHours[k]) {
                daysInHours[k] = [];
            daysInHours[k][j] = cleanPlan[j][k];

    The most important line above is the daysInHours[k][j] = cleanPlan[j][k]; where the indexes are reversed — the kj element of one array becomes the jk element of the other. d3h2 takes the place of d2h3 and vice versa.

    The daysInHours array should now hold the plan prepared for the UI. Now we can iterate over it to render the plan into the HTML table. There is an important thing to note here — table.insertRow needs to use the (otherwise optional) index set to -1, as by default Android inserts the row on top of the table.

    Add the following block right below the previous one:

    for (var j = 0; j < daysInHours.length; j++) {
        var tr = table.insertRow(-1);
        var td = tr.insertCell(-1);
        td.appendChild(document.createTextNode(j + 1));
        for (var k = 0; k < cleanPlan.length; k++) {
            var td = tr.insertCell(-1);
            if (daysInHours[j][k]) {

    We iterate over all the hours (index j). The first <tr> is created at the bottom of the array, then the <td> with the textNode containing that row number. After that we iterate over the days inside the hour (index k) and create more cells — if there is a plan for this hour and day a textNode is created.

    You might be surprised to see this code using cleanPlan.length instead of daysInHours[j].length. This is because we need to create a cell on each day even if no lesson is planned, otherwise we will end up with a broken table structure like this:

    short row issue

    Now we’re ready to create a header with days. Add the following code block right below the previous one:

    var thead = table.createTHead();
    var tr = thead.insertRow();
    var th_empty = document.createElement('th');
    var weekDayNumber;
    for (var j = 0; j < numberOfDays; j++) {
        var weekDayNumber = (j + 1) % 7;
        if (plan.week[j].length > 0) {
            var th = document.createElement('th');

    First, an empty header cell is created for the column, containing the corresponding hour of the day. Then we iterate over the days and create a new <th> with a day name only if there is a plan for the current day (in the same manner as for cleanPlan before.)

    Next we need a line to place the created <table> inside the brick-card element — add the following line below the previous block:


    When all tabs are ready, we’ll want the first tab to be selected when the app is loaded. To do this we’ll use the following block — add this just below the previous line:

    if ( {
        selectTab(deck, tab);

    selectTab is a helper function created outside of the app object. It is using polling on activeTab.targetElement to detect if Brick had already linked tab with cards, as seen below. Add this block at the very bottom of your index.js file:

    function selectTab(deck, activeTab) {
        function selectActiveTab() {
            if (!activeTab.targetElement) {
                return window.setTimeout(selectActiveTab, 100);

    Testing time

    At this moment the app should work exactly the same as on Stage 4 in Part 1. The only difference may be in the localized names of the days in the plan’s header.

    When you want to test your app, type in the following terminal commands (from the root directory of your school-plan app):

    cordova prepare
    cordova serve

    This will make the app and its different platforms available to you at localhost:8000.

    If you also want to test the app in Firefox OS, you’ll need to open WebIDE in Firefox, go to Open App > Open Packaged App, and from the file chooser select to open the school-plan/platforms/firefoxos/www directory as a packaged app. From here you can choose to load the app in a simulator or a real Firefox OS device. See the MDN WebIDE page for more details.

    Note: If you’d like to tailor the application for different people who want to use it, at this stage you can do so by replacing the www/app_data/plans.json file with different information for each individual user.

  2. An analytics primer for developers

    There are three kinds of lies: lies, damned lies, and statistics – Mark Twain

    Deciding what to track (all the things)

    When you are adding analytics to a system you should try to log everything. At some point in the future if you need to pull information out of a system it’s much better to have every piece of information to hand, rather than realising that you need some data that you don’t yet track. Here are some guidelines and suggestion for collecting and analysing information about how people are interacting with your website or app.

    Grouping your stats as a best practice

    Most analytics platforms allow you to tag an event with metadata. This lets you analyse stats against each other and makes it easier to compare elements in a user interaction.

    For example, if you are logging clicks on a menu, you could track each menu item differently e.g.:

    track("Home pressed");
    track("Cart pressed");
    track("Logout pressed");

    Doing this makes it harder to answer questions such as which button is most popular etc. Using metadata you can make most analytics platforms perform calculations like this for you:

    track("Menu pressed","Home button");
    track("Menu pressed","Cart button");
    track("Menu pressed","Logout button");

    The analytics above mean you now have a total of all menu presses, and you can find the most/least popular of the menu items with no extra effort.

    Optimising your funnel

    A conversion funnel is a term of art derived from a consumer marketing model. The metaphor of the funnel describes the flow of steps a user goes through as they engage more deeply with your software. Imagine you want to know how many users clicked log in and then paid at the checkout? If you track events such as “Checkout complete” and “User logged in” you can then ask your analytics platform what percentage of users did both within a certain time frame (a day for instance).

    Imagine the answer comes out to be 10%, this tells you useful information about the behaviour of your users (bear in mind this funnel is not order sensitive, i.e., it does not matter in which order the events happen in login -> cart -> pay or cart -> login -> pay). Thus, you can start to optimise parts of your app and use this value to determine whether or not you are converting more of your users to make a purchase or otherwise engage more deeply.

    Deciding what to measure

    Depending on your business, different stats will have different levels of importance. Here are some common stats of interest to developers of apps or online services:

    Number of sessions
    The total number of sessions on your product (the user opening your product, using it, then closing it = 1 session)
    Session length
    How long each session lasts (can be mode, mean, median)
    How many people come back to your product having used it before (there are a variety of metrics such as rolling retention, 30 day retention etc)
    Monthly active users: how may users use the app once a month
    Daily active users: how may users use the app once a day
    Average revenue per user: how much money you make per person
    Average transaction value: how much money you make per sale
    Customer acquisition cost: how much it costs to get one extra user (normally specified by the channel for getting them)
    Customer lifetime value: total profit made from a user (usually projected)
    The number of people who leave your product in a given time (usually given as a percentage of total user base)
    Cycle time
    The the time it takes for one user to refer another

    Choosing an analytics tool or platform

    There are plenty of analytics providers, listed below are some of the best known and most widely used:

    Google Analytics

    Developer documentation

    Quick event log example:

    ga('send', 'event', 'button', 'click');


    • Free
    • Easy to set up


    • Steep learning curve for using the platform
    • Specialist training can be required to get the most out of the platform

    Single page apps:

    If you are making a single page app/website, you need to keep Google informed that the user is still on your page and hasn’t bounced (gone to your page/app and left without doing anything):

    ga('set' , 'page', location.pathname + + location.hash);
    ga('send', 'pageview');

    Use the above code every time a user navigates to a new section of your app/website to let Google know the user is still browsing your site/app.


    Developer documentation

    Quick event log example:

    FlurryAgent.logEvent("Button clicked");
    FlurryAgent.logEvent("Button clicked",{more : 'data'});


    • Free
    • Easy to set up


    • Data normally 24 hours behind real time
    • Takes ages to load the data


    Developer documentation

    Quick event log example:

    mixpanel.track("Button clicked");
    mixpanel.track("Button clicked",{more : 'data'});


    • Free trial
    • Easy to set up
    • Real-time data


    • Gets expensive after the free trial
    • If you are tracking a lot of points, the interface can get cluttered

    Speeding up requests

    When you are loading an external JS file you want to do it asynchronously if possible to speed up the page load.

    <script type="text/javascript" async> ... </script>

    The above code will cause the JavaScript to load asynchronously but assumes the user has a browser supporting HTML5.

    //jQuery example

    This code will load the JavaScript asynchronously with greater browser support.

    The next problem is that you could try to add an analytic even though the framework does not exist yet, so you need to check to see if the variable framework first:

    if(typeof FlurryAgent != "undefined"){

    This will prevent errors and will also allow you to easily disable analytics during testing. (You can just stop the script from being loaded – and the variable will never be defined.)

    The problem here is that you might be missing analytics whilst waiting for the script to load. Instead, you can make a queue to store the events and then post them all when the script loads:

    var queue = [];
    if(typeof FlurryAgent != "undefined"){
       queue.push(["data",{more : data}]);
    //jQuery example
       for(var i = 0;i < queue.length;i++)
       queue = [];

    Analytics for your Firefox App

    You can use any of the above providers above with Firefox OS, but remember when you paste a script into your code they generally are protocol agnostic: they start // and you need to choose either http: or https: (This is required only if you are making a packaged app.)

    Let us know how it goes.

  3. Open Web Apps feedback: Consolidating our channels

    In August 2014 we announced the opening of a new feedback channel for web apps on UserVoice. It has led to some good discussions and here are a few highlights:

    We would like to sincerely thank those who have provided input and participated in all of the discussions. Unfortunately, after some great initial levels of participation we have since seen usage fall, so at this time we think it is best to discontinue use of With UserVoice’s handy data exporting services, we’ve made sure we have an archived copy of the ideas posted and interactions that took place on the site.

    Please keep the feedback and feature suggestions coming. It’s essential for us to continue to hear from developers like you. We’d simply like to redirect feedback back to mailing lists/newsgroups (see this list of IRC channels and mailing lists for some Mozilla app-specific channels), which aims to be a forum for building web standards, and Bugzilla instances like Mozilla’s.

    Note: The Firefox Developer Tools feedback channel hosted on UserVoice ( is very active and is most definitely remaining open!

  4. Introducing node-firefox

    NOTE: we presented this project last Sunday at FOSDEM, but not everyone could make it to Brussels, so here’s a post explaining what node-firefox is and how can it help you superturbocharge your Firefox OS app development!

    At Mozilla we’re always looking for ways in which we can make developers’ lives easier. When aspiring app developers told us that it was cumbersome to get started writing Open Web Apps, we worked on turning App Manager into a more beginner friendly environment, which in turn gave way to WebIDE. This tool simplifies many actions that were slow and tedious before, such as creating a new app, downloading and installing simulators or running and debugging apps.

    But there was still a segment of developers that felt left out: power users! They already have their node.js-based build toolchains, with tasks such as asset optimisation, code hinting, or test running. They often also use tools such as Browserify, and perhaps they don’t even write JavaScript, favouring alternatives such as CoffeeScript instead, but all these goodies require you to build the app or website before you push it again to your device or reload the browser.

    Essentially, we were telling these developers to leave their beloved command line (or editor shortcuts!) to go to WebIDE and click a button to deploy the app, and then go back to their editor of choice. And they most unanimously answered: “But we don’t like to click! We like the terminal!”

    How can we make this more efficient?

    People didn’t like this because it implied changing contexts. It is inefficient, we are engineers, and if there one thing that engineers like more than building new things it is probably optimising and streamlining processes.

    Since we already have a build script, the only step that is left in order to get our apps onto the runtime is deploying, and that’s what we are using WebIDE for. So the obvious question would be: can we do whatever WebIDE is doing to deploy, but programmatically?

    Servers and actors

    Every Firefox runtime has something called the remote debugger server. This is not enabled by default, for obvious security reasons, but when enabled, clients can connect to it and take advantage of its various functionalities, such as installing apps, accessing the console, etc. And this is what WebIDE does internally.

    Each of these functionalities is provided by an actor. For example, suppose we want to list the installed apps. We would…

    • first find the webApps actor
    • then run the getAll command
    • and get a list of apps in response

    Another example would be installing a packaged app. The steps would be:

    • first zip the app contents, using whatever library or way you like
    • then get the webApps actor
    • call the uploadPackage command in the webApps actor with the contents of the ZIP file
    • the result of this call is a File actor
    • call the install command in the webApps actor with the returned File actor
    • done!

    Therefore all the magic for installing apps is not in WebIDE—it is in the servers! We can take advantage of this magic programmatically, but building a client from scratch involves establishing TCP connections and parsing packets, which is not what you want to be doing: you want to write apps and push them to devices instead!

    Despair not, as node-firefox will abstract that for you. It is not a monolithic piece of code, but a series of node.js modules, each one of them performing a different task, hosted on its own separate repository and published to the npm registry like good module citizens. You can use as many of them as you need in your scripts or task runners, and thus you can finally build and run your app without ever leaving the command line.

    Show, don’t tell

    But enough of talking and describing; let’s see how to write a script that starts a simulator!

    First install the module in your project, using npm:

    npm install --save node-firefox-start-simulator

    And this would be the script:

    var startSimulator = require('node-firefox-start-simulator');
    startSimulator({ version: '2.2' })
      .then(function(simulator) {
        console.log('Listening in port', simulator.port);

    That’s it! With just a few lines of code you are able to programmatically start a version 2.2 simulator. If you don’t care about the version, just don’t pass in any option to startSimulator, and it will start the first simulator it finds:

    startSimulator().then(function(simulator) {
      // your code

    We can also see this in action. Here’s us starting a simulator, installing an app and launching it, all from a node.js script:

    Starting simulator, running app from node.js

    The code for this example is actually the example for the node-firefox-uninstall-app module. Each of the node-firefox modules come with an examples folder so you can get started rather quickly.

    As we mentioned at the beginning, many web developers that move to app development want to keep using their task runners, so we also wrote an example of how to use node-firefox with gulp.

    Let’s run the default-one task. This starts a simulator, deploys an app, and for a bit more of a challenge, also keeps watching for CSS changes. If you edit and save any of the app’s stylesheets, the file watcher will detect the change, and send the new file contents to the runtime, which will replace them on the fly, without having to stop, push and relaunch the whole app. Look at me changing the background colour from austere dark blue to the timeless Paul Rouget pink!

    Starting simulator, launching app with gulp

    Live CSS reloading is really great to build and experiment with UI interfaces. Not having to reload the app and then navigate to the particular layout you want to work in saves lots of time—I wish I’d had that when I was programming Android apps!

    But we can outdo this. The default-all task will do the same as default-one, but for all the simulators installed in your system, so you can see the effect of your CSS changes in all the simulators at the same time:

    Starting all simulators, launching app and live CSS reload with gulp.

    Unfortunately there is a bug in the 2.1 and 2.2 simulators, and those don’t reload the stylesheet changes, but it’s been filed and will be fixed.

    What can we do so far?

    The current set of modules lets you find ports where runtimes are listening, find and start simulators; connect to runtimes; find, install, uninstall and launch apps, and reload stylesheets.


    You might have noticed a pattern already, but just in case it wasn’t evident enough, we are trying to write deliberately simple modules. Each module should perform only one action, return a Promise and use as few dependencies as possible.

    Small modules are easier to understand, use, and test. Also, most of the future Web APIs are designed to work with Promises, and we want to write code for the future, not for the past. In addition, reducing the number of dependencies also makes it easier for new people to get started on contributing to a module, as there are fewer new unfamiliar elements to understand.

    Finally, since all the modules work the same way, when you know how to use one module you know how to use the rest—the only thing that changes is the parameters, and the result.

    Dream ideas (or: what we cannot do yet)

    There’s a number of things that we’d like to see happen in the future. Some people call them features, but I call them ‘dream ideas.’

    A recurrent one is the WebCLI: a counterpart equivalent to WebIDE, where everything you can do with WebIDE could be done with a command line tool. I keep switching back and forth between “this is a good idea” and “perhaps we don’t need this at all and a library of tasks will be enough”, but people seemed to like the idea, so maybe it’s not that bad!

    Another great feature would be the ability to attach the DevTools debugger to an app that was launched from the command line but that just crashed. Launching apps from the command line is great, but command line debuggers are not that exciting! Why not use the best of both worlds?

    Or maybe it would be neat to control any browser from the command line, interfacing via Valence!

    And finally, there is my favourite dream idea: Firefox OS custom editions. Imagine if we could just write a script that would create an empty Firefox OS slate, pull in our favourite apps and settings, and generate a whole Firefox OS image that we could then flash to devices. And since it is not a binary blob but a script, we could just publish it on its repository, and other people could remix and build their own Firefox OS based editions.

    How do we get there?

    There’s still a long way ahead of us, and lots of areas that need work. Perhaps the most urgent task is to get better multiplatform support. Currently we can only interact with runtimes through the network, but no physical devices. Also, support on platforms other than Mac OS is largely lacking.

    Testing is another important aspect. If we test early, often and profusely we will be able to detect problems such as the CSS bug I stumbled upon when building the gulp demo. We want to have these modules running on several platforms and connecting to other different platforms, including physical devices.

    Of course we need more modules, and more examples! To make sure no two people start writing the same module, we are discussing and proposing new modules in the top project issue tracker. And we’d love to see more examples, or even just better examples that hook existing functionality in other node modules with our code. For example, one could add manifest validation via the firefox-app-validator-manifest module.

    And, as always, we need you. We are not you, so we cannot know what you need or what thoughts cross your mind. And we certainly cannot use software the same way you use it either. We need your input and your contributions!

    We’re looking forward to seeing what you create with node-firefox. File issues, or talk to us on irc if you have questions. We hang out mostly in the #apps and #devtools channels in


    It would be dishonest not to thank Nicola Greco, whom I mentored last summer when he was interning at Mozilla. He came up with the initial idea of building individual node modules that would help you develop Firefox OS apps. Go check out his final intern presentation, as it’s really entertaining and illustrative!

    Many thanks to all the (infinitely patient) DevToolers Ryan Stinnet, Alexandre Poirot, Jeff Griffiths and Dave Camp, who helped us find our way around remote servers and actors and whatnot, and huge thanks to Heather Arthur who wrote firefox-client and made writing node-firefox way more pleasant than it would have been otherwise.

  5. Creating a mobile app from a simple HTML site

    This article is a simple tutorial designed to teach you some fundamental skills for creating cross platform web applications. You will build a sample School Plan app, which will provide a dynamic “app-like” experience across many different platforms and work offline. It will use Apache Cordova and Mozilla’s Brick web components.

    The story behind the app, written by Piotr

    I’ve got two kids and I’m always forgetting their school plan, as are they. Certainly I could copy the HTML to JSFiddle and load the plan as a Firefox app. Unfortunately this would not load offline, and currently would not work on iOS. Instead I would like to create an app that could be used by everyone in our family, regardless of the device they choose to use.

    We will build

    A mobile application which will:

    1. Display school plan(s)
    2. Work offline
    3. Work on many platforms

    Prerequisite knowledge

    • You should understand the basics of HTML, CSS and JavaScript before getting started.
    • Please also read the instructions on how to load any stage in this tutorial.
    • The Cordova documentation would also be a good thing to read, although we’ll explain the bits you need to know below.
    • You could also read up on Mozilla Brick components to find out what they do.


    Before building up the sample app, you need to prepare your environment.

    Installing Cordova

    We’ve decided to use Apache Cordova for this project as it’s currently the best free tool for delivering HTML apps to many different platforms. You can build up your app using web technologies and then get Cordova to automatically port the app over to the different native platforms. Let’s get it installed first.

    1. First install NodeJS: Cordova is a NodeJS package.
    2. Next, install Cordova globally using the npm package manager:
      npm install -g cordova

    Note: On Linux or OS X, you may need to have root access.

    Installing the latest Firefox

    If you haven’t updated Firefox for a while, you should install the latest version to make sure you have all the tools you need.

    Installing Brick

    Mozilla Brick is a tool built for app developers. It’s a set of ready-to-use web components that allow you to build up and use common UI components very quickly.

    1. To install Brick we will need to use the Bower package manager. Install this, again using npm:
      npm install -g bower
    2. You can install Brick for your current project using
      bower install mozbrick/brick

      but don’t do this right now — you need to put this inside your project, not just anywhere.

    Getting some sample HTML

    Now you should find some sample HTML to use in the project — copy your own children’s online school plans for this purpose, or use our sample if you don’t have any but still want to follow along. Save your markup in a safe place for now.

    Stage 1: Setting up the basic HTML project

    In this part of the tutorial we will set up the basic project, and display the school plans in plain HTML. See the stage 1 code on Github if you want to see what the code should look like at the end of this section.

    1. Start by setting up a plain Cordova project. On your command line, go to the directory in which you want to create your app project, and enter the following command:
      cordova create school-plan com.example.schoolplan SchoolPlan

      This will create a school-plan directory containing some files.

    2. Inside school-plan, open www/index.html in your text editor and remove everything from inside the <body> element.
    3. Copy the school plan HTML you saved earlier into separate elements. This can be structured however you want, but we’d recommend using HTML <table>s for holding each separate plan:
    4. Change the styling contained within www/css/index.css if you wish, to make the tables look how you want. We’ve chosen to use “zebra striping” for ease of reading.
      table {
        width: 100%;
        border-collapse: collapse;
        font-size: 10px;
      th {
        font-size: 12px;
        font-weight: normal;
        color: #039;
        padding: 10px 8px;
      td {
        color: #669;
        padding: 8px;
      tbody tr:nth-child(odd) {
        background: #e8edff;
    5. To test the app quickly and easily, add the firefoxos platform as a cordova target and prepare the application by entering the following two commands:
      cordova platform add firefoxos
      cordova prepare

      The last step is needed every time you want to check the changes.

    6. Open the App Manager in the Firefox browser. Press the [Add Packaged App] button and navigate to the prepared firefoxos app directory, which should be available in school-plan/platforms/firefoxos/www.

      Note: If you are running Firefox Aurora or Nightly, you can do these tasks using our new WebIDE tool, which has a similar but slightly different workflow to the App Manager.

    7. Press the [Start Simulator] button then [Update] and you will see the app running in a Firefox OS simulator. You can inspect, debug and profile it using the App Manager — read Using the App Manager for more details. App Manager buttons<br />
    8. Now let’s export the app as a native Android APK so we can see it working on that platform. Add the platform and get Cordova to build the apk file with the following two commands:
      cordova platform add android
      cordova build android
    9. The apk is build in school-plan/platforms/android/ant-build/SchoolPlan-debug.apk — read the Cordova Android Platform Guide for more details on how to test this.

    Stage1 Result Screenshot<br />

    Stage 2

    In Stage 2 of our app implementation, we will look at using Brick to improve the user experience of our app. Instead of having to potentially scroll through a lot of lesson plans to find the one you want, we’ll implement a Brick custom element that allows us to display different plans in the same place.

    You can see the finished Stage 2 code on Github.

    1. First, run the following command to install the entire Brick codebase into the app/bower_components directory.
      bower install mozbrick/brick
    2. We will be using the brick-deck component. This provides a “deck of cards” type interface that displays one brick-card while hiding the others. To make use of it, add the following code to the <head> of your index.html file, to import its HTML and JavaScript:
      <script src="app/bower_components/brick/dist/platform/platform.js"></script>
      <link rel="import" href="app/bower_components/brick-deck/dist/brick-deck.html">
    3. Next, all the plans need to be wrapped inside a <brick-deck> custom element, and every individual plan should be wrapped inside a <brick-card> custom element — the structure should end up similar to this:
      <brick-deck id="plan-group" selected-index="0">
        <brick-card selected>
            <!-- school plan 1 -->
            <!-- school plan 2 -->
    4. The brick-deck component requires that you set the height of the <html> and <body> elements to 100%. Add the following to the css/index.css file:
      html, body {height: 100%}
    5. When you run the application, the first card should be visible while the others remain hidden. To handle this we’ll now add some JavaScript to the mix. First, add some <link> elements to link the necessary JavaScript files to the HTML:
      <script type="text/javascript" src="cordova.js"></script>
      <script type="text/javascript" src="js/index.js"></script>
    6. cordova.js contains useful general Cordova-specific helper functions, while index.js will contain our app’s specific JavaScript. index.js already contains a definition of an app variable. The app is running after app.initialize() is called. It’s a good idea to call this when window is loaded, so add the following:
      window.onload = function() {
    7. Cordova adds a few events; one of which — deviceready — is fired after all Cordova code is loaded and initiated. Let’s put the main app action code inside this event’s callback — app.onDeviceReady.
      onDeviceReady: function() {
          // starts when device is ready
    8. Brick adds a few functions and attributes to all its elements. In this case loop and nextCard are added to the <brick-deck> element. As it includes an id="plan-group" attribute, the appropriate way to get this element from the DOM is document.getElementById. We want the cards to switch when the touchstart event is fired; at this point nextCard will be called from the callback app.nextPlan.
      onDeviceReady: function() {
          app.planGroup = document.getElementById('plan-group');
          app.planGroup.loop = true;
          app.planGroup.addEventListener('touchstart', app.nextPlan);
      nextPlan: function() {

    Stage2 Result Animation<br />

    Stage 3

    In this section of the tutorial, we’ll add a menu bar with the name of the currently displayed plan, to provide an extra usability enhancement. See the finished Stage 3 code on GitHub.

    1. To implement the menu bar, we will use Brick’s brick-tabbar component. We first need to import the component. Add the following lines to the <head> of your HTML:
      <script src="app/bower_components/brick/dist/platform/platform.js"></script>
      <link rel="import" href="app/bower_components/brick-deck/dist/brick-deck.html">
      <link rel="import" href="app/bower_components/brick-tabbar/dist/brick-tabbar.html">
    2. Next, add an id to all the cards and include them as the values of target attributes on brick-tabbar-tab elements like so:
      <brick-tabbar id="plan-group-menu" selected-index="0">
          <brick-tabbar-tab target="angelica">Angelica</brick-tabbar-tab>
          <brick-tabbar-tab target="andrew">Andrew</brick-tabbar-tab>
      <brick-deck id="plan-group" selected-index="0">
          <brick-card selected id="angelica">
    3. The Deck’s nextCard method is called by Brick behind the scenes using tab’s reveal event. The cards will change when the tabbar element is touched. The app got simpler, as we are now using the in-built Brick functionality, rather than our own custom code, and Cordova functionality. If you wished to end the tutorial here you could safely remove the <script> elements that link to index.js and cordova.js from the index.html file.

    Stage3 Result Animation<br />

    Stage 4

    To further improve the user experience on touch devices, we’ll now add functionality to allow you to swipe left/right to navigate between cards. See the finished stage 4 code on GitHub.

    1. Switching cards is currently done using the tabbar component. To keep the selected tab in sync with the current card you need to link them back. This is done by listening to the show event of each card. For each tab from stored in app.planGroupMenu.tabs:
      tab.targetElement.addEventListener('show', function() {
          // select the tab
    2. Because of the race condition (planGroupMenu.tabs might not exist when the app is initialized) polling is used to wait until the right moment before trying to assign the events:
      function assignTabs() {
          if (!app.planGroupMenu.tabs) {
              return window.setTimeout(assignTabs, 100);
          // proceed

      The code for linking the tabs to their associated cards looks like so:

      onDeviceReady: function() {
          app.planGroupMenu = document.getElementById('plan-group-menu');
          function assignTabs() {
              if (!app.planGroupMenu.tabs) {
                  return window.setTimeout(assignTabs, 100);
              for (var i=0; i < app.planGroupMenu.tabs.length; i++) {
                  var tab = app.planGroupMenu.tabs[i];
                  tab.targetElement.tabElement = tab;
                  tab.targetElement.addEventListener('show', function() {
          // continue below ...
    3. Detecting a one finger swipe is pretty easy in a Firefox OS app. Two callbacks are needed to listen to the touchstart and touchend events and calculate the delta on the pageX parameter. Unfortunately Android and iOS do not fire the touchend event if the finger has moved. The obvious move would be to listen to the touchmove event, but that is fired only once as it’s intercepted by the scroll event. The best way forward is to stop the event from bubbling up by calling preventDefault() in the touchmove callback. That way scroll is switched off, and the functionality can work as expected:
      // ... continuation
      app.planGroup = document.getElementById('plan-group');
      var startX = null;
      var slideThreshold = 100;
      function touchStart(sX) {
          startX = sX;
      function touchEnd(endX) {
          var deltaX;
          if (startX) {
              deltaX = endX - startX;
              if (Math.abs(deltaX) > slideThreshold) {
                  startX = null;
                  if (deltaX > 0) {
                  } else {
      app.planGroup.addEventListener('touchstart', function(evt) {
          var touches = evt.changedTouches;
          if (touches.length === 1) {
      app.planGroup.addEventListener('touchmove', function(evt) {

    You can add as many plans as you like — just make sure that their titles fit on the screen in the tabbar. Actions will be assigned automatically.

    Stage4 Result Screenshot<br />

    To be continued …

    We’re preparing the next part, in which this app will evolve into a marketplace app with downloadable plans. Stay tuned!

  6. The Missing SDK For Hybrid App Development

    Hybrid vs. native: The debate has gone on, and will go on, for ages. Each form of app development has its pros and cons, and an examination of the key differences between the two methods reveals that a flat correlation is like comparing apples to oranges. Many hybrid app developers understand that they’re not starting on a level playing field with native developers, but it’s important for them to understand exactly how that field fails to be level. We should analyze the differences at the app development framework level, instead of simply comparing hybrid to native.

    Native App Development

    Native software development kits (SDKs) come prepackaged with the required tools to compile and sign apps–all that boring stuff that “just works.” Their canned templates and the common code they provide determines “how” an app works, which are hugely beneficial features hiding in plain sight.

    For example, Apple’s own development environment, Xcode, is a suite of tools that make it easier to develop software for Apple platforms. As soon as you launch Xcode, it provides a list of templates for a new project. Let’s create an iOS tabbed application and see just how many tools native app developers have available to them from the start.

    After plugging in a few settings, I quickly have a working tabbed app that can be run within a minute of Xcode’s launch. Awesome! The easy part is done, and now it’s time to sport the hoodie and headphones and focus on my goal of creating a best-selling iOS app.

    Let’s drill into this a little further and take a look at what Xcode built for me, without me even having to give it a second thought. The app fills 100% of the device’s display; the tabs are aligned to the base with a gray background; one tab is highlighted blue, the other one gray, with icons on top of the tab’s title. Event listeners are added to the tab buttons, and when I click the second tab, it then turns blue, and the other one turns gray, along with switching out the content for the second view.

    After a little more development, my app will have a separate navigation stack for each tab; the back button will show when needed; the title of each view will switch out in the header; and smooth transitions will happen as I navigate between different views. Fonts, colors, gradients, and styles will all follow what an app should look like on that platform. By expanding folders in Xcode’s project navigator, I notice the ridiculous amount of files that were placed there for me. I have no clue what they do and honestly don’t really care, but they’re actually extremely important: They’re the files that made the development of my app so seamless.

    Hybrid App Development

    Honestly, though, I’m a web developer. My organization isn’t filled with Objective-C and Java developers ready to build multiple apps with the ultimate goal of just trying to be the same app (but built entirely differently, from the ground up). I have existing HTML/CSS/JS skills, and I want my app to hit not only Apple’s App Store, but Google’s Play Store and all the others. Instead of locking myself into each platform and having to learn and maintain multiple proprietary languages, hybrid app development makes more sense, given my skill set and my time constraints.

    Don’t let hybrid app development scare you. In its simplest form, a hybrid app is still just a web browser, but without the URL bar and back button. This means you can build a full-fledged app using HTML/CSS/JS but still have it work like a native app, with all the same superpowers, like accessing bluetooth, GPS, camera, files, device motion, etc. Hybrid apps offers the best of both worlds.

    Let’s Build A Hybrid App

    For my use-case, I’ve decide a hybrid app is perfect, so let’s fire up….wait, there is no Xcode for hybrid apps! Where do I get all those files that makes my app do app things? Where’s the built-in UI, cool animations, and smooth transitions? The disadvantage to hybrid app development is that those starting with the web platform have to start from scratch. It’s the Wild West, and each developer is on his or her own.

    I absolutely love the web platform. It provides a core set of tools to not only share information but consume it. However, the web platform offers only the basic building blocks for structuring content; styling and interacting with that content; and navigating between documents. The core of the web platform does not provide pre-packaged libraries like those in iOS and Android. At the lowest level, a web browser represents one “view” and one navigation/history stack. This is another area in which native apps have an advantage, and hybrid devs burn up time generating code to give browsers the ability to handle multiple views with multiple stacks.

    Hybrid app developers quickly find themselves dealing with countless issues just to get their heads above water: figuring out the CSS to fill 100% of the viewport, sticking the tabs on the bottom and hovering content, adding event listeners, switching active states for icons and views, keeping track of navigation stacks of each tab, implementing touch gestures, generating a common way to navigate and transition between view, using hardware accelerated animations for the transitions, removing 300ms delays, knowing when to show or hide the back button, updating and animating the header title, interacting with Android’s back button, smooth scrolling through thousands of items, etc. All of these things come with native SDKs. And as an app grows, it’ll seem as though recreating natural, native interactions is a constant uphill battle–all of which native developers rarely think about, because for them it was baked in from the start.

    I believe the solution is to use a framework/library that levels the playing field, giving hybrid developers a toolkit similar to that of native developers. Most developers have a sense of pride in writing everything themselves, and there are certainly plenty of use-cases in which frameworks and/or libraries are not required. But when it comes to hybrid app development, there is a whole world of common code being recreated by each developer, for each app, and that’s a lot of work and time to invest in something that native developers already get.

    Cordova (the guts to Phonegap) is the predominant open-source software to morph the web platform into a native app. But just like the web platform, it only offers the basic building blocks, rather than a built-in framework to start with.

    Frameworks and libraries amplify app development and allow devs to focus on how their apps work, not the logic of how apps work.

    Hybrid Development Frameworks: Hybrid’s Missing SDK

    I define frameworks and libraries as any software package that increases productivity. In my experience, hybrid developers’ main frustration lies not in creating their app, but rather in getting their app to work like an app, which is a subtle, yet significant difference.

    With the advent of development frameworks focused on hybrid app development, developers finally have that missing SDK that levels the playing field with native. Cross-platform frameworks that embrace HTML/CSS/JS allow web developers to take their skills to app development. To increase productivity, hybrid app development frameworks should not only stick to the standards with pretty CSS and markup; they should also provide a MVC for serious, large-scale app development by a team.

    Sworkit, a hybrid app built using the Ionic Framework, featured in the iOS App Store.

    Sworkit, a hybrid app built using the Ionic Framework, featured in the iOS App Store.

    Frameworks like the Ionic Framework provide a common set of logic used to create apps, which isn’t already baked into the web platform (full disclosure: I am a co-creator of Ionic and a core contributor to AngularJS Material Design). Rather than inventing yet another MVC, Ionic chose to build on top of AngularJS, which has proven itself to be a leader among popular front-end frameworks in the last few years. Ionic is backed by a large and active community, solid documentation, and its own command-line tool to increase productivity (the CLI isn’t required but is highly recommended).

    Ionic’s use of AngularJS directives to create the user-interface allows for fast development, but most importantly, it’s highly customizable, through its use of Sass and simple markup. If you’re unfamiliar with AngularJS, Ionic offers a great way to learn it quickly, via numerous examples and templates.

    Google’s Polymer project and Mozilla Brick are built on top of the cutting-edge Web Components specification. As with AngularJS directives, Web Components offer a great way to abstract away complex code with simple HTML tags.

    Other proven hybrid development frameworks that have been around longer and offer their own powerful MVC/MVVM include Sencha Touch and Kendo UI. Both frameworks come with a large list of built-in components and widgets that enable developers to build powerful apps that work on iOS, Android, BlackBerry, Windows Phone, and more.

    I do not consider front-end frameworks, such as AngularJS, Ember, and Backbone to be hybrid app development frameworks. While I highly recommend front-end frameworks for large-scale app development, they’re focused on the logic, rather than the user interface.

    Frameworks like Twitter Bootstrap and Foundation offer a great user interface and responsive design capabilities. However, CSS frameworks focus on the UI and a responsive design pattern; but a UI alone still requires each developer to recreate the way a native app “works.”

    App frameworks abstract away the complexity of building an app and offer developers both the core logic and the UI, similar to what iOS and Android provide. I believe it is important to embrace the web standards and the web platform at the core, so it can be easily run from Cordova and built for multiple platforms (including a standard web browser).

    Software Engineering: Still Required

    Hybrid app development frameworks have come a long way in the last few years, and they have a bright future ahead of them. However, Developing Hybrid Apps Still Requires Actual Software Engineering, just as developing native apps does. As in any form of web development, if only a few hours are put into a project, the result is rarely a highly polished and production-ready piece of work.

    Hybrid fans sometimes offer the impression that frameworks create a unicorn and rainbow filled wonderland during development, which may mislead new developers. Just because you can write once and deploy everywhere doesn’t mean you’re exempt from the rules of software development. Hybrid offers many benefits, but as with so many things in life, cutting corners does not produce quality results, so please don’t claim all is lost after minimal effort.

    Making An Accurate Comparison

    The comparison of a hybrid app without a framework to a native app isn’t a fair one. To accurately examine hybrid vs. native development, we need to analyze each method at the framework level (hybrid with a framework vs. native, like Ionic Framework vs. iOS or Polymer vs. Android). As for hybrid vs. native: It’s a matter of studying your use-case first, rather than a choosing a definitive level of abstraction over everything else. It all ends up as 1s and 0s anyway, so jumping up another level of abstraction (HTML/CSS/JS) may be the right fit for your use-case and organization.

    I often feel that opinions regarding hybrid app development were formed well before hybrid was ready for prime time. The world has quickly been transitioning to faster devices and browsers, as well as improved web standards, and there’s no signs of either one slowing down. There is no better time than now to leverage your existing web development skills and build quality apps by standing on the shoulders of hybrid SDKs.


  7. Introducing fxpay for in-app payments

    A while ago Mozilla announced navigator.mozPay() for accepting payments on Firefox OS. This was our first step toward helping developers do commerce on the web. It solved the problem of processing payments but what about the rest? Today we’re announcing an early peek at fxpay, a library for the rest of what you need as a developer to sell digital products in your app. This small JavaScript library (11kB minified) gives you some nice additional features on top of payment processing:

    • Work with a catalog of in-app products without hosting your own server
    • Securely verify each payment in one simple JavaScript callback
    • Restore previous purchases from receipts

    The mozPay() API is great if you need to integrate with an existing system but building a product catalog from scratch is a lot of work. If you have an idea for adding revenue to your app, why not quickly toss in some products and see what sells?

    The fxpay library is designed to get you selling as quickly as possible. Because it interacts with the Firefox Marketplace API you don’t need to manage code on your own server — you enter product details on Firefox Marketplace and call some JavaScript functions in your app to sell them.

    First: A Warning

    fxpay is in an early experimental state. We’re looking for your help to make it a concise, intuitive library which means the API might change rapidly. There’s a section below for details about how to get involved.

    Offer Some Products For Sale

    After running bower install fxpay (installation details), show some products for sale within your app using getProducts():

    // First, let's test with some fake products.
    fxpay.configure({fakeProducts: true});
    fxpay.getProducts(function(error, products) {
      if (error) {
      } else {
        products.forEach(function(product) {

    The code here would add a buy button for each product so that tapping the button would start a purchase. Here’s a simplistic example:

    function addBuyButtonForProduct(product) {
      var button = document.createElement('button');
      button.textContent = 'Buy ' +;
      button.addEventListener('click', function () {
                       function(error, product) {
          if (error) {
          } else {
            console.log( + ' bought!');

    That’s it. The call to fxpay.purchase() guides the user through payment via mozPay() and verifies the result on the Firefox Marketplace server. If you receive the callback without an error that means the purchase was verified and funds will be transferred to your account upon completion. It is safe to deliver the product.

    Try It Out

    Install an app on the Firefox OS Simulator using the App Manager and tap your custom buy button. Since this is a test with fake products, you’ll see a payment simulation screen. Tap Continue and your purchase callback will fire, allowing you to get your product delivery code working.

    Restoring Purchases

    When a user completes a purchase, a portable receipt is installed on their device behind the scenes. This is a cryptographically signed JSON object that proves ownership of the product. Each time the user returns to your application, you’ll want to check for any receipts so you can restore their purchased products. The fxpay library does the validation for you but you have to define a callback for when each product is restored like this:

      onerror: function(error) {
        console.error('init error:', error);
      onrestore: function(error, product) {
        if (error) {
          console.error('onrestore error:', error);
        } else {
          console.log( + ' restored');

    Just like the purchase callback, if you don’t get an error it means the receipt is valid; the user owns the product so you should make it available. You probably only need to run init() once when your app starts up.

    Publishing Your Application

    Once you get everything working with fake products, the next step is to submit your app to the Firefox Marketplace developer hub so users can install it. The submission process is detailed in the documentation; it includes entering bank account details to receive payouts and submitting real names and prices of the products you wish to sell.

    Once all of your products are in place and your app has been approved, set {fakeProducts: false} and the same code you see here will begin to work with real products. The getProducts() function will use your app’s origin to retrieve the configured products.

    Example App

    The fxpay library ships with an example app that you can install from the App Manager and play around with.

    Get Involved

    Do you have an idea for an app with in-app payments? Try it out. We’re announcing an early version of fxpay so we can make it work well for you, the developer. If something breaks or just feels awkward or if you have an idea to make the library better, get in touch!

    Going Further

    The Payments team at Mozilla is small (but mighty!). This release has a lot of missing features but we wanted to start getting early feedback. Here are a few ideas for features we’d like to add next:

    Support More App Types

    Right now, fxpay is limited to privileged packaged apps on mobile only. See all prerequisites. We’re working to open up access to other app types such as hosted apps and desktop apps.

    Receipt Recovery

    If a user loses their device or deletes the app they will lose their in-app purchase receipts. Those receipts are backed up on the Marketplace server but users don’t have an interface to reinstall them yet. We’re trying to figure out a way to do that in bug 1045228.

    Exact Product Prices

    Price points and currencies vary by mobile network but non-certified apps don’t have a reliable way to detect users’ networks. Currently you can’t display prices next to your custom buy buttons. We’d like to offer some solutions for this even if it’s just a manual currency selector. See bug 1063758.

    Product Assets

    This first release of fxpay is best suited for local content such as unlocking a level in a game. If an app were to distribute remote content such as a MP3 file as a ring tone, there would be no way to securely protect the contents of that file. We’ll be considering how to add support for this in bug 1063059.

    We’re planning lots of other stuff too!

  8. Enabling Voice Input into the Open Web and Firefox OS

    With the advent of smartphones triggered by iPhone in 2007, Touch became the primary mode of input for interacting with these devices. And now with the advent of wearables (and other hands-free technologies that existed before), Voice is becoming another key method of input. The possibilities of experiences Voice Input enables are huge, to say the least.

    They go beyond just merely interacting with in-vehicle devices, accessories and wearables. Just think of the avenues Voice Input opens up for bringing more technologies to more people. It’s enormous: Accessibility, Literacy, Gaming, VR and the list goes on. There is a social vibe there that definitely resonates with our mission at Mozilla detailed in our Mozilla Manifesto

    How it started

    Both current leading mobile OS/ecosystem providers of today- Apple & Google have their native experiences with Siri and “OK Google” (coupled with Google Now). We really needed an effort to enable Voice Input into the first ecosystem that existed – the open Web. Around MWC 2013 in Barcelona, when Desigan Chinniah introduced me to André Natal – Firefox contributor from Brazil, we had a conversation around this and we instantly agreed to do something about this in whichever way possible. Andre told me about being inspired from a talk by Brendan Eich in BrazilJS, so I did not have much convincing to do. :-)

    First steps

    We had numerous calls and meetings over the past year on the approach and tactics around this. Since “code wins arguments”, the basic work started in parallel with Firefox desktop and FxOS Unagi devices, later switching to Mozilla Flame devices over time. Over a period of the past year, we had several meetings with Mozilla engineering leads on exact approach and decided to break this effort into several smaller phases (“baby steps”).

    The first target was getting Web Speech API implemented, and getting acoustic/language modules integrated with a decoder and giving that a try. Lots of similar minded folks in Mozilla Engineering/QA & community helped along with guidance and code-reviews while Andre moonlighted (on top of his day job) with a very high focus. Things moved fast in past month or so. (Well, to be honest, the only day this effort slowed down was when Team Brazil lost to Germany in FIFA 2014. :-)) Full credit to André for his hard work!

    Where are we?

    Our current thinking is to get a grammar-based (limited commands) app working first and distribute it in our rich & diverse international Mozilla community for accent-based testing and enhancements. Once we have this stablilized, we will get into the phase 2 where we can focus more on natural language processing and get closer to a virtual assistant experience sometime in future that can give users voice based answers. There is lots of work to do there and we are just beginning.

    I will save the rest of the details for later and jump to the current status this month. Where are we so far?

    We now have the Web Speech API ready for testing and we have a couple demos for you to see!

    Desktop: Firefox Nightly on Mac

    Editor’s note: for full effect, start playing the two above videos at the same time.

    Firefox OS demo

    Come, Join us!

    If you want to follow along, please look at the SpeechRTC – Speech enabling the open web wiki and Bug 1032964 – Enabling Voice input in Firefox OS.

    So jump in and help out if you can. We need all of you (and your voices). Remember “Many Voices, One Mozilla”!

  9. Webapplate – Maintainable web app template for Firefox OS and Chrome Apps

    There are many powerful tools and technologies surrounding the Web, and we can reuse them to develop cross platform mobile and desktop apps, especially in light of installable apps appearing on platforms such as Firefox OS. This article looks at the best way to do this, and presents Webapplate, a powerful new template to help facilitate this.

    Why invent the wheel (for the new frontier)

    As is the nature of the whole web, web apps are simple to write but hard to get done right. Even though the Web doesn’t provide an SDK or simple ready-to-use templates like other mobile platforms, you can still come out with a workable web app from candidates like Mozilla Open Web Apps, Chrome Apps, or Apache Cordova. But developers who want to quickly build a web app usually take longer time than say, an iOS developer.

    Here is the state of web app support by those candidates:

    • Firefox (desktop), Firefox OS, Firefox for Android support hosted web apps. Those web apps could be hosted on a static or dynamic web server just like normal web sites. Hosted web apps don’t allow some certified web APIs such as the TCP socket API because of security concerns.
    • Firefox OS and Chrome (desktop) support packaged web apps with different APIs for different purposes, because currently they focus on different types of devices.
    • Cordova provides device adapters for many platforms, including Android, iOS and Firefox OS.
    • Google has its Cordova variant to adapt Chrome App’s specific APIs to run on Android devices.

    In quick summary, the web app concept is not totally unified yet, but powerful enough to compete with native apps. Currently packaged web apps are mainstream because of the security concerns with new web API’s. Mozilla is mainly focusing on exposing new web APIs to mobile devices, Google is developing new web APIs for desktop. Apache Cordova is a good container to expose web APIs to different platforms.

    To make things harder, provided examples are often focused on teaching you how to pick up new web APIs rather than utilizing proper web app concepts with your development process.

    I’ve had the chance to join the development of an evolving web app project called Gaia, the Firefox OS user interface. The Gaia project contains the very first Mozilla installable web app implementation, including apps for music, photo gallery, e-mail, calendar and much more. According to GitHub’s pulse monthly, there are about 850 commits per month to the Gaia web apps. In the Gaia project, Mozilla developers and community members devoted lots of time and effort to bring it from the prototype stage to a shippable product within 2 years, and iteratively make it a competitive option for smartphone consumers. As a living large web app project, there are many lessons that can be learned from it, and applied to general web app development.

    Introducing webapplate

    Like other software projects, there are many things beside commiting code to develop a web app, such as:

    • How to organize the source code
    • How to handle library dependencies
    • How to keep the coding style in convention
    • How to optimize web app load performance
    • How to unit/integrate test your web app
    • How to localize your web app
    • How to automate those processes

    Those are topics that need to be resolved to develop a quality web app. In Gaia we have addressed these issues by utilizing a bunch of build scripts (Makefiles).

    You may wonder why we didn’t use Grunt or gulp for building? The answer: at the time Firefox OS was started, these tools didn’t exist. And the module owner wanted to make the core build process run in a Firefox extension one day.

    For general web app development, we didn’t have to follow those constraints. And we could do some experiments rapidly by reusing 3rd-party tools and libraries. From 2013, I’ve initiated a side project called webapplate, the open-sourced web app template that attempts to make Gaia’s solutions compatible with emerging toolkits like npm, Grunt and Bower. It also tries to transport good practices from Gaia to make new web apps more maintainable.

    How to setup webapplate

    Webapplate utilizes many powerful tools. With node.js, Grunt, Bower, Karma, Mocha and l20n, we come out with a maintainable full stack and self-contained web app template with JavaScript. So you could just copy or download the webapplate from Github, and develop and deploy to a hosting server or correspondent web app store.

    You need to install node.js in your desktop first. With Node.js installed, you’ll have the npm tool to manage Node.js modules. Now run this command:

    $ npm install -g grunt-cli bower karma

    to install the primary tools.

    Grunt is a JavaScript task runner tool (like Make) and grunt-cli is its command interface. Gruntfile.js file is similar to Makefile, but written in Javascript.

    Bower is a management tool for the front-end libraries. It helps developer manage different library versions. In webapplate, Bower will download client side libraries into the public/vendor folder when you run

    $ bower install


    Karma is the test runner that runs test code for each of the browsers. karma.conf.js defines the detail settings to specify how the test runner goes.

    Next, enter the webapplate folder and run:

    $ npm install

    npm will reference package.json to install all dependent node modules. The command will trigger Bower to install client-side library dependencies as well.

    Then you are all set! What you get is:

    • Pre-commit lint checking
    • Firefox and Chrome web app-compatible templates
    • Library dependency management
    • Client-side localization framework
    • Unit test and mock framework
    • Deployable web server

    If you use Firefox nightly, you could open the webapplate/public folder as a packaged app in the WebIDE developer tool.

    WebIDE allows you to edit, debug or execute your web app in the Simulator or on the device, with your favorite Firefox Developer Tools.

    With the Chrome Apps & Extensions developer tool, you can import the webapplate/public folder as a Chrome App and check the UI on desktop.

    webapplate on Chrome devtool

    Pre-commit lint checking

    The very first good practice that Gaia and webapplate provide is git pre-commit lint checking.

    Since in Gaia every commit needs to get reviewed and verified by the module owner before the code is checked in, we have followed the Google JavaScript style conventions. At that time we used gjslint to test it. It sounds good but actually forcing people to follow the exact same discipline manually is hard; asking the reviewer to pick through those style errors is another waste of time. So some genius introduced a git pre-commit hook to check several kinds of lint errors when the developer tries to commit their code, and provide a whitelist for the code that isn’t fully lint-free but should be allowed. Currently in Gaia we have pre-commit checks for JavaScript, CSS and JSON! This is a big relief.

    Currently webapplate utilizes code quality and style checking for JavaScript, JSON via JSHint, JSCS and JSONLint.

    It has exactly the same settings as Gaia for JSHint and also comes with the whitelist. Gaia is also planning to migrate to jscs to replace gjslint. If you use git for version control, run:

    $ grunt githooks

    to bind the git pre-commit code style check to your development process.

    Firefox OS- and Chrome App- compatible templates

    Webapplate uses HTML5 mobile boilerplate as the template base, and adds web app install helpers, icon links and usemin annotation for web app optimization on top. The main web app source is located in the public/ folder. You could check the webapplate wiki to see the full webapplate structure.

    Currently, Firefox web apps use manifest.webapp and Chrome Apps use manifest.json as the manifest file. The syntaxes are mutually compatible, except the localization part (we’ll address this issue later).

    After you edit one of these files, use:

    # firefox to chrome
    $ grunt f2c


    # chrome to firefox
    $ grunt c2f

    to overwrite manifest.webapp with manifest.json, or viceversa.

    To generate a Firefox OS packaged app or Chrome App, run this command:

    $ grunt pack

    to package your web app to an uploadable zip file. With the default settings, webapplate-generated packaged web apps could be uploaded to the Firefox Marketplace and the Chrome App store.

    Library dependency management

    For Gaia we manage development tools via npm and generally don’t use many 3rd-party client side libraries. We host commonly-used libraries between apps in a shared/ folder, and then copy them in at build time via a build script.

    webapplate defines these libraries in package.json, uses npm to require build tools, and doesn’t assume any app framework (e.g. Backbone or Angular.js, or a UI framework such as Bootstrap.) Client-side libraries could be managed via Bower in bower.json.

    Client side localization framework

    Since web apps might be run without an Internet connection, we can’t count on the server to detect multiple languages. Currently Firefox OS uses navigator.mozL10n and Chrome Apps uses chrome.i18n for localization. Both of them are non-standard.

    In webapplate we take the l20n library to address the client-side localization issue. l20n is crafted by Mozilla and the developers are currently working on enhancing the Firefox OS localization framework as well.

    Check out index.html; the localization syntax looks exactly like what we used in Gaia:

    <h1 data-l10n-id="hello">Hello WebApplate</h1>

    The locale file however is in a different format, locales.en.l20n:

    <projectName "WebApplate">
    <hello "Hello {{ projectName }}">

    Also, check out the Multiple Language Support Framework section for how l20n is integrated with webapplate.

    Unit test and mock framework

    Gaia uses its own test-agent to trigger unit tests on Firefox. Gaia uses the Mocha test framework, Chai assertion library and the Sinon test helper library for unit tests.

    Webapplate uses the above unit test libraries plus the Karma test runner to run unit tests on all mainstream browsers.

    Deployable web server

    For developing Firefox OS hosted web apps, we need a working web server and maybe some dynamic web server support. Now that’s what we call the 21st century: it is possible to write server-side code in JavaScript as well.

    Running the command:

    $ grunt server

    will trigger the Express-powered server with django-like Swig template support. It’s been pre-configured for performance. Measure with YSlow and you’ll get a pretty good grade for your web site.

    Webapplate has been tested on some free dynamic web page hosting providers such as openshift, heroku and appfog. Check the deployment section to find out more details.

    If you like to host your web apps on a static web server, run:

    $ grunt static

    to generate optimized web pages for hosting.

    If you want to deploy your web app on a GitHub page (as a free static hosting server), run:

    $ grunt github

    Start your new web app project with webapplate!

    Webapplate is the web app template that borrows good practices for web app maintenance from the Gaia project. It provides ready-to-use Firefox OS and Chrome App support, an integrated toolbox to optimize your web app and maintain quality, and uses JavaScript through client/server side build/test frameworks. If you are about to make a web app or want to see how to maintain a web app, webapplate is a good start.


  10. PhoneGap Developer App preview for Firefox OS

    The cross-platform team at Mozilla is always looking for ways to improve how developers build apps with open web standards. We consider Cordova and PhoneGap to be great tools to achieve that. We are excited to work on improving support for PhoneGap by getting the PhoneGap Developer App into Firefox OS.

    The PhoneGap Developer App allows you to easily run PhoneGap apps in multiple platforms, without the need to install SDKs or have a developer subscription. The app is available for Android, iOS and Windows Phone at their respective app stores. You can pair your app with multiple devices at a time and any changes you make to your app’s code get propagated to all devices.

    Even though developing for Firefox OS does not require a beefy SDK or a developer subscription, being able to have your changes propagate to multiple devices at once is pretty cool!

    We have started working on support for Firefox OS and you can try it out today. In this post we’re going through the steps needed to get the preview version of the PhoneGap developer app in Firefox OS. As they say, a video is worth 1k images:

    Getting the dependencies

    We will be using a development version of Cordova combined with a development version of the PhoneGap command line interface to get it all working. Luckily, they are very compatible and work well together. You will need to have git, nodejs and npm installed before proceeding.

    Let’s first get all modules we’ll need from github:

      $ git clone
      $ git clone
      $ git clone
      $ git clone -b fxos
      $ git clone -b fxos
      $ git clone

    Now let’s set dependencies up:

      $ cd connect-phonegap
      $ npm link
      $ cd ../phonegap-cli
      $ npm link connect-phonegap
      $ npm install
      $ cd ../cordova-lib/cordova-lib
      $ npm link
      $ cd ../../cordova-cli
      $ npm link cordova-lib
      $ npm install
      $ cd ..

    Load the app to your device

    The app is available at phonegap-app-developer/platforms/firefoxos/www/, just point the app manager or webIDE to this path and load it to your device or simulator. Once you start the app, you should see a screen with an IP address. That’s where you enter the address of your server.

    Starting the server

    Let’s get the server going. It will serve your app’s content to the PhoneGap Developer App. Create a new Cordova app:

      $ cordova-cli/bin/cordova create myapp "I Heart PhoneGap Dev App"
      $ cd myapp

    Now we need to point cordova to the development version of cordova-firefoxos. In your root app folder, myapp in our case, create a folder named .cordova (with the leading dot) and add a file named config.json to the new folder with the following contents:

      "lib": {
        "firefoxos": {
          "uri": "/&lt;Full/Path/To&gt;/cordova-firefoxos",
          "version": "dev",
          "id": "cordova-firefoxos-dev"

    Make sure you have the correct full path to cordova-firefoxos in the uri property above.

    Time to start the server, we’ll switch back to PhoneGap for that:

      $ ../phonegap-cli/bin/phonegap.js serve

    You should see a line saying [phonegap] listening on Enter that IP in the PhoneGap Developer App and see your app start running there! Easy.

    Ship It!

    If you got this far, you’re probably asking why isn’t the app in the marketplace already! As you saw, to get all up an running we required the development version of the PhoneGap command line interface. Once a new version with our new code is released, we can publish the app and not require development version of the command line.

    If you have any questions leave a comment, find us at the #apps channel on IRC or send us an email at