Build Native Mobile Apps on iOS & Android with Nothing but JSON
As a mobile app developer, you‘re probably used to building separate native apps for iOS and Android. You have to learn the intricacies of each platform, use different programming languages and tools, and often end up duplicating effort. But what if I told you there was a way to build sophisticated, native mobile apps for both iOS and Android using nothing but a JSON markup? A way that lets you express your entire app – from the UI to the application logic – in a single JSON file?
That‘s the promise of a new open source framework called Jasonette. With Jasonette, you define your app declaratively using a simple but expressive JSON format, and the framework takes care of translating that into a native iOS or Android app. There‘s no need to write any Swift, Objective-C, Java, or Kotlin code. Just good old JSON.
Let‘s take a closer look at how it works and what you can build with it.
Anatomy of a Jasonette App
At its core, a Jasonette app is just a JSON file that follows a certain structure and conventions. The top-level object has a "$jason" key which contains two main sections:
- "head" – this is where you define metadata about your app, like the title, icon, etc.
- "body" – this is where the meat of your app goes and you define the actual views and components that make up your app‘s UI
Here‘s a simple example:
{
"$jason": {
"head": {
"title": "My Cool App"
},
"body": {
"header": {
"title": "Welcome"
},
"sections": [{
"items": [
{
"type": "label",
"text": "Hello World!"
}
]
}]
}
}
}
This would produce an app with a header title of "Welcome" and a single vertically scrolling list with one item – a label that says "Hello World!".
Already you can start to see the power and simplicity of expressing an app‘s UI in JSON. But this just scratches the surface. Let‘s go deeper.
Design Philosophy
The Jasonette approach to defining UIs is based on a few key design principles:
- It should feel native on each platform
- It should be cross-platform
- It should be simple to understand but expressive enough to build complex UIs
To achieve this, Jasonette‘s JSON format combines common layout concepts from the web world, like vertical and horizontal stacking and absolute positioning, with native mobile UI paradigms like lists and grids.
The end result is a flexible layout system that maps well to the underlying native UI frameworks on iOS and Android (UIKit and Android Layouts respectively) while still being simple to express in JSON.
Building Blocks
Let‘s break down the main UI building blocks you have to work with in Jasonette.
Sections
A section represents a vertically or horizontally scrolling list of items. You can think of it like a UITableView on iOS or a RecyclerView on Android.
Vertical sections will automatically fill the height of the screen and let the user scroll through the items vertically. Here‘s an example:
{
"body": {
"sections": [{
"items": [
{
"type": "label",
"text": "Item 1"
},
{
"type": "label",
"text": "Item 2"
},
{
"type": "label",
"text": "Item 3"
}
]
}]
}
}
Horizontal sections work similarly but scroll horizontally instead of vertically:
{
"body": {
"sections": [{
"type": "horizontal",
"items": [
{
"type": "image",
"url": "http://i.giphy.com/l0MYB87QDWnXkalqM.gif"
},
{
"type": "image",
"url": "http://i.giphy.com/26BoCh3PgT1hWIOKA.gif"
},
{
"type": "image",
"url": "http://i.giphy.com/xUA7b0OQjKOLSZcFSo.gif"
}
]
}]
}
}
You can mix and match horizontal and vertical sections to create more complex layouts.
Items
An item represents an individual cell in a list. It can either be:
- An individual UI component like a label, image, button, etc.
- A vertical or horizontal layout composed of multiple components
Here are a few examples:
A single label item:
{
"type": "label",
"text": "Hello World"
}
A vertical layout item with multiple labels:
{
"type": "vertical",
"components": [
{
"type": "label",
"text": "Hello"
},
{
"type": "label",
"text": "World"
}
]
}
A horizontal layout item with an image and a label:
{
"type": "horizontal",
"components": [
{
"type": "image",
"url": "http://i.giphy.com/media/Vuw9m5wXviFIQ/source.gif"
},
{
"type": "label",
"text": "Mind Blown!"
}
]
}
You can think of items like miniature self-contained layouts that can be composed together. This maps conceptually to UIStackViews on iOS and LinearLayouts on Android.
Layers
Everything we‘ve seen so far has been constrained to individual items that scroll with their parent section. But sometimes you want to absolutely position elements on screen, independent of any scrolling. That‘s where layers come in.
With layers you can specify the exact coordinates of labels or images and position them anywhere you want on the screen. Here‘s an example:
{
"body": {
"style": {
"background": "#000000"
},
"layers": [
{
"type": "image",
"url": "http://i.giphy.com/l0K45RrWZflYAtJf2.gif",
"style": {
"width": "100%",
"height": "30%",
"top": "20%"
}
},
{
"type": "label",
"text": "In space, no one can hear you scream...",
"style": {
"bottom": "50",
"left": "50%-100",
"width": "200",
"color": "#ffffff"
}
}
]
}
}
This would position an image at the top of the screen taking up 30% of the height, and a label centered at the bottom.
As you can see, layers give you pixel-level control to build complex custom layouts.
Putting it All Together
By nesting and composing sections, items, and layers, you can create any type of UI you can imagine. The Jasonette website has some great examples of non-trivial UIs built entirely with JSON:
Looking at the JSON for these, you really get a sense for how expressive the markup can be. You can achieve pixel perfect designs that look and feel truly native.
Beyond Just a Pretty Face
So far I‘ve focused on the view layer and how Jasonette lets you express UIs with JSON. But Jasonette is much more than just a pretty face. Its markup lets you define your entire app – the view, the model, and the controller logic – all in a single JSON file.
On top of the UI components I described above, Jasonette also has:
-
Actions – these let you define event handlers that get triggered on user interactions, like tapping a button or pulling down to refresh a list. Actions can do things like make HTTP requests, modify the UI, transition to a new view, and more.
-
Templates – these let you cleanly separate your data from your presentation by defining reusable templates to populate your UI with data from a JSON payload.
-
$global – this is a special top-level object you can use to define app-wide styles, event handlers, templates, and other resources.
When you can define not just the look of your app, but also how it behaves in response to user input and changing data, all without leaving the JSON world, you‘ve got a powerful framework for building non-trivial apps.
App Ideas
Hopefully by now the gears are turning in your head with ideas for apps you could build using nothing but JSON. Here are a few thought-starters:
- A yelp-style restaurant review app that hits the Yelp API and displays the results in a Jasonette-styled UI
- A Pokedex app using the Pokemon API to display a master-detail view of different Pokemon and their stats
- A SoundCloud client using the SoundCloud API to let users browse and play tracks
- A weather app that pulls data from the OpenWeatherMap API and presents a 5-day forecast
Really though, the sky is the limit. Any app that‘s primarily focused on displaying data from an API and providing a way for users to interact with that data is a great candidate for Jasonette.
Conclusion
In a world dominated by native app development, Jasonette presents a refreshingly novel approach. By letting you define every aspect of your app with a simple JSON syntax, it dramatically lowers the barrier to entry for building cross-platform mobile apps.
Of course, there will always be a place for fully native apps built in Swift and Java for ultimate performance and control. But for a large class of apps that are primarily about presenting data and letting users interact with that data, the Jasonette approach can be a huge time saver.
So the next time you‘re thinking about building a mobile app, give Jasonette a look. With its powerful and expressive JSON-based syntax, you might be surprised at how much you can accomplish without writing a single line of native code.