Articles in this section
Vtiger Process Designer Vtiger Module Designer API Designer in Vtiger CRM Insights Designer Data Source Designer Vtiger Add-ons Publisher VTAP Release Notes VTAPIT - Command line tool VTAP Tables

VTAP - App Creator

This article guides you through the process of using the Vtiger Application Platform to create small applications.
A
Abdul Sameer
14 Jul, 2026 - Updated  3 months ago

Feature Availability

Vtiger Editions: One Professional | One Enterprise | One AI

Introduction

VTAP App Creator allows developers to build custom web applications within Vtiger CRM. These applications can extend CRM functionality, connect with CRM data, and support business-specific workflows beyond standard CRM configuration.

Using App Creator, you can create browser-based applications with standard web technologies such as HTML, CSS, and JavaScript, and publish them directly inside your CRM environment.

App Creator is useful when you want to:

  • Build specialized business applications for CRM users.
  • Create interactive interfaces tailored to specific workflows.
  • Display CRM data in custom layouts and visual formats.
  • Extend the CRM using lightweight front-end applications.

Benefits of App Creator

The benefits of using the VTAP App Creator are:

  • Build custom web applications directly within Vtiger CRM.
  • Extend CRM functionality for specific business use cases.
  • Create interactive user interfaces using standard web technologies.
  • Access CRM data from your applications.
  • Reuse third-party libraries and front-end frameworks.
  • Publish and distribute applications for CRM users.
  • Support both in-browser development and offline development workflows. 

In this article, you will learn about:

  • Creating an Application
  • Editing an Application

Key Terminology

Field Name

Description

Web Application

It is an application program that is stored on a remote server and delivered over the internet through a browser interface.

Framework

A framework in programming is a tool that provides ready-made components or solutions that are customized in order to speed up development.

Runtime

It is a stage of the programming lifecycle. It is the time that a program is running alongside all the external instructions needed for proper execution.

VCAP Runtime

The VCAP runtime is the VTAP application runtime that allows custom applications to interact with CRM data and application events.

VTAPIT

VTAPIT is a command-line tool used to develop, test, push, and publish VTAP applications from a local development environment.

Creating an Application

Follow these steps to create an application using VTAP App Creator:

  1. Log in to the CRM.
  2. Click the main Menu.
  3. Go to Platform.
  4. Select App Creator. The App Creator page opens. 
  5. Click +Add App. The Add App Creator page opens. 
  6. Enter or select the following information:
    1. Name: Enter a name for the application.
    2. Icon: Browse and select an icon for the application.
    3. Description: Enter a brief description explaining the purpose of the application.
    4. Status: Select the checkbox to mark the application as Active. Clear the checkbox to keep it inactive.
    5. Viewers: Select the users, roles, or groups who can view and access the application.
    6. Owner: Select the user who will be the owner of the application from the drop-down list.
    7. Editors: Select the users, roles, or groups who can edit and manage the application.
    Click Save.

A new application is created and is available in the List View.

Navigating the App Creator Editor

After you create and save an application, the App Creator editor opens automatically. This is where you build and manage the files required for your application.

The application is organized into two main directories:

  • Views
  • Resouces

views

  • The views folder stores the HTML files used to define the structure and presentation of the application.

resources

  • The resources folder stores the JavaScript and CSS files used to control application behaviour and styling.
  • You can create additional files or subfolders under these directories based on your project structure and naming convention.
  • To help you get started quickly, VTAP provides a default file structure.

Default Files in App Creator

  • Index.html - Use this file to define the structure and content displayed in the application.
  • index.js - Use this file to write JavaScript logic, interactivity, and dynamic behaviour.
  • Index.css - Use this file to define the style, layout, spacing, colours, fonts, and visual formatting of the application.
  • vcap.js - This file provides the VCAP runtime required for interacting with CRM records and VTAP application events.

Editing an Application

Follow these steps to edit the default application files:

  1. Log in to the CRM.
  2. Click the main Menu.
  3. Go to Platform.
  4. Select App Creator. The App Creator page opens. 
  5. Open the application from the Apps List View.
  6. Click views > index.html.
  7. Edit the HTML content as required.
  8. Press Ctrl+S to save the file.
  9. Click resources > index.js.
  10. Add or edit the JavaScript code as required.
  11. Press Ctrl+S to save the file.
  12. Click resources > index.css.
  13. Add or edit the CSS rules as required.
  14. Press Ctrl+S to save the file.
  15. Click Save and Publish to publish the application.

To launch the published application, use the following URL:

https://INSTANCE.od1.vtiger.ws/myapps/APPLICATION_NAME

 

Note: The above URL is a sample. Make sure to add your Instance address and Application name to run the application.

 

Now, let us consider a sample web application. 

Sample Application - Flipbook

