So far the only known application type is watchface - presumably the music app is also an app but it is built in to the firmware.



As of 2013-02-15, the Pebble Android and iPhone apps load a webpage with a list of watchfaces from


The list of watchfaces as of 2013-02-22 is:

Of these, the most useful for analysis are big-time-12 and big-time-24 as they should be nearly identical and watchfaces are not encrypted.

File Structure

Each watch face is a ".pbw" file and is a standard zip file. All current watch faces consist of three parts; manifest.json, pebble-app.bin, and app_resources.pbpack.


This file appears to be generated by Pebble's internal SDK. It is useful for double-checking parsing of the other files as it contains CRCs and duplicate metadata.


This file appears to have some custom Pebble-centric headers (such as the name of the application) followed by a binary. The definition according to the 'pebble_app_info.h' file in the SDK:

typedef struct __attribute__((__packed__)) {
 char header[8];                   //!< Sentinal value, should always be 'PBLAPP\0\0'
 Version struct_version;           //!< version of this structure's format
 Version sdk_version;              //!< version of the SDK used to build this app
 Version app_version;              //!< version of the app
 uint16_t size;                    //!< size of the app binary, including this metadata but not the reloc table
 uint32_t offset;                  //!< The entry point of this executable
 uint32_t crc;                     //!< CRC of the app data only, ie, not including this struct or the reloc table at the end
 char name[APP_NAME_BYTES];        //!< Name to display on the menu
 char company[COMPANY_NAME_BYTES]; //!< Name of the maker of this app
 uint32_t icon_resource_id;        //!< Resource ID within this app's bank to use as a 32x32 icon
 uint32_t sym_table_addr;          //!< The system will poke the sdk's symbol table address into this field on load
 uint32_t flags;                   //!< Bitwise OR of PebbleAppFlags
 uint32_t reloc_list_start;        //!< The offset of the address relocation list
 uint32_t num_reloc_entries;       //!< The number of entries in the address relocation list
 struct __attribute__((__packed__)) {
   uint8_t byte0;
   uint8_t byte1;
   uint8_t byte2;
   uint8_t byte3;
   uint8_t byte4;
   uint8_t byte5;
   uint8_t byte6;
   uint8_t byte7;
   uint8_t byte8;
   uint8_t byte9;
   uint8_t byte10;
   uint8_t byte11;
   uint8_t byte12;
   uint8_t byte13;
   uint8_t byte14;
   uint8_t byte15;
 } uuid;                           //!< The app's UUID
} PebbleAppInfo;

The current sizes of 'name' and 'company' are 32:

#define APP_NAME_BYTES 32

The version info consists of 2 bytes. One for the major version, and one for the minor version:

//! Version data structure with minor & major versions: When making non-backwards-compatible changes,
//! the major version should get bumped. When making a change (e.g. to the PebbleAppInfo struct) that is backwards
//! compatible (e.g. adding a field at the end), you should only bump the minor version.
typedef struct __attribute__((__packed__)) {
 uint8_t major; //!< "compatibility" version number
 uint8_t minor;
} Version;

The end of the .bin file contains the timestamp and crc of the pbpack file, CRCs of the resources, references to external (system) resources / fonts, the app version & app title, but the format is unknown.


This file has the same format as the app_resources.pbpack in firmware updates.