A couple of years ago Java was the de-facto technology for writing platform independent applications. Nowadays developers can write their applications in JavaScript and run it on any platform (OS X, Linux and Windows). 

Google took this cross-platform technology to another level with Google Chrome Apps, which allowed apps to run anywhere users can run the Chrome browser. This means that the applications written as Chrome Apps can run on all the traditional operating systems, plus mobile platforms (Chrome apps use Cordova for supporting mobile) and chromebooks. One of the apps that I love to use for testing my APIs, Postman, is a Chrome App too.

The exciting thing about this is that Google Chrome Apps can be developed using JavaScript. Imagine if you created a Single Page Application (SPA) that worked seamlessly on the website, while an app with the same code base and logic, and a similar look and feel would work on desktop and mobile also. This means you would have the same codebase available for all the platforms, which can be a huge competitive advantage on the market.

In this guide, I will present how to create a new Google Chrome App, gaText. The source code for the application is hosted on GitHub, you can find it in the gaText repo. The application is a minimalistic notepad replacement where you can create, open, and save text files.

Building blocks

A Chrome App has four important elements: the manifest file, a background script, icons, and all the code files that implement the application logic

The manifest file

Each Google Chrome App has to have a file called manifest.json. This is a standard JSON configuration file.  The first property in the file is the manifest_version; for Chrome Apps this should have the value 2, but it can have a value of 1 for Chrome Extensions as well.

The name property stores the name of the application. The description and the version are self-explanatory. The minimum_chrome_version specifies what version of Google Chrome the app need to run correctly. The icons object stores the paths for the different size of icons. In the example below, I only have two sizes specified: a 16x16 pixel and a 128x128 pixel.

{
  "manifest_version": 2,
  "name": "gaText",
  "short_name": "gaText",
  "description": "A simple text editor.",
  "version": "0.0.1",
  "minimum_chrome_version": "38",
  "icons": {
    "16": "assets/icon_16.png",
    "128": "assets/icon_128.png"
  },
  "app": {
    "background": {
      "scripts": [
        "background.js"
      ]
    }
  },
  "permissions": [
    {
      "fileSystem": [
        "write"
      ]
    },
    "storage",
    "webview"
  ]
}

The app object holds the so-called background script, which is responsible for starting the application. If you are familiar with native desktop application development in WPF or JavaFX, then this can be thought of as the main method that displays the main window of your application.

Permissions is again a very important part of the manifest where you add all the necessary modules that your application uses.  These require user permission—for example, the storage API needs user permissions because it can make changes to the filesystem.

The background script

The background is responsible for starting the application and setting the startup properties of the application. The source code for this is in the background.js file.

chrome.app.runtime.onLaunched.addListener(function (launchData) {
    chrome.app.window.create(
        'index.html',
        {
            id: 'mainWindow',
            bounds: {width: 950, height: 550}
        }
    );
});

For this application, the background.js file only contains an event handler attached to the onLaunched event of the Chrome App. The event listener is a function where you can create the main window of your application. The main page for the window is the index.html file. The second parameter of the create method takes the startup arguments for the application, like the id of the main window and the size of the opening window.

Index.html

For the application styling, I used bootstrap along with cerulean theme. Since Chrome Apps are running locally and these are running as native desktop applications, it’s a best practice to include the dependent JavaScript files into your application package. This allows the app to be used even if the user does not have a valid Internet connection.


The structure of the application is shown on the image. There is no predefined structure, so you can arrange your folders and files as you wish. The only limitation is that the icons should be accessible in the assets folder.

I have added a css folder, which holds the bootstrap styling, the stylesheet for the theme, and a styles.css that contains some overrides for the bootstrap classes.

The index.html file is in the root folder of the application, as shown below:

<!DOCTYPE html>
<html>
<head>
    <title>gaText Editor</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/bootstrap-theme.min.css">
    <link rel="stylesheet" href="css/bootstrap-cerulean.min.css">
    <link rel="stylesheet" href="css/styles.css">
</head>

<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
                    aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li><a href="#" id="btnNewFile">New File</a></li>
                <li><a href="#" id="btnOpenFile">Open File</a></li>
                <li><a href="#" id="btnSaveFileAs">Save as</a></li>
            </ul>
        </div>
        <!--/.nav-collapse -->
    </div>
</nav>

<div class="container" id="content">
    <div class="row">
        <div class="col-md-12">
            <textarea id="textContent" placeholder="enter text here" rows="20" cols="100"
                      autofocus=autofocus></textarea>
        </div>
    </div>


</div>
<script src="thirdParty/jquery-1.11.3.min.js"></script>
<script src="thirdParty/bootstrap.min.js"></script>
<script src="main.js"></script>
</body>
</html>

Hire A Freelancer In Seconds

Looking to get some work done? Hire the world's best Designers, Developers, and Copywriters in just a few clicks.

Greg Bogdan
Greg Bogdan Hire Me

Software Engineer, Blogger, Tech Enthusiast

I am a Software Engineer with over 7 years of experience in different domains(ERP, Financial Products and Alerting Systems). My main expertise is .NET, Java, Python and JavaScript. I like technical writing and have good experience in creating tutorials and how to technical articles. I am passionate about technology and I love what I do and I always intend to 100% fulfill the project which I am ...

Hire Me

Next Article

Creating a Contact Form for Your Website [Quick Tutorial]