Using Parse and Trigger.io for cross-platform apps without pain in the back-end

Your new mobile app looks beautiful. Great! But what about all the data storage, user accounts, push notifications and server-side goodness that will keep users coming back for more? Building all that back-end stuff from scratch can be a big job.

Luckily, you can wave away these problems by using Parse, who offer a complete back-end solution for mobile apps.

Trigger.io and Parse work great together. Use Trigger.io to build your native apps for iOS and Android, and also deploying to the web, by just writing HTML5 – and Parse to handle your back-end services. In fact, we’ve built Parse’s native libraries right into Trigger.io Forge so you can access their notification center integration from our JavaScript API.

Let’s take a look at how to set up Parse for your Forge apps. We’ll build a super simple iOS and Android photo sharing app that will allow

  • Uploading photos
  • Viewing a photo stream
  • Sending notifications when new photos are posted

We’ll do all this in a few lines of HTML and JavaScript. The project is hosted on github here.

Let’s get stuck in

To work with your JavaScript and CSS in the app, just include them in your index.html as you might in a normal website:

<link rel='stylesheet' href='css/parse-demo.css'>
<script type='text/javascript' src='js/lib/jquery.min.js'></script>
<script type='text/javascript' src='js/parse-demo.js'></script>

HTML pages don’t get much simpler than this:

<body>
    <button id='upload-photo'>Upload photo</button>
    <div id='photo-container'></div>
</body>

In our JavaScript we’ll set up an object to store our Parse account details (you’ll get these details when you sign up and create an app at parse.com). We’ll also store a name for our default photo stream, to make it easy to add extra streams later.

var config = {
    parseAppId: 'ggJShmbAJh7YTgviK3fpH4QdIIp9az6WMW03swf5',
    parseRestKey: 'Bqjru0vC610FCIl5isczzxjPlv5CsFe8uK0yztez',
    streamName: 'parse-demo'
};

Uploading photos

Let’s begin by looking at how to store photos in our Parse datastore. We first capture a photo using the forge.file.getImage API call.

forge.file.getImage({width: 500, height: 500}, function (file) {
    forge.file.imageURL(file, function (url) {
        $('#photo-container').prepend($('<img>').attr('src', url));
    });
    uploadPhotoFile(file);
});

This will prompt the user to take a photo from their camera or select one from an album. Rather than waiting to display it until the photo has been uploaded, we show it straight away by retrieving an internal url for the photo using forge.file.imageURL. We add an <img> tag with this url to the photo-container div in our HTML.

The upload then happens in the background by calling our uploadPhotoFile function. Let’s take a look at what this does.

var uploadPhotoFile = function(file) {
    forge.request.ajax({
        url: 'https://api.parse.com/1/files/' + (
            new Date()).getTime() + '.jpg',
        headers: {
            'X-Parse-Application-Id': config.parseAppId,
            'X-Parse-REST-API-Key': config.parseRestKey
        },
        type: 'POST',
        files: [file],
        fileUploadMethod: 'raw',
        dataType: 'json',
        success: function (data) {
            uploadPhotoMetadata(data);
        },
        error: function () {
            alert('Problem uploading photo');
        }
    });
};

Here we’re using the forge.request.ajax API to post our image to the the Parse file REST API (Forge allows for easy file uploading through this method, and also sidesteps any cross-domain restrictions where necessary). We authenticate by adding our Parse account information to the headers of the post request and add our photo file to the parameters.

Straightforward, right? But we’re not quite done yet. We might want to store some metadata for the photo (date, location, user, etc) and for that we need to create a Parse object. So if the file was uploaded properly, we call uploadPhotoMetadata with the JSON returned by the upload request.

var uploadPhotoMetadata = function(data) {
    forge.request.ajax({
        url: 'https://api.parse.com/1/classes/Photo',
        headers: {
            'X-Parse-Application-Id': config.parseAppId,
            'X-Parse-REST-API-Key': config.parseRestKey
        },
        type: 'POST',
        contentType: 'application/json',
        dataType: 'json',
        data: JSON.stringify({
            file: {
                '__type': 'File',
                name: data.name
            },
            stream: config.streamName
        }),
        success: function (file) {
            // Upload complete - do nothing
        },
        error: function () {
            alert('Problem uploading photo metadata');
        }
    });
};

