Running React, Angular.js, Ember.js, … Locally on Android

Zafir Sk Heerah
3 min readNov 27, 2024

--

In this post, we’ll explore how you can run any JavaScript framework app — like React, Angular.js, or Ember.js — locally on an Android device. Using Ember.js as an example, we’ll discuss how to serve a statically built JS app with a lightweight local web server and run it in a WebView. You can check the full implementation on this GitHub repository.

Repository Overview

The GitHub repository contains the complete implementation of:

  • An Ember.js app pre-built into static assets.
  • A lightweight Android web server to serve those static files.
  • A WebView configuration to load and run the Ember.js app locally on an Android device.

Feel free to clone the repo for hands-on experimentation.

git clone https://github.com/zfir-dev/ember-android.git

How It Works

Here’s the high-level workflow:

  1. The Ember.js app is built and stored in the Android app’s assets/ember-dist folder.
  2. A lightweight web server, implemented in Java, serves these files locally.
  3. The WebView loads the app through the local server (http://localhost:8080).

Key Components

Ember.js App

The Ember.js app is pre-built using:

ember build --environment=production

The output is placed in the assets/ember-dist folder of the Android project. These files include:

  • index.html
  • app.js
  • styles.css
  • Other static assets.

The Ember.js app doesn’t require any external hosting since it is served locally on the device.

Web Server

The web server is implemented using NanoHTTPD, a lightweight HTTP server library. It serves the static assets from the assets folder.

Here’s an overview of the WebServer class, located in the WebServer.kt file:

Core Responsibilities:

  • File Routing: Routes incoming HTTP requests to corresponding files in the assets/ember-dist directory.
  • Dynamic MIME Type Detection: Ensures proper file rendering by assigning the correct MIME type (e.g., text/html, application/javascript).

Serve:

@Override
public Response serve(IHTTPSession session) {
String uri = session.getUri().equals("/") ? "ember-dist/index.html" : "ember-dist/" + session.getUri();

try {
InputStream inputStream = context.getAssets().open(uri);
String mimeType = getMimeType(uri);
return newChunkedResponse(Response.Status.OK, mimeType, inputStream);
} catch (IOException e) {
return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "File Not Found");
}
}

This method:

  1. Handles HTTP requests and determines the file to serve.
  2. Uses getMimeType(uri) to assign appropriate MIME types (HTML, CSS, JS, etc.).
  3. Returns the file content as a Response. If the file doesn’t exist, a 404 error response is returned.

MIME Type Detection:

private String getMimeType(String fileName) {
if (fileName.endsWith(".html")) return "text/html";
if (fileName.endsWith(".js")) return "application/javascript";
if (fileName.endsWith(".css")) return "text/css";
if (fileName.endsWith(".png")) return "image/png";
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) return "image/jpeg";
return "application/octet-stream";
}

This ensures the client (WebView) can correctly interpret and render the files.

WebView Configuration

The WebView is configured in the MainActivity.kt file. It connects the Ember.js app served by the local web server to the Android app.

Key Configuration:

  • Enable JavaScript: Allows the WebView to execute JavaScript.
  • Local Server URL: Loads the app from http://localhost:8080.
  • Optimizations: Settings like domStorageEnabled and useWideViewPort ensure smooth performance.
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("http://localhost:8080/");

This simple configuration is sufficient to load and display the Ember.js app locally.

Getting Started

To try it out:

  1. Clone the repository:
git clone https://github.com/zfir-dev/ember-android.git
  1. Open the project in Android Studio.
  2. Build and run the app on an Android emulator or device.

The Ember.js app will load in the WebView, served locally from http://localhost:8080.

Advantages of This Setup

  • Framework-Agnostic: Works with any JavaScript framework (React, Angular.js, Vue.js, etc.).
  • Offline Capability: No internet is required to run the app.
  • Performance: Static assets load instantly from the device.

Conclusion

This approach demonstrates how you can run a completely offline JS framework-based app on an Android device using a local web server and WebView. In this example, I am using Ember.js but this also works for React, Angular and other JS frameworks. For more details and the full code, check out the repository: github.com/zfir-dev/ember-android. Happy coding!

--

--

Zafir Sk Heerah
Zafir Sk Heerah

Written by Zafir Sk Heerah

Software Engineer | Consultant | Android and iOS Development | www.zfir.dev | blog.zfir.dev

No responses yet