Structure of an Ionic App

posted in: Uncategorized | 18

If you have never used Ionic, or Angular for that matter, the structure of an Ionic app may be completely new to you. Coming from JQuery world, there was a bit of a learning curve for me personally, but once you wrap your mind around the concepts, it quickly becomes a very powerful toolset.

One thing to keep in mind that may help is to remember that at it’s heart, Angular was built with MVC style frameworks in mind, meaning if you have ever built with MVC on the server-side, the concepts should already be familiar.

In this article, I will give an overview of the basic structure of an Ionic Hybrid app and how each piece is used to build amazing apps.


ionic architecture

An Ionic App can be broken down into 5 major pieces: Views (Made from templates), Controllers, Data (Services and Factories, App Configuration, and Directives. The Views, Controllers, and Data are the most recognizable pieces from a MVC perspective (They are exactly what you think they are), and you can probably guess what App Configuration is.


Views in an Ionic App are often referred to as templates because Angular controllers refer to them as such. Because of this, views are often stored in a /templates folder where each view is in a separate .html file. A view is where the markup for state, or page, of your app lives. In Ionic, these files tend to look something like this:

<ion-view title="About">
	My super cool content here!

The title attribute is used for other Ionic directives such as the ion-nav-bar.

These views can use data binding, similar to frameworks like handlebars.

<ion-view title="About">
	My super cool content here! My name is {{name}}

{{name}} would be a variable that has been defined to the $scope in the controller.

$ = "Andrew";

So the template, once data bound, would say “My super cool content here! My name is Andrew”;

These views can also use ionic directives, angular logic (like if statements), loops, and more.

Read More: Creating Views with Ionic


The controllers are the brains behind the app, where the flow of logic and data is controlled. When you go to a “page” in Angular, you are really calling a controller. The controller will use a view as a template for the markup it will show to the user (hense, templates) and make calls to the data layer classes (factories/services) to get the actual data to bind to the template. The controller assigns this data to a $scope variable, which is then binded to the view. The $scope is an object that contains data defined by the controller used to build the view.

For example, I go to page which will call the mySuperPage controller (mySuperPageCtrl). The controller is configured to use the superpage.html template which looks like this:

<ion-view title="About">
	My super cool content here! My name is {{}}.

My controller needs to talk to the awesomeService class to get the user variable and assign it to the $scope.

.controller('MainCtrl', function($scope, $stateParams, awesomeService) {
	$scope.user = awesomeService.getUser();

We are assuming getUser will return an object with a “name” property.

var user = {
	name: "Andrew";

When the page is called, the controller will take the user variable that has been assigned to the $scope, and data bind it to the template. In this case, the template is calling the “name” property of the “user” $scope variable. This would result in:

<ion-view title="About">
	My super cool content here! My name is Andrew.

Read More: Controllers in Ionic/Angular

Data (Factories/Services)

The Data layer of an Ionic app is the provider of data, usually from a external backend or web service. The controller requests the data from the Data layer to use in binding to the view. These Data layer classes are known as Services or Factories. The difference? Read here. At the end of the day, they more or less serve the same purpose. For the sake of simplicity, we’ll just refer to them both as a “data class”.

A data class generally will make some kind of http call and return a promise which when resolved contains the data received. Angular uses the $http module which will look very familiar to anyone coming from a JQuery background:

$http.get("some url here");

If you want to process the data before returning it back to the controller, you can do so when the promise is resolved and then return data that will get passed back in a promise.

$http.get("some url here").then(function(response){
	//Do stuff here
	return response;

So, a data class may look something like this:

.factory('awesomeService', function($http) {
	return {
		GetUser: function() {
			  return $http.get("some url here").then(function(response) {
					//Process Stuff Here
					return response;

Which when used in the controller would look something like this:

.controller('MainCtrl', function($scope, $stateParams, awesomeService) {
		$scope.user = response;

Read More: Ionic: Using Factories and Web Services for Dynamic Data

App Configuration

The App Configuration states configures the app… thanks, captain obvious. More specifically, the routes, or states, of the app are specified, hooking up a controller to a template (view). A default route is also specified. An example .config from the ionic-starter-tabs project:

.config(function($stateProvider, $urlRouterProvider) {

    // setup an abstract state for the tabs directive
    .state('tab', {
      url: "/tab",
      abstract: true,
      templateUrl: "templates/tabs.html"

    .state('tab.dash', {
      url: '/dash',
      views: {
        'tab-dash': {
          templateUrl: 'templates/tab-dash.html',
          controller: 'DashCtrl'
	// if none of the above states are matched, use this as the fallback


In simple terms, the $stateProvider sets up each page or view of your app and links it with a controller.


From the Angular Docs for Directives: “directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.”

To put this even more simply, Directives can either just be a attribute/class that triggers custom behavior on an element, or in some cases, they act a lot like custom elements. For example, in Ionic, all of the ion-* tags are custom directives that come with the Ionic framework.


In the Ionic source, there is a directive that is coded against any element with the name ion-list.

IonicModule.directive('ionList', [ '$timeout',
function($timeout) {
  return {
    restrict: 'E',
    require: ['ionList', '^?$ionicScroll'],
    controller: '$ionicList',
    compile: function($element, $attr) {
	//... etc ...

There is alot there, but there are two key parts to pay attention to.

restrict: 'E',

The restrict parameter tells the directive if it is looking for an attribute, element, or class.

‘A’ – only matches attribute name
‘E’ – only matches element name
‘C’ – only matches class name
‘AEC’ – matches either attribute or element or class name

In the case of the ion-list, we are looking for the element that matches.

You’ll notice that the directive is called ionList instead of ion-list. The directive is smart enough that it considers ion-tab and ionTab to be the same thing.


In an Ionic App, a controller gets data from one or many services/factories and then data binds it to a view/template. The app config glues the controller to the view/template. Directives are elements with customized behavior.

Special Thanks

Special thanks to Max Lynch (@maxlynch) for a technical review of this post to make sure everything was factually correct. 🙂

More Reading

Creating Views with Ionic
Controllers in Ionic/Angular
Ionic: Using Factories and Web Services for Dynamic Data
Modules in Ionic/Angular
Ionic: Master Detail Pattern
“Models” and “Collections” in Ionic and Angular

My name is Andrew McGivery. I currently work full time as an application developer at Manulife Financial in Canada. My current passion is building and leading highly engaged teams where employee happiness, learning, and growth is a priority.

18 Responses

  1. This was very helpful. Thank you.

  2. […] I covered in my Structure of an Ionic App post, a typical Ionic app has a Data Layer which uses Factories or Services to provide data to the […]

  3. Nice post, congratulations

  4. […] Using Factories and Web Services for Dynamic Data Structure of an Ionic App Creating Views with Ionic Original Question/Answer on Stack […]

  5. […] Structure of an Ionic App Ionic: Using Factories and Web Services for Dynamic Data Angular Module Docs Angular Structure: Refactoring for Growth Andrew McGivery My name is Andrew McGivery. I work full time as a Web/Portal Developer in the System Integration and Innovation department at Conestoga College in Canada where we focus in Research and Development for new projects, concepts, and technologies. […]

  6. Nice post ! thanks

  7. Michel van Geel

    Thanks for this clear overview! Nice interesting other links in your page as well!

  8. Hi thanks for the tutorial.
    But I want to ask, with this structure how do you handle producing the production code. That is when you bundle and minify your project for deployment.
    When looking at some web projects they have a src folder which then contains a dev folder for development code and a dist folder for the final/deployment code. My question is how do you handle it for ionic.


    • It really depends on your process. If you are using a build tool like Grunt, you may decide to have a temp, build, or dist folder where you have your tool place the production files.

  9. This is a really helpful and clear explanation of an Ionic app structure. Thank you very much!

  10. You made my day! After looking for a solution to bind data via JSON for three days, I stumbled across your page and voilà: wroks like a charm!

  11. Excellent write up – thank you!

  12. Awesome! Coming from a .Net MVVM background, this helps alot!

  13. great posts thanks

  14. Cheers, this is one of the best overviews of Ionic that I’ve come across on the web.

Leave a Reply