Here we follow the same pattern, but this time create a bespoke Photo object (Parse objects are schema-less, so we can create new classes and fields on the fly). Here we create a new object containing the photo file name and the name of the stream to which it belongs. If the request is successful – hooray! We’re done. If not, we let the user know.

Viewing a photo stream

Next, we want to show users the stream of uploaded photos. We’ll call this function from the $(document).ready listener.

var getPhotos = function() {
    forge.request.ajax({
        url: 'https://api.parse.com/1/classes/Photo',
        headers: {
            'X-Parse-Application-Id': config.parseAppId,
            'X-Parse-REST-API-Key': config.parseRestKey
        },
        type: 'GET',
        dataType: 'json',
        data: {
            'where': '{"stream": "' + config.streamName + '"}',
            'order': '-createdAt'
        },
        success: function (data) {
            $('#photo-container').children().remove();
            data.results.forEach(function (photo) {
                $('#photo-container').append(
                    $('<img>').attr('src', photo.file.url));
            })
        },
        error: function () {
            alert('Problem reading photos');
        }
    });
};

By now, this should be starting to look familiar. We request all of our stream’s Photo objects, most recent first. Then we remove child elements from our photo-container and append <img> elements with the photos’ url. In a real app, you should separate the display logic (we’ve kept things deliberately simple here).

Sending notifications

Finally, want to let users know when new photos are posted (to close that all important viral loop). Push notifications need deep native integration on each platform, so we’ve integrated the Parse notification framework into our Forge JavaScript API.

Once you’re set up with your Parse account, pairing it up with Forge is easy. Just add your Parse app ID and client key to your app’s local config file:

"partners": {
    "parse": {
        "applicationId": "ggJShmbAJh7YTgviK3fpH4QdIIp9az6WMW03swf5",
        "clientKey": "Bqjru0vC610FCIl5isczzxjPlv5CsFe8uK0yztez"
    }
}

(If you’re developing for iOS, you’ll need to upload a certificate to Parse before enabling pushing. This process is described in Parse’s own tutorial.)

After this, you’ll be able to send push notifications right away from Parse’s online interface (click ‘Push Notifications’ on your app’s admin panel). Type your message in a text box to broadcast it to all your app’s users, or specified groups. You can also send raw JSON data.

In our app, we’ll listen for these notifications and simply alert the user to the contents of the message:

forge.event.messagePushed.addListener(function (msg) {
    alert(msg.alert);
});

If you want to send notifications programmatically, check out Parse’s notifications API to see how to do this.

Building and running the app

To build and run the app yourself, first grab the code. Then sign up on our website and install the Trigger.io Forge framework if you haven’t already and start the Forge environment (instructions here).

Then,

  • Create a new directory for your app, cd into it, and run “forge create” to create the app in your account
  • Copy the tutorial code into the src directory, over-writing the boilerplate code that forge created
  • Run forge build to create each version of the app (this is only slow the first time – subsequent builds are lightning fast!)
  • Run forge run android or forge run ios to see the app (you’ll need to have the Android Emulator or iPhone Emulator installed first – see our documentation for more details)
  • If you have your Android phone connected, forge run android will deploy the app to your phone for testing (make sure you have USB debugging on)
  • Enjoy!

That’s it

If you’d like to play more, we’re sure you can think of lots of extensions. You might also like to think about how to port it to backbone.js.

Parse is a great solution for a simple, platform-agnostic back-end – and we’ve made it super-simple to take full advantage of it with Forge as well. Parse is free in beta, so sign up and give it a go – let us know how you get on, with any questions, comments or troubleshooting at support@trigger.io.

What multi-platform means for viral loops

A friend came by our office (which is in one of the coolest startup office buildings in San Francisco by the way) last Thursday for a beer. He showed me a cool app he’d just discovered called Highlight which, this week, seems to be the breakout app at SXSW.

Highlight looks awesome

The app lets you discover who in your network is present at your current location.

Awesome.

Except not for me. I’d really like to try it – but can’t because I have an Android and it’s iPhone-only at the moment (being a cross-platform company, the team here at Trigger.io is pretty split between Android and iOS for our personal phones, with a single Windows Phone 7 lurking also).

