Create powerful mobile apps with just HTML, CSS, and Zepto.js (or jQuery).

  • By Sencha Labs
  • Last update: Dec 29, 2022
  • Comments: 15


Create powerful mobile apps with just HTML, CSS, and Zepto.js (or jQuery).

Build Status

jQTouch is a JavaScript plugin which works with either Zepto.js or jQuery, and comes with smooth animations, navigation, and themes for mobile WebKit browsers (as found in iOS, Android, BlackBerry, and WebOS).

  • Easy to install. Get up and running in a few minutes.
  • Entirely customizable with selector options
  • Theme support, including default Apple and jQTouch custom themes
  • Callback functions throughout, including swipe and orientation change detection
  • Zepto integration - Use Zepto.js instead of jQuery to cut down on precious bandwidth. Zepto.js features a similar API to jQuery, but optimized for WebKit and much smaller.
  • Sass-based stylesheets, easily modified with variables and optimized for size.
  • Image-less stylesheets -- Using Compass Recipes, we have recreated all of the gradients and background patterns with CSS. This way, they are resolution independent, dynamically theme-able, and lower bandwidth.
  • Page history management and CSS3 page transitions, including 3D flip, cube, and swap
  • Failover to 2D animations for devices that don't support 3D
  • Easily allow apps to run in fullscreen mode with custom icons and startup screens
  • The power of jQuery to build AJAX applications
  • New demos: Clock and Todo

Getting Started

The easiest way to try out jQT is with the demo archive, which can be found in the release tab on Github:

Please look for the download (green button) with filename prefixed with jqt-demo (ie, jqt-demo-<< version >>.tar.gz.)

Once unzipped and untar, you can open package/demons/index.html with any WebkitBrowser on a desktop.


Recently added features can be found at New and Noteworthy page.

Source code, issue tracking, and documentation are available on github.

Watch this video preview to see it in action.

Building your own version of jQTouch


We have quite a few dependencies at the moment, as we build with Compass/SASS for stylesheets, which is only available via Ruby. The actual build system, however, is built on Grunt.

Please make sure you have the following installed:

  • Ruby — Comes default on Macs, Windows users can use RubyInstaller
  • Sass & Compass — Install both with sudo gem install compass once you have Ruby/RubyGems installed
  • Node.js & NPMbrew install node
  • Grunt CLI — Install with npm install -g grunt-cli once you have Node.js as listed above.
  • Local node packages — Run npm install from this directory


grunt (default)

Will create a build of jQTouch in the build/ directory, compiling any theme files and updating with source from the Zepto submodule. This must be run to preview jQTouch.

grunt build

This task is used only for iterative development. It does not update submodule, nor clean the build. (The default grunt task must be called once before this task.)

grunt watch

Will create the same build as grunt build, but will continue to watch for file changes to theme and source files, compiling/copying them into build every time you save. If you have a livereload browser extension installed and enabled, the page will update live after every change. (The default grunt task must be called once before this task.)

grunt compass

Only build the theme files. Typically, you'll want to use grunt watch for developing a custom theme. (The default grunt task must be called once before this task.)

grunt test

Run our test suite. (The default grunt task must be called once before this task.)

grunt dist

This is typically used internally for creating releases — It does everything the standard build does, but then additionally minifies all JS/CSS and updates the paths in demo files.

External Guides

Jonathan Stark has created an excellent introduction to jQTouch as part of his book, Building iPhone Apps with HTML, CSS, and Javascript.

PeepCode did a screencast ($9), as well as a cheat sheet, which have been helpful to many people.


Created, and still occasionally maintained, by David Kaneda.

Maintained by Thomas Yip.

Special thanks to pinch/zoom and Jonathan Stark.

(c) 2009-2013 Sencha Labs.