Following is the script for a web application - Flipbook:

  • views/index.html
 
  • resources/index.js

VCAP.event.on('app.loaded', function(){

 

$("#flipbook").turn({

width: 400,

height: 300,

autoCenter: true

});

});

 
  • resources/index.css

.sample-flipbook{

width:400px;

height:200px;

-webkit-transition:margin-left 0.2s;

-moz-transition:margin-left 0.2s;

-ms-transition:margin-left 0.2s;

-o-transition:margin-left 0.2s;

transition:margin-left 0.2s;

}

 

.sample-flipbook .page{

width:200px;

height:200px;

background-color:white;

line-height:300px;

font-size:20px;

}

 

.sample-flipbook .page-wrapper{

-webkit-perspective:2000px;

-moz-perspective:2000px;

-ms-perspective:2000px;

-o-perspective:2000px;

perspective:2000px;

}

 

.sample-flipbook .hard{

background:#ccc !important;

color:#333;

-webkit-box-shadow:inset 0 0 5px #666;

-moz-box-shadow:inset 0 0 5px #666;

-o-box-shadow:inset 0 0 5px #666;

-ms-box-shadow:inset 0 0 5px #666;

box-shadow:inset 0 0 5px #666;

font-weight:bold;

}

 

.sample-flipbook .odd{

background:-webkit-gradient(linear, right top, left top, color-stop(0.95, #FFF), color-stop(1, #DADADA));

background-image:-webkit-linear-gradient(right, #FFF 95%, #C4C4C4 100%);

background-image:-moz-linear-gradient(right, #FFF 95%, #C4C4C4 100%);

background-image:-ms-linear-gradient(right, #FFF 95%, #C4C4C4 100%);

background-image:-o-linear-gradient(right, #FFF 95%, #C4C4C4 100%);

background-image:linear-gradient(right, #FFF 95%, #C4C4C4 100%);

-webkit-box-shadow:inset 0 0 5px #666;

-moz-box-shadow:inset 0 0 5px #666;

-o-box-shadow:inset 0 0 5px #666;

-ms-box-shadow:inset 0 0 5px #666;

box-shadow:inset 0 0 5px #666;

}

 

.sample-flipbook .even{

background:-webkit-gradient(linear, left top, right top, color-stop(0.95, #fff), color-stop(1, #dadada));

background-image:-webkit-linear-gradient(left, #fff 95%, #dadada 100%);

background-image:-moz-linear-gradient(left, #fff 95%, #dadada 100%);

background-image:-ms-linear-gradient(left, #fff 95%, #dadada 100%);

background-image:-o-linear-gradient(left, #fff 95%, #dadada 100%);

background-image:linear-gradient(left, #fff 95%, #dadada 100%);

-webkit-box-shadow:inset 0 0 5px #666;

-moz-box-shadow:inset 0 0 5px #666;

-o-box-shadow:inset 0 0 5px #666;

-ms-box-shadow:inset 0 0 5px #666;

box-shadow:inset 0 0 5px #666;

}

 

Click Save and Publish, and launch the application to see it in action.

Sample Application - Traffic Clock

Here is a prototype to represent time in a traffic signal theme. We will implement this in VTAP using a step-by-step process to understand the design of components and reuse the same.

 

 

Before implementing the application, identifying the data and visual scope makes it easy to structure the application. We have time (hour, minute, second) to be displayed as text (left side) and boxes (right side).

 

The boxes should further highlight the elapsed value and the remaining value.

 

Elapsed hour

Remaining hour

 

So our data structure would be like

 

elapsed: {

    hour: A,

    minute: B,

    second: C,

}

 

Box UI can be created using a span element:

 

.box {

    display: inline-block; /* to make it work without content */

    width: 16px;

    height: 16px;

    margin: 2px;

    border: 1px solid black;

}

 

We will be using VueJS to enable binding the Visual and Data rendering.

 

Now let's create the traffic_clock application in VTAP

 

Iteration - 1

Let us first get the timer display on HTML that changes every second.

 

views/index.html

< !DOCTYPE html>

< html>

    < head>

        < title>Traffic Clock< /title>

        < meta charset="UTF-8">

        < meta name="viewport" content="width=device-width, initial-scale=1.0">

        < link rel="stylesheet" href="resources/index.css">

    < /head>

    < body>

        < div id="app" v-cloak>

            < div class="hour">{{elapsed.hour}}< /div>

            < div class="minute">{{elapsed.minute}}< /div>

            < div class="second">{{elapsed.second}}< /div>

        < /div>

        < script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js">< /script>

         < script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js">< /script>

        < script src="resources/index.js">< /script>

    < /body>

< /html>

CTRL+S (Save the file)

resources/index.js

 

window.addEventListener('DOMContentLoaded', function() {

new Vue({

el: "#app",

data: function() {

                                        /* Initialization */

var d = new Date();

return {

elapsed: {

hour: d.getHours(),

minute: d.getMinutes(),

second: d.getSeconds()

}

}

},

mounted: function() {

setInterval( () => {

var d = new Date();

this.elapsed.hour = d.getHours();

this.elapsed.minute = d.getMinutes();

this.elapsed.second = d.getSeconds();

}, 1000);

}

});

});

CTRL+S (Save the file)

 

Publish the changes. Launch the application.

 

 

Iteration - 2

 

Let us now get the boxes displayed representing elapsed and remaining value of hour, minute, second.

 

views/index.html

 

< !DOCTYPE html>

< html>

    < head>

        < title>Traffic Clock< /title>

        < meta charset="UTF-8">

        < meta name="viewport" content="width=device-width, initial-scale=1.0">

     < link rel="stylesheet" href="resources/index.css">

    < /head>

    < body>

        < div id="app" v-cloak>

            < div class="hour">

               {{elapsed.hour}}

               < span class="box hour elapsed" v-for="h in elapsed.hour">< /span>

               < span class="box hour" v-for="h in (24 - elapsed.hour)">< /span>

            < /div>

            < div class="minute">

               {{elapsed.minute}}

               < span class="box minute elapsed" v-for="m in elapsed.minute">< /span>

               < span class="box minute" v-for="m in (60 - elapsed.minute)">< /span>

            < /div>

            < div class="second">

               {{elapsed.second}}

               < span class="box second elapsed" v-for="s in elapsed.second">< /span>

               < span class="box second" v-for="s in (60 - elapsed.second)">< /span>

             < /div>

        < /div>

        < script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js">< /script>

        < script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js">< /script>

        < script src="resources/index.js">

    < /body>

< /html>

CTRL+S (Save the file)
 

resources/index.css

 

.box {

display: inline-block;

width: 16px;

height: 16px;

margin: 2px;

border: 1px solid black;

}

 

.hour.elapsed {

background: red;

}

 

.minute.elapsed {

background: orange;

}

 

.second.elapsed {

background: green;

}

CTRL+S (Save the file)

 

Publish the changes. Launch the application.

 

 

Iteration - 3

 

Let us now build a custom VueJS boxes component that takes care of representing the elapsed and remaining value. This will help us reduce HTML repetition as the component can be reused for hour, minute, and second by varying the inputs to the component through attributes (type, value, and max).

 

views/index.html

 

< !DOCTYPE html>

< html>

    < head>

        < title>Traffic Clock< /title>

        < meta charset="UTF-8">

        < meta name="viewport" content="width=device-width, initial-scale=1.0">

     < link rel="stylesheet" href="resources/index.css">

    < /head>

    < body>

        < div id="app" v-cloak>

            < div class="hour">

               {{elapsed.hour}}

               < boxes type="hour" :value="elapsed.hour" :max="24">< /boxes>

            < /div>

            < div class="minute">

               {{elapsed.minute}}

               < boxes type="minute" :value="elapsed.minute" :max="60">< /boxes>

            < /div>

            < div class="second">

               {{elapsed.second}}

               < boxes type="second" :value="elapsed.second" :max="60">< /boxes>

             < /div>

        < /div>

        < script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js">< /script>

        < script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js">< /script>

        < script src="resources/index.js">

    < /body>

< /html>

 

CTRL+S (Save the file)

resources/index.js

 

window.addEventListener('DOMContentLoaded', function() {

    Vue.component("boxes", {
        props: ["type", "value", "max"],
        template:\`< div style="display:inline-block">

                < span :class="type" class="box elapsed" v-for="v in value">< /span>

                < span :class="type" class="box" v-for="v in (max - value)">< /span>

            < /div>\`
    });

    new Vue({
        el: "#app",
        data: function() {
            /* Initialization */
            var d = new Date();
            return {
                elapsed: {
                    hour: d.getHours(),
                    minute: d.getMinutes(),
                    second: d.getSeconds()
                }
            }
        },
        mounted: function() {
            setInterval( () => {
                var d = new Date();
                this.elapsed.hour = d.getHours();
                this.elapsed.minute = d.getMinutes();
                this.elapsed.second = d.getSeconds();
            }, 1000);
        }
    });
});

CTRL+S (Save the file)

 

Publish the changes. Launch the application.

 

 

Iteration - 4

Continue the journey to match the expected representation.

Reference 

Related articles
May 2021 July 2021 VTAP Release Notes Data Source Designer API Designer in Vtiger CRM
Home Privacy Policy Terms of Service Security Center Policy & Legal Center Contact Us
© Copyright 2025 Vtiger. All rights reserved.
Powered by Vtiger
Facebook Twitter Linkedin Youtube