What if they had a real web app also?

It’s not just about Android and iOS though - take a look at their landing page on the web. Now imagine if they had even a semi-functional version of the app available there as a web app using HTML5 geolocation.

If a user receives an invite to the app while on their laptop, they’re MUCH more likely to convert if they could get a taste of the value on the web first.

Now the guys at Highlight seem to be doing fantastically on iPhone only for now and I’m also sure an Android and maybe a web-app version will come along soon. How much faster do you think they’ll grow through word-of-mouth and in-app invites when that happens? Could it even be a Twitter-style success, which some commentators are saying is a thing of the past at least at SXSW?

Bake virality in from the start = bake cross-platform in

That’s Highlight, but what about your app? The damage caused to your viral loop by not being cross-platform could be the difference between going viral (e.g. a 1.1 k-factor):

And almost viral  (e.g. a 0.9 k-factor):

(thanks to Jon Radoff for the spreadsheet model for viral growth).

If you’re intent on baking in viral from the start, you need to bake in a cross-platform strategy from the start.

If this has inspired you to go cross-platform with Trigger.io, we now support ‘web’ as one of our target platforms with our newly released Build to Web feature. Enjoy, and email us at support@trigger.io anytime with questions.

 

Introducing ‘Build to Web’ – simple deployment of your mobile codebase as a web app

Last week, at the Launch conference, we announced a major new feature for the Trigger.io framework: Build to Web. Trigger.io is now the simplest way to build for both mobile and web from the same HTML5 codebase.

> forge create
> forge build
> forge run web
> forge package web

Trigger.io launched a couple of months ago as the simplest way for web developers to create native mobile apps from a single HTML5 codebase. (Not to sell ourselves short, that’s a huge deal.)

But what about the web?

We’ve already blogged about how consumer attention is shifting to apps and that web developers are going to have to make big changes to keep up. But the web is still hugely important – even for a mobile-first company. The fact remains you need somewhere to showcase your product to users who do not already have your app installed.

To maximise the conversion ratio of people arriving at your web site to active app users, you really want to give them a taste of your app’s features: your invitation for users to try the app on other devices is incredibly compelling if they have already tried it and loved it on a website first!

Now, with our new Build to Web feature, you can deploy your code as a web app just as easily as you built your code as native mobile apps before. Consider the web as another platform you can target with our Forge framework. You can create a rich application for the web proper, extending your app’s reach and audience with no need to write any more code.

Simple development workflow

Creating a web app alongside your mobile apps fits right into your Trigger.io workflow. Running forge build now creates a Node.js web app at the same time as iOS and Android apps. We’ve kept our build process lightning fast — after the initial build, your native and web apps can be re-built in just a few seconds. This makes iterative development really fast.

To test your web app locally, run forge run web and the app will open in a new browser tab. Whichever platforms you’re targeting, this is a great way to inspect the DOM and debug your Javascript, using standard desktop browser development tools.

When you’re ready to deploy your web app, run forge package web and your app will be deployed to Heroku from the command line.

Create powerful web apps using our JavaScript API and web proxy

Because it’s all the same codebase, you can take advantage of all our framework’s existing benefits. You can mash-up third-party APIs by using the Forge API to work around cross-domain restrictions (normal in-page JavaScript can only make XHRs to the same server as the one hosting the current page).

So what happens when your app expects native functionality, e.g. a camera or address book? You can show/hide the key parts of your app using our platform detection API.

if (forge.is.web()) {
    // invite the user to download your mobile app
    $('#download-pane').show();
} else {
    // Show camera button
    $('#camera-button').show();
}

Really simple back ends

And what about storing data remotely to share with others or your own accounts on other devices? We want to make this just as platform agnostic, fast and easy to implement as your app itself. That’s why we recommend using Parse as a lightweight database; their simple REST API for data storage is a perfect compliment to our mobile framework.

We’ll blog more soon with a tutorial on how to use Trigger.io and Parse effectively together.

A new way to develop apps

With Trigger.io Forge now able to deploy the same client-side code to both web and mobile, you can now cover all the important platforms for your app from a much smaller, single codebase. That’s a huge cost and time saving, even excluding the ongoing maintenance benefits.

