Cordova hybrid apps - How to structure your codebase
Tags: cordova, architecture, javascript
Published: 2019-02-23 00:00:00

---
date: "2019-02-23"
title: "Cordova hybrid apps - How to structure your codebase"
description: A suggested codebase architecture for a cordova hybrid app without losing connection to the cordova cli tools
tags: "cordova, architecture, javascript"
published: true
canonical_url: https://www.learningsomethingnew.com/cordova-hybrid-apps-how-to-structure-your-codebase
cover_image: "https://www.learningsomethingnew.com/cordova-hybrid/shark.jpg"
---
## The problem
A cordova hybrid app necessitates changing the generated native project, thereby breaking the ability to use cordova cli features like adding plugins, updating cordova etc.

## Some definitions

### Cordova
Cordova let's you build cross platform mobile apps, while designing the UI using web technologies (html/js/css). 
The app runs in a native WebView which is basically a browser. 
The inner cordova browser allows access to native device capabilities through *cordova plugins*. These have a js side and a native side (java/kotlin/swift/objective-c/whatever).

### Cordova CLI
CLI tools that generate native platform projects from your web app. 
They add the cordova platform logic, and are used to add plugins, update the platform, generate packaged app store installations etc. 

### Normal cordova app
The usual way of loading the app's UI is *locally* with `file:///` protocol. So you build a static website, deploy it to the device, and the WebView loads the website from the local device's folder. Accessing the server is done via ajax/sockets.

![local](https://www.learningsomethingnew.com/cordova-hybrid/local-loading.png)

### Hybrid cordova app
But wait, if cordova gives us a browser, and we've already built a responsive website, why not load that website inside our cross platform app? 
This approach is called *hybrid*, and often involves some extra layer of native UI like a menu or settings screens apart from the main WebView.
> Notice that loading remote content isn't officially supported by cordova, but in some cases it's ok. More about this in my next post.

![remote](https://www.learningsomethingnew.com/cordova-hybrid/remote-loading.png)


## Breaking the link
In order to add your own UI layer like a menu or settings screen to your *hybrid* app, you need to take the generated platform project, let's say android, and add stuff to it.
But there's the rub, because the cordova cli tools will override those changes next time you build the platform. Directly editing the generated platform files is [discouraged](https://cordova.apache.org/docs/en/latest/reference/cordova-cli/index.html#platforms) for this reason. 


### Why you don't want to break the link
If you start changing the generated project, you no longer use cordova cli to:
- add plugins. manually adding plugins is a headache.
- get new versions of the cordova platform
- get security updates


## A suggested architecture

My current way of designing the code base structure is the following:
- Generate a native project with `cordova platform add`
    - This generates the project under `/platforms/<platform-name>`
    - Everything under `/platforms` is ignored by source control.
- Copy the generated native project to `<platform>-project` (`android-project` or `ios-project`)
    - Make your native changes in that folder. 
    - This folder will be source controlled.
- Write a task for generating the platform project and updating your native project

![edit](https://www.learningsomethingnew.com/cordova-hybrid/edit-this.png)

### The "generate" task

You can use some task runner like gulp or grunt (I use grunt) to keep the project in sync. 
The task will (to take an android platform for example):
- Copy your modified files from `android-project` to `temp`
- Build the platform with `cordova build android`
- Copy `/platforms/android` to `android-project`
- Copy and replace from `temp` to `android-project`

This way you always have a working Android Studio project in the `android-project` folder, which is source controlled, but still have the ability to update cordova and add plugins using the cordova cli.

### Comparison with embedded WebView approach
In the [cordova website](https://cordova.apache.org/docs/en/latest/guide/hybrid/webviews/index.html) they describe an approach to embedding WebViews which is to basically create a project and add a cordova WebView manually.
I like the approach described here better for several reasons:
- You don't have to create a project from scratch, integrate cordova jar files manually etc.
- You get to use cordova cli's scaffolding and folder structure, which is subject to change/update.
- Easy plugin installation/removal with cordova cli.
- Easy cordova platform updates. 

## Next steps
In future posts I'll show the creation of a sample project actually implementing all this, stay tuned :)

> This is a cross-post from my [blog](https://www.learningsomethingnew.com/cordova-hybrid-apps-how-to-structure-your-codebase)