jQTouch may be freely distributed under the MIT license. See LICENSE.txt for license.



  • 8

    Using jqtouch on a normal website (not mobile) and getting a scroll i cant stop..

    Although i do know jquery enough to tinker with any code i come across, i tried using jqtouch for a website (to show a list of buttons/links that will reveal info on each link), to also make it friendly for the mobile devices. However, with each click on any link that links to another div inside the document, it will scroll the page up to 0 of the main jqt div. This might be needed for mobile devices but its definitely not needed for a "real" website and it looks like there is something broken. I am using the latest version of jqtouch and although i commented all scrollTo(0,0) lines it still scrolls. I could make it stop by commenting other lines of code, but then other problems came up. So, is there an easy way for me to remove that scrolling to the top? Its the only thing i still need to fix to complete this page!

    btw, jqtouch is excellent and i love it :D

  • 9

    type error in vanilla.css

    Line 1262 in vanilla.css has content : '>'; which produces an unintended default. Line 1262 in vanilla.css should have content : ">"; which will yield the intended character.

  • 10

    href click sometimes opens in new page


    I have some links <a href="http://...." > tags inside <div> <ul> <li>, and they appear as 'buttons' (jqt theme) on my main page. When I click the link it will get data from the webserver which is a formatted html <div> with content.

    • Sometimes the new <div> is inserted in the DOM and I will get a page transition.
    • Sometimes the new <div> opens in a new page

    jQTouch 1.4.2 Revision 150 Safari 5.0.2 (7533.18.5) Mobile Safari iPod Touch 3.1.3

    edit: I found that whenever I left click on the href, a new page opens in the same window, when I middle click the mouse, the page opens correctly (sliding to the correct div).

    edit2: Tested again with jquery 1.3.2 and that one works. Note that I use <div id="jqt"> with 1.4.2 but not with 1.3.2. When switching the version I also switch the extensions and themes.

  • 11

    back button obscured

    Back button has the left arrow portion of the button going the wrong way which obscures the text. Both android 2.2 and firefox desktop browsers exhibit the problem. You can view it here:

    Looks ok on 4.0 android

    Only the "ck" shows on the button.

  • 12


    Could you please suggest any good and complete documentation or tutorial for JQT? The code look a bit outdated and could not find documentation newer than eight years ago. Also, the external guides mentioned in the readme file are not more available. I was mainly searching for a way to create header and footer and menu icons on them.

  • 13

    Double tapping a link for an external page breaks the app (custom fix inside)

    jQTouch already stops taps when animating from one page to another, but it doesn't when tapping an element that triggers an ajax page load, so tapping such element twice results in broken element bindings and ugly animations.

    To fix this, read below, but first apply the fix for #524.


    // jqt.js
      name: "external",
      isSupported: function(e, params) {
        return true;
      fn: function(e, params) {
        var animation;
        animation = getAnimation(params.$el);
        $body.addClass("external-loading"); // FIX
        params.$el.addClass("loading active");
        showPageByHref(params.$el.attr("href"), {
          animation: animation,
          callback: function() {
            $body.removeClass("external-loading"); // FIX
            return setTimeout(function() {
              return params.$el.removeClass('active');
            }, 250);
          $referrer: params.$el
        return false;
    // _core.scss - inside the #jqt selector
    // Make sure nothing is tappable when loading external pages
    &.external-loading:after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        z-index: 10;
  • 14

    Internal showPageByHref() not calling callback functions (custom fix inside)

    Internal showPageByHref function doesn't take into account the callback parameter:

    For example, this callback found on jQT itself won't work:

    showPageByHref(params.$el.attr("href"), {
      animation: animation,
      callback: function() {
        return setTimeout(function() {
          return params.$el.removeClass('active');
        }, 250);
      $referrer: params.$el

    Here's the original showPageByHref with my fix applied (again, I'm not familiar with CoffeeScript, so can't do a pull request:

    showPageByHref = (function(_this) {
      return function(href, options) {
        options = $.extend({}, {
          data: null,
          method: "GET",
          animation: null,
          $referrer: null
        }, options);
        if (href.charAt(0) !== '#') {
          return $.ajax({
            url: href,
            type: options.method,
            success: function(data) {
              var firstPage;
              firstPage = insertPages(data, options.animation);
              if (firstPage) {
                if (options.method === "GET" && _this.settings.cacheGetRequests === true && options.$referrer) {
                  return options.$referrer.attr("href", "#" + firstPage.attr("id"));
              // FIX START         
              if (options.callback && typeof options.callback === "function") {
              // FIX END
            error: function(data) {
              if (options.$referrer) {
                return options.$referrer.removeClass('active');
        } else {
          if (options.$referrer) {
            return options.$referrer.removeClass('active');
  • 15

    goTo() no longer support external urls (custom fix inside)

    Hello, I'm hoping this project has still a little support from the community. I've switched from a pre-coffeescript version of jqtouch to the latest one, and I am having troubles porting my app.

    The main issue is that the goTo method, that once supported both IDs and urls, now gives an error.

    With Zepto:

    > jQT.goTo('mobile/projects')
    zepto.js:261 Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Document': '/mobile/projects' is not a valid selector.
    zepto.js:261 zepto.qsa
    zepto.js:188 zepto.init
    zepto.js:218 $
    jqt.js:243 (anonymous function)
    VM4881:2 (anonymous function)
    VM4846:847 InjectedScript._evaluateOn
    VM4846:780 InjectedScript._evaluateAndWrap
    VM4846:646 InjectedScript.evaluate

    With jQuery 2 + jqtouch-jquery2.js:

    > jQT.goTo('mobile/projects')
    jquery-2.1.3.js:1453 Uncaught Error: Syntax error, unrecognized expression: mobile/projects
    jquery-2.1.3.js:1453 Sizzle.error
    jquery-2.1.3.js:2070 Sizzle.tokenize
    jquery-2.1.3.js:850 Sizzle
    jquery-2.1.3.js:2690 jQuery.fn.extend.find
    jquery-2.1.3.js:2798 jQuery.fn.init
    jquery-2.1.3.js:76 jQuery
    jqt.js:243 (anonymous function)
    VM4896:2 (anonymous function)
    VM4894:847 InjectedScript._evaluateOn
    VM4894:780 InjectedScript._evaluateAndWrap
    VM4894:646 InjectedScript.evaluate

    Any cue?