Combining that capability with backends-as-a-service, such as Parse, a completely new way to develop apps is emerging. Write a single client-side codebase in HTML5, and use 3rd party services to get your data store, push notifications etc (in an increasing number of cases, without any server side code at all!). Then deploy your single code base to multiple mobile platforms and the web.

The result is the fastest and simplest process ever for web and front-end developers to create rich apps in a mobile world.

Questions/ideas? We’d love to hear from you on support@trigger.io or in the comments below.

How to build fast HTML5 mobile apps using backbone.js, zepto.js and trigger.io

Last week, we discussed how we made our Native Bridge 5x faster than PhoneGap. This week, we’d like to share some techniques for making your application code just as snappy.

For speed and responsiveness, we recommend backbone.js and zepto.js

To make this more fun, we’ve developed a little example project, using a CSS reset, Backbone.js and a couple of pages with transitions. Our project will display the Trigger twitter feed and individual tweets. As usual, we’ll create Android and iOS apps from a single HTML5 codebase. Along the way, we’ll show you how to:

  • include your JavaScript files in your app
  • use Backbone.js to present a responsive interface
  • use a CSS reset to reduce inconsistencies across platforms
  • implement an example transition between views in your app

Please feel free to base your own projects on this – it’s a great springboard for a new project! The code is hosted on github here: https://github.com/trigger-corp/Forge-Bootstrap.

Included files

  • Backbone.js to handle history, user actions, and to structure our JavaScript in general
  • HTML5 Boilerplate to reduce the impact of inconsistent rendering defaults on different platforms
  • Zepto, a light-weight, mobile-focussed alternative to jQuery, for DOM manipulation

Let’s get stuck in

To work with your JavaScripts and CSS in the app, just include them in your index.html as you might in a normal website:

<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/demo.css">

<script type="text/javascript" src="js/lib/zepto.min.js"></script>
<script type="text/javascript" src="js/lib/underscore-min.js"></script>
<script type="text/javascript" src="js/lib/backbone-min.js"></script>
<script type="text/javascript" src="js/demo.js"></script>

Here, we have simply used the HTML5 Boilerplate reset (reset.css), JavaScript libraries and two of our own files, demo.css and demo.js.

When using Backbone, your entry point should set up whatever your app requires to function, then start Backbone’s history system.

For example, in this project, we use $(Demo.init) to run the following function once, at app startup:

// Called once, at app startup
init: function () {
    // Grab the Trigger twitter feed
    forge.request.ajax({
        url: "https://twitter.com/statuses/user_timeline/14972793.json",
        dataType: "json",
        success: showIndex
    });

    // to be called once we have the Trigger twitter feed
    function showIndex(data) {
        // Save away initial data
        Demo.items = new Demo.Collections.Items(data);

        // Set up Backbone
        Demo.router = new Demo.Router();
        Backbone.history.start();
    }
}

Here we we use our request.ajax function to retreive our tweets, store the data into a collection then start Backbone.

Using Backbone.js

Backbone.history.start() kicks off Backbone’s window.onhashchange event subscription. When the fragment of the URL changes, the routes defined in routes.js are used:

routes: {
    "" : "index",          // entry point: no hash fragment or #
    "item/:item_id":"item" // #item/id
},

The routes map a URL to a function. We have two routes defined here: one that matches #index(), and one that matches #item/[item_id]item_id is then passed into item() as a parameter. Routes map out the URLs for your whole app.

Using Backbone to manage views inside a Forge app is a great strategy: not only do we build URLs in the history stack (meaning the back button works as expected on Android, for example), we are also able to take complete control over what is displayed in the app, without having to resort to sluggish page loads.

However, especially on mobile platforms, your users will expect some form of dynamic transition from one view to the next; to do that, you can organise your Backbone views into pages.

Page View

This snippet shows how we implement pages in this project, with an animated transition as one page becomes active. You can also see us using Zepto for DOM manipulation here.

Demo.Views.Page = Backbone.View.extend({
    className: "page",

    initialize: function () {
        this.render();
    },
    show: function () {
        $('.page').css({"position": "absolute"});
        var direction_coefficient = this.options.back ? 1 : -1;
        if ($('.page').length) {
            var $old = $('.page').not(this.el);

            // This fix was hard-won -
            // just doing .css(property, '') doesn't work!
            $old.get(0).style["margin-left"] = ""
            $old.get(0).style["-webkit-transform"] = ""

            this.$el.appendTo('body').hide();
            this.$el.show().css(
                {"margin-left": 320 * direction_coefficient});
            this.$el.anim(
                {translate3d: -320 * direction_coefficient +'px,0,0'},
                0.3, 'linear');
            $old.anim(
                {translate3d: -320 * direction_coefficient + 'px,0,0'},
                0.3, 'linear', function() {
                    $old.remove();
                    $('.page').css({"position": "static"});
            });
        } else {
            this.$el.appendTo('body').hide();
            this.$el.show();
        }
        window.scrollTo(0, 0);
    }
});

You can  this page in your own views if you wish, and use the show() method to switch from one to another.

For example, in this project, we create a page for the initial view of all the tweets, and a page for each individual tweet when the user selects it.

Using other parts of the Forge API

We have already seen the use of forge.request.ajax to make a request to a remote server. This project makes use of some other Forge APIs too.

In expand_item(), we use forge.tabs.open() to open an external page new tab in a cross-platform manner. Our documentation for open() is here.

Lastly, we use forge.is in the click_or_tap() function so that we can listen for tap events on mobile devices, but click events otherwise. Documentation for easy platform detection can be found here forge.is.mobile

click_or_tap: function(obj) {
    // for property in obj, add "click " to property and use original value
    var new_obj = {};
    for(var property in obj) {
        if (obj.hasOwnProperty(property)) {
            if (forge.is.mobile()) {
                new_obj["tap " + property] = obj[property];
            }
            else {
                new_obj["click " + property] = obj[property];
            }
        }
    }
    return new_obj
}

This is important because the click event is less responsive on mobile than tap.

Building and running the app

To build and run the app yourself, sign up on our website and install the Trigger.io Forge framework if you haven’t already and start the Forge environment (instructions here).

Then,

  • Create a new directory for your app, cd into it, and run “forge create -n Demo” to create the Demo app in your account
  • Copy the tutorial code into the src directory, over-writing the boilerplate code that forge created
  • Run forge build to create each version of the app (this is only slow the first time – subsequent builds are lightning fast!)
  • Run forge run android or forge run ios to see the app (you’ll need to have the Android Emulator or iPhone Emulator installed first – see our documentation for more details)
  • If you have your Android phone connected, forge run android will deploy the app to your phone for testing (make sure you have USB debugging on)
  • Enjoy!

That’s it

Have fun playing with the source for yourself. We hope everything is clear.

Still unsure? Want to ask for help? Spotted a mistake in this tutorial? Drop us a line at support@trigger.io and we’ll be happy to help.

Why Trigger.io doesn’t use PhoneGap – 5x faster native bridge

Firstly, our own native bridging technology is significantly faster – up to 5x on Android according to our testing below.

We wanted to design the best experience for web developers to create native mobile apps by having:

  • a super fast build-test cycle
  • no need to write any native code,
  • no need to setup your environment for local compiles,
  • no need to setup XCode and Eclipse

These design constraints mean that our approach includes a ton of small differences from PhoneGap, not just in our native bridge but in the code around it to provide the best possible API and best possible build process for developers coming from web technologies.

We’re not averse to using existing solutions, and working to promote them and improve on them, where it’s right for our customers (our Catalyst debugging tool is a hosted build of Weinre). PhoneGap is a great product with lots of flexibility to write your own platform-specific native code in conjunction with HTML5 (which is not something Trigger.io offers). Strobe and appMobi both decided to use PhoneGap rather than developing their own native bridge.

Performance

Speed is a big concern for developers considering HTML5 and hybrid frameworks as opposed to native. So how does Trigger.io’s native bridge perform in practice?

On iOS, compared with PhoneGap we saw that our bridge performed at a similar level to PhoneGap with a small increase in speed:

Performance results on iOS

Performance results on iOS

On Android it’s dramatically faster:

Performance results on Android

Performance results on Android

To test both native bridges we created a PhoneGap plugin for both Android and iOS which immediately responds to any call with the data sent to it. This allowed us to send varying amounts of data from JavaScript to native and back again. We also added an equivalent method to our own API. Adding a new method which does no processing means we can more accurately test the bridge itself rather than a particular API method. If you want to see the source code used for this benchmark you can find it on github.

How Trigger’s native bridge technology works

Since launch, we’ve been asked about how our bridge technology works. Our architectural approach has much in common with PhoneGap’s – but with some differences that reflect our different priorities and ways of thinking.

Here’s how it works.

Wrapping and bridging to native

Our native bridge is what allows your JavaScript code to communicate with native code, in a way that’s consistent across platforms. For mobile platforms, your code is outputted into a WebView / UIWebView mobile browser frame, and our wrapper grabs your API calls and ‘translates’ them as appropriate for each platform on the fly.

We deal with iOS and Android  in different ways:

iOS: JavaScript to Objective-C, and back again

To talk to native code from JavaScript, we take your API call, serialise and store it temporarily in the DOM. We then make a request to a fake URI (forge://…) which we intercept in native code – allowing us to read in and act upon the API call stored in the DOM.

To communicate from native to JavaScript, it’s no problem: iOS gives us an API called

UIWebView.stringByEvaluatingJavaScriptFromString

which lets us execute JavaScript directly in the context of the UIWebView.

PhoneGap use a similar method, which explains why our performance is comparable in the benchmarking we did.

Android: Java to JavaScript, and back again

Java on Android provides an interface for Javascript to access Java methods directly, the opposite way round to what can be done in Objective-C. We use this method to pass API calls from Javascript back to native code – PhoneGap used to use this method but now avoid it. Instead PhoneGap use Javascript prompt boxes which they intercept in Java and prevent the user from seeing. This approach is heavier and hackier, but a decision they made in order to sideline a bug in the Android 2.3 simulation. It’s not a bug that affects actual Android 2.3 devices, so we take this to be a bit of overkill.

For Java to Javascript communication we can cause Javascript methods to be called (but not get access to any data they return) using the following code:

WebView.loadUrl(“javascript:alert(‘Hello World’);”)

Using this we can tell Javascript that there are responses waiting to be returned from Java and use the more efficient Javascript to Java interface to transfer the data. An issue with the loadUrl technique is by default it will close the keyboard if the user is currently entering text – something which is very annoying if you happen to make an API call in the background. We managed to work around this issue by preventing Android from closing the keyboard while an API call is made. PhoneGap instead run a local HTTP server on the device in Java, and send JavaScript requests to that server. We find that approach too heavyweight, especially as on devices with a proxy configured it has to resort to polling every 50ms, a very inefficient method.

In practice: calling native functionality from JavaScript with Trigger

How does this look in practice? You don’t need to worry about what the bridge does – you simply call native functionality in through our Forge API (the full details of which are in our documentation).

Here’s what happens when you run a command to access the native camera:

Native bridge flow

Native bridge flow

Conclusion

We aim to keep our framework as lean as possible and making the development environment and build process simple. We want the start to finish of cross-platform app development to be as straightforward as standard web development.

As a result we opted to build our own, faster bridge to native, for more responsive apps and fast development.

Cross-platform and cross-continent: how Trigger came to be international with Y Combinator’s help

One of the more unusual attributes of Trigger as a company – for our relative youth and size – is that we’re already international, operating out of offices in San Francisco and London. Though it can be tough to operate as a single-team across an ocean and eight hours of time difference (we’ll cover a bit about how we work in a future post), our international split is largely a healthy one – and has brought some great benefits to our company.

Of the founding team, two – myself and James – are British, while Sahil is American. So we’ve had an international make-up from the start. And with Y-Combinator funding, other great investors and many of our customers in the US, it made total sense to setup the company in San Francisco. But London, apart from being an amazing city to live and work in, has fantastic talent and a burgeoning startup scene (about the oddly named ‘Silicon Roundabout’ at Old Street).

But getting to where we are now was tough, especially in setting up the legal, accounting and visa aspects. Without the help and advice of the many Y Combinator alumni, we couldn’t have done it. In fact, I’d go as far as to say that access to the YC alumni network has been our single greatest asset in building an international business.

For advice, knowledge and introduction – the value of that network is unparalleled, and alone worth YC’s stake in our business.

Cross-platform and cross-continent 

Having moved in the beautiful Storek in downtown SoMa about eight months ago, we opened our second office in London not long after (we recently moved across Old Street roundabout to new offices in Karen House, home to last.fm, Pusher, amongst others).

For one, we double up talent. Smart people are everywhere, and just one location can be limiting. Not only can you tap into more talent with a second office, but you’re able to offer much more flexibility to those you hire.

Second, we’re able to offer customer support across time zones and on a localized basis. For a company built on helping our customers, often delving into their code, that’s a huge benefit that we can pass on to our customer base – and rare for a company this young.

Third, we can benefit from the distance. That might sound strange, but it’s a hidden blessing. It’s certainly hard that, for much of the day, it’s not possible to hop on a quick call to talk something through – but hours apart can help us crack on with bigger projects without the temptations of micromanagement.

Still, face-to-face time remains unmatched. We fly employees between offices when we need do, and it’s always worth doing. The benefits of working shoulder-to-shoulder can’t be matched by regular Skype and email, and the serendipitous helping-out that can happen when you’re in the same room – it all breathes energy into the workplace.

Even better, when business is good, we’ll arrange company meetups somewhere new for both teams. Airbnb has been amazing for this – last year we rented places in Puerto Vallarta, Playa del Carmen (both Mexico) and Montreal for 10 day stretches to hack day and night and have a great time. It’s incredible fun for all, and a perk of the company – but it’s also one of the most productive times for us, and hardly a goof-off. Living under one roof, cooking each other meals, the team gets much stronger – and we reap the benefits then and for months after.

Working across the two offices is never going to be perfect – and it’s going to get tougher as we grow, no doubt – but we couldn’t run our company any other way. It’s in our DNA.

Starting Up

With all that said, it remains incredibly tough to set up business in the US. Even with the US funding behind us, and an American co-founder, options are surprisingly slim as the usual work visa – H1-B – is not suited for companies that are just starting out or for founders who have major stakes in the company. It doesn’t matter how many jobs you do or promise to create.

Luckily, we – Amir and James – secured O-1 visas, which are for ‘aliens of extraordinary ability’ in a particular field. If you meet 3 of the 9 criteria – supported by, for example, academic papers, patents, reference letters from the great and good in your field, being featured in the press (if not a Nobel Prize) – you’ll qualify and can apply for these. Hopefully, the proposed startup visa will make things more straightforward for future founders.

Still, you’ll need some help – starting an international business means not just securing visas, but a whole heap of legal and accounting paperwork and expensive corporate lawyers in an unfamiliar legal system. You’ll need to know the process inside and out, or lawyers can all too easily take you for a ride. All the while it puts your business on hold: getting in the way of a million other hurdles that come  with establishing a startup, making a good product and building a customer base.

And that’s where YC come in. It’s not just because YC offers great advice, operational support and kickstart funding: it’s the many, many founders – including British founders – who’ve been through it all before. It’s nobody’s job to set you up, but a nudge in the right direction can save you months of figuring it out for yourself.

That alumni network is truly YC’s greatest single benefit, and would alone be worth their stake.

Making cross-platform app development simpler, a first step

Today, we’re launching our Trigger.io Forge framework and announcing seed investment. A special shout-out to AngelList for making the fundraising process so efficient and allowing us to focus on product, thanks guys!

 

 

 

This is the result of a year’s work in private beta iterating on the needs of our early customers. And while there’s way more to do than we’ve already completed to make cross-platform app development simple, I am super excited to be working in this area and with this team and these investors.

Our goal is to give web developers the tools they need to access the $15Bn mobile applications market. We’ve designed our product to be the simplest way for web developers to create powerful, native mobile applications without needing to write any Java, Objective-C or native code.

While the mobile app market is already large driven by games, startups and consumer adoption, we think it’s only going to keep growing since mobile adoption is the gateway to the cloud for enterprise. Having multiple mobile software stacks is great for competition and choice but cross-platform development pains are an obstacle to this growth and we’re determined to remove as many as we can.

As well as the build tools and native wrapping technology, we’re also launching our hosted debug tool – Catalyst – which brings a Webkit-style debugger to mobile.

We’ll be posting every couple of weeks showcasing apps build using the Forge framework, and tutorials on various HTML5 and Forge best practices.

In the meantime, listen to me talk about Trigger and what it’s like to work here: