DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to the story
WATCHRANKER
Connect IQ

How to Create a Garmin Watch Face From Scratch

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To create a Garmin watch face from scratch, build a Connect IQ Watch Face with Garmin’s SDK and the Monkey C language. The practical workflow is: choose target watches, install the Connect IQ tools, create a Watch Face project, draw and test the face in the simulator, sign and build it, then sideload the resulting .PRG file to a compatible Garmin watch.

This guide covers a coded, installable application—not Garmin’s Face It photo-customization tool, editing an existing native face, or designing a visual mock-up without implementing it in code.

As an Amazon Associate I earn from qualifying purchases.

Before you write code, choose the watches you will support

A Garmin watch face is not drawn on one universal screen. Garmin products differ in resolution, dimensions, color depth, display technology, memory, supported APIs, and power behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start with one exact model, or a small group of closely related models. Decide whether you will support:

#1 Best Overall
Sale
Garmin vívoactive® 5, Health & Fitness GPS Smartwatch, 42mm, Ivory | 24/7 Health Monitoring, Built-In Sports Apps, Sleep Coach, Body Battery™ Energy Monitoring, Workout Benefit & Recovery Time
  • Designed with a bright, colorful AMOLED display, get a more complete picture of your health, thanks to battery life of up to 11 days in smartwatch mode (5 days display always-on)
  • Body Battery energy monitoring helps you understand when you’re charged up or need to rest, with even more personalized insights based on sleep, naps, stress levels, workouts and more (data presented is intended to be a close estimation of metrics tracked)
  • Get a sleep score and personalized sleep coaching for how much sleep you need — and get tips on how to improve plus key metrics such as HRV status to better understand your health (data presented is intended to be a close estimation of metrics tracked)
  • Find new ways to keep your body moving with more than 30 built-in indoor and GPS sports apps, including walking, running, cycling, HIIT, swimming, golf and more
  • Wheelchair mode tracks pushes — rather than steps — and includes push and handcycle activities with preloaded workouts for strength, cardio, HIIT, Pilates and yoga, challenges specific to wheelchair users and more (data presented is intended to be a close estimation of metrics tracked)
  • MIP: low-power memory-in-pixel displays, usually designed around minute-by-minute updates.
  • AMOLED: brighter, more colorful displays with special always-on and burn-in restrictions.
  • Both: possible, but likely to require different layouts, resources, and rendering strategies.

Supporting every Garmin model increases layout, compatibility, resource, and testing work. Select products later with Monkey C: Edit Products, but make the design decision first.

Garmin’s watch-face UX guidance warns that a design suitable for an eight-color display may not scale well to a 64-color, LCD, or AMOLED product.

Install the development tools

Garmin’s official development stack consists of:

  • Connect IQ SDK Manager.
  • Connect IQ SDK. Garmin lists SDK 9.2.0 as the latest SDK as of August 18, 2026.
  • Visual Studio Code.
  • Garmin’s Monkey C extension for Visual Studio Code.
  • Oracle Java Runtime Environment 11 or later, as required by the current Monkey C extension documentation.
  • A Garmin Connect account.
  • A compatible Garmin watch for physical testing.

Install the SDK through the SDK Manager and make sure the extension can locate the selected SDK and Java installation. You do not necessarily need the newest SDK for every project: choose the lowest minimum API level that provides the features you need, then confirm that your target products support it. A newer SDK can generally build for older supported API levels, but newer APIs and devices are not universally available.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Generate and protect your developer key

Connect IQ applications must be signed. Garmin requires an RSA 4096-bit developer key for compiling and packaging apps.

In Visual Studio Code, open the Command Palette and run Monkey C: Generate a Developer Key. Store the key outside your project if practical, protect it carefully, and keep a secure backup. Never commit it to a public repository.

Garmin’s documented command-line alternative is:

openssl genrsa -out developer_key.pem 4096
openssl pkcs8 -topk8 
  -inform PEM 
  -outform DER 
  -in developer_key.pem 
  -out developer_key.der 
  -nocrypt

The same signing key is required for updates to an existing Connect IQ Store app. Losing it can prevent normal updates to that published application. Keep a record of which key belongs to each app.

See Garmin’s getting-started documentation and security guidance.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a Watch Face project

  1. Open Visual Studio Code.
  2. Open the Command Palette with Ctrl+Shift+P on Windows/Linux or Command+Shift+P on macOS.
  3. Run Monkey C: New Project.
  4. Enter a project name.
  5. Choose Watch Face as the project type.
  6. Choose the Simple template.
  7. Select a minimum API level.
  8. Choose the parent directory.

Garmin’s beginner tutorial uses API level 3.2.0 as an example. Treat that as a tutorial example, not a universal requirement. A lower API level can improve compatibility; a higher one may be necessary for newer APIs.

After creation, run Monkey C: Edit Products and select the watches you intend to support. The project normally contains:

Rank #2
Sale
Garmin vívoactive® 5, Health & Fitness GPS Smartwatch, 42mm, Black | 24/7 Health Monitoring, Built-In Sports Apps, Sleep Coach, Body Battery™ Energy Monitoring, Workout Benefit & Recovery Time
  • Designed with a bright, colorful AMOLED display, get a more complete picture of your health, thanks to battery life of up to 11 days in smartwatch mode
  • Body Battery energy monitoring helps you understand when you’re charged up or need to rest, with even more personalized insights based on sleep, naps, stress levels, workouts and more (data presented is intended to be a close estimation of metrics tracked)
  • Get a sleep score and personalized sleep coaching for how much sleep you need — and get tips on how to improve plus key metrics such as HRV status to better understand your health (data presented is intended to be a close estimation of metrics tracked)
  • Find new ways to keep your body moving with more than 30 built-in indoor and GPS sports apps, including walking, running, cycling, HIIT, swimming, golf and more
  • Wheelchair mode tracks pushes — rather than steps — and includes push and handcycle activities with preloaded workouts for strength, cardio, HIIT, Pilates and yoga, challenges specific to wheelchair users and more (data presented is intended to be a close estimation of metrics tracked)
bin/
resources/
source/
manifest.xml
  • source/: Monkey C source files.
  • resources/: fonts, bitmaps, layouts, strings, properties, and settings.
  • manifest.xml: application metadata, app type, ID, permissions, and supported products.
  • bin/: compiler output and intermediate files.

Build the minimum working face

The initial view must extend Toybox.WatchUi.WatchFace. The main lifecycle methods are:

  • initialize(): initializes the watch-face view.
  • onUpdate(dc): performs the normal redraw.
  • onPartialUpdate(dc): optionally updates a small region on devices that support it.
  • onEnterSleep(): runs when the face enters its low-power state.
  • onExitSleep(): runs when the face returns to high-power viewing.

This illustrative skeleton shows the architecture. Check the generated template and the current SDK API for exact imports, declarations, and device availability before treating it as a drop-in project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
using Toybox.Graphics;
using Toybox.Lang;
using Toybox.Time;
using Toybox.Time.Gregorian;
using Toybox.WatchUi;

class MainView extends WatchUi.WatchFace {

    function initialize() {
        WatchFace.initialize();
    }

    function onUpdate(dc as Dc) as Void {
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        dc.clear();

        var now = Gregorian.info(
            Time.now(),
            Gregorian.FORMAT_SHORT
        );

        var hour = now.hour.format("%02d");
        var minute = now.min.format("%02d");

        dc.drawText(
            dc.getWidth() / 2,
            dc.getHeight() / 2,
            Graphics.FONT_LARGE,
            hour + ":" + minute,
            Graphics.TEXT_JUSTIFY_CENTER
        );
    }

    function onEnterSleep() as Void {
        // Stop timers or animations here.
    }

    function onExitSleep() as Void {
        // Restart them here if needed.
    }

    function onPartialUpdate(dc as Dc) as Void {
        // Use only for supported second-by-second updates.
    }
}

Use Garmin’s WatchFace API documentation to verify the lifecycle for your target API level.

Draw a responsive layout

The display context, usually called dc, provides the basic drawing API:

  • dc.clear() clears the display.
  • dc.setColor(foreground, background) selects drawing colors.
  • dc.drawText() draws text.
  • dc.drawBitmap() draws a bitmap resource.
  • dc.drawLine(), dc.drawCircle(), and related methods draw simple shapes.
  • dc.getWidth() and dc.getHeight() let you calculate positions for the current screen.

Prefer calculated coordinates, text justification, and measured bounds over hard-coded positions. A centered label should use the current display width, not a coordinate copied from one watch.

Use drawing primitives for simple hands, rings, ticks, and separators where that saves memory. Use bitmap resources for static backgrounds, logos, and decorative artwork. Check bitmap format, dimensions, and color limitations for every target device, and avoid unnecessarily large full-screen images.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add the date, battery, fonts, and bitmaps

Watch faces can typically display the current time and date, battery status, activity-monitor information, selected profile or activity data, and static or generated graphics. However, they do not have unrestricted access to sensors. Garmin says watch faces cannot directly access GPS, the compass, or other sensors in the same way as ordinary device apps. A project needing GPS, complex networking, or substantial background processing may need a device app or widget alongside the face.

For custom fonts:

  1. Place the font in resources/fonts.
  2. Define it using the resource XML generated or expected by the current SDK template.
  3. Use the generated resource identifier in code.
  4. Pass the loaded font to drawText().

Do not hard-code a file path or invent a resource identifier. Garmin recommends specifying a point size for each supported resolution and including only the glyphs the face needs. That reduces memory use. Test the font at every supported resolution.

For time handling, use Garmin’s Time and Gregorian APIs rather than manually calculating dates. Respect the user’s 12-hour or 24-hour preference where appropriate. Test midnight, month changes, leap years, daylight-saving transitions, time-zone changes, and date changes received through Garmin Connect or Garmin Express. Garmin notes that some date settings are stored in UTC and must be handled with the appropriate Gregorian UTC functions. See properties and app settings.

Rank #3
Sale
Garmin vívoactive® 5, Health & Fitness GPS Smartwatch, 42mm, Orchid
  • Designed with a bright, colorful AMOLED display, get a more complete picture of your health, thanks to battery life of up to 11 days in smartwatch mode
  • Body Battery energy monitoring helps you understand when you’re charged up or need to rest, with even more personalized insights based on sleep, naps, stress levels, workouts and more (data presented is intended to be a close estimation of metrics tracked)
  • Get a sleep score and personalized sleep coaching for how much sleep you need — and get tips on how to improve plus key metrics such as HRV status to better understand your health (data presented is intended to be a close estimation of metrics tracked)
  • Find new ways to keep your body moving with more than 30 built-in indoor and GPS sports apps, including walking, running, cycling, HIIT, swimming, golf and more
  • Wheelchair mode tracks pushes — rather than steps — and includes push and handcycle activities with preloaded workouts for strength, cardio, HIIT, Pilates and yoga, challenges specific to wheelchair users and more (data presented is intended to be a close estimation of metrics tracked)

Understand low-power and high-power modes

This is the difference between a watch face that merely compiles and one that works acceptably on a watch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Low-power mode

A watch face normally updates once per minute in low-power mode. Timers and animations are unavailable. Design the face so it remains useful without a continuously moving seconds hand, and avoid expensive calculations or unnecessary rendering.

High-power mode

When the user raises the watch or returns to the face, it enters high-power mode. Full-screen updates can normally occur once per second for a short period, typically around 10 seconds. Timers and animations may be available during this period.

Start high-power timers or animations in onExitSleep() and stop them in onEnterSleep(). Do not assume that an animation can run indefinitely.

Partial updates and seconds

“Display seconds” is not a universal Garmin watch-face feature. Some devices support onPartialUpdate(), which can update a small region—potentially once per second—with strict execution and power limits. It is not permission to redraw the entire screen every second.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a seconds hand or seconds digits:

  • Prepare static graphics during onUpdate().
  • Clip drawing to the smallest changing region with dc.setClip().
  • Redraw only the pixels that change.
  • Use BufferedBitmap where appropriate.
  • Watch for power-budget violations and fall back to minute updates when necessary.

Garmin’s second-by-second update guidance and watch-face UX guidance describe the device-specific limits.

Design separately for MIP and AMOLED

On MIP watches, standard faces generally redraw once per minute. Supported always-active faces may update a small region once per second, but full-screen second-by-second redraws are inappropriate for battery reasons.

AMOLED watches have different always-on rules. Garmin’s current guidance limits always-on updates and illuminated pixels, with exact behavior varying by device generation. Bright, static, large elements can increase battery use and burn-in risk. Safer choices include dark backgrounds, restrained colors, thinner fonts, and movement of static elements where the device’s protection model requires it.

Build a dedicated always-on rendering path when supporting AMOLED. Detect display mode and follow the restrictions documented for each target rather than applying rules from an older AMOLED model to every current product. See Garmin’s AMOLED guidance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Garmin Instinct® 3 Solar, Rugged GPS Smartwatch, 45mm, Black | Solar Charging, Rugged Design, Metal-Reinforced Bezel, 24/7 Health Monitoring, Built-In Flashlight
  • Make a bold statement with this rugged GPS smartwatch, featuring a 0.9” display with solar charging lens and unlimited battery life with solar charging (assumes all-day wear with 3 hours per day outside in 50,000 lux conditions)
  • Engineered with a supertough 45 mm fiber-reinforced polymer case and metal-reinforced bezel
  • Built-in LED flashlight with variable intensities and strobe modes gives you greater visibility in the outdoors and provides convenient illumination when you need it
  • Know your body better with health monitoring features, including wrist-based heart rate, advanced sleep monitoring, Pulse Ox and more (this is not a medical device, and data presented is intended to be a close estimation of metrics tracked; Pulse Ox not available in all countries)
  • Navigate confidently with a 3-axis compass, barometric altimeter and multi-band GPS with SatIQ technology, which delivers superior positioning while also optimizing battery life

Add user settings

A first useful settings set might include color theme, date format, seconds visibility, data fields, background style, battery-saving mode, or numeral and hand style.

Define settings as resources and read the resulting properties in the application. Users may change them through Garmin Connect, Garmin Express, or the Connect IQ Store app. Respond to changes through AppBase.onSettingsChanged(), refresh cached values, and ensure the next redraw uses those values.

For supported newer devices, AppBase.getSettingsView() can provide an on-device settings flow. This is an advanced path with additional API and device requirements.

Garmin also documents a native watch-face configuration API beginning at API level 5.1.0 for supported devices. It can expose styles, data, data colors, accent colors, and up to four saved configurations on the device. Do not add it to a broad-compatibility project without checking the target device list and API documentation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run the face in the simulator

  1. Open a Monkey C source file.
  2. Choose Run → Run Without Debugging.
  3. Select a supported product.
  4. Inspect the face in the Connect IQ simulator.

Test multiple resolutions and, where relevant, both a MIP and AMOLED product. Exercise time and date changes, sleep and wake transitions, settings changes, fonts, bitmaps, memory use, and partial-update behavior.

The simulator cannot prove battery behavior or exact physical-screen behavior. Differences can appear in refresh behavior, gesture handling, sensor availability, font rendering, display mode, and device-specific APIs. Physical-watch testing is required before claiming support.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Build and sideload the face

For a beginner-friendly device build:

  1. Connect the watch to the computer by USB.
  2. Open the Command Palette.
  3. Run Monkey C: Build for Device.
  4. Select the target product.
  5. Choose an output directory.
  6. Copy the generated .PRG file to GARMIN/APPS.
  7. Safely eject or disconnect the watch before testing.

Garmin documents this sideloading workflow. To remove a test build, delete its .PRG file from the watch or remove the application through the watch’s app management interface. If a build causes problems, disconnect the watch safely before removing or replacing it.

Optional command-line workflow

Developers who prefer a terminal can use Garmin’s SDK tools:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
connectiq
monkeyc -d <device_id> 
  -f /path/to/monkey.jungle 
  -o project_name.prg 
  -y /path/to/developer_key.der
monkeydo project_name.prg <device_id>
  • connectiq: launches the simulator.
  • monkeyc: compiles Monkey C.
  • monkeydo: runs a compiled executable in the simulator.
  • -d: target device.
  • -f: Jungle build file.
  • -o: output file.
  • -y: signing key.
  • -e: package output as an .IQ Store file.

SDK paths and shell syntax differ between Windows, macOS, and Linux. Consult Garmin’s command-line setup and compiler options documentation.

Best Value
Sale
Garmin Forerunner 55, GPS Running Watch with Daily Suggested Workouts, Up to 2 Weeks of Battery Life, Black - 010-02562-00
  • Easy-to-use running watch monitors heart rate (this is not a medical device) at the wrist and uses GPS to track how far, how fast and where you’ve run.Special Feature:Bluetooth.
  • Battery life: up to 2 weeks in smartwatch mode; up to 20 hours in GPS mode
  • Plan your race day strategy with the PacePro feature (not compatible with on-device courses), which offers GPS-based pace guidance for a selected course or distance
  • Run your best with helpful training tools, including race time predictions and finish time estimates
  • Track all the ways you move with built-in activity profiles for running, cycling, track run, virtual run, pool swim, Pilates, HIIT, breathwork and more

Publish to the Connect IQ Store

Sideloading is the quickest route for personal use and testing. For distribution, package the signed application as an .IQ file, then prepare the Store metadata, screenshots, compatibility list, and required assets through Garmin’s publishing workflow.

Before submission, verify every advertised product, test settings and power modes, and confirm that the developer key is backed up. Do not promise universal device support simply because the application builds for one watch.

Troubleshooting

The device is missing from Edit Products

Update device definitions in SDK Manager, confirm the active SDK, lower the minimum API level if possible, and rerun Monkey C: Edit Products. Remove APIs that the target cannot support. A device can also be absent because the project is not actually a Watch Face project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

“No valid devices configured” appears

The project has no valid supported products. Recheck the manifest and product list using Garmin’s project guide.

The face crashes on the watch

Check unsupported API calls, memory use, invalid resource identifiers, bitmap dimensions and color depth, excessive work in onPartialUpdate(), and differences between simulator and physical device. Also verify the signing key and target product.

Seconds stop updating

The device may not support the required partial-update behavior, the callback may exceed its time budget, too many pixels may be redrawn, or the face may have entered low-power or AMOLED always-on restrictions. Reduce the clip region, pre-render static content, update only the changing hand or digits, remove logging from performance-critical code, and provide a minute-update fallback.

The AMOLED always-on display is blank or unexpected

The always-on path may illuminate too many pixels, violate burn-in rules, or assume MIP behavior. Create a dedicated AMOLED path, use darker colors and thinner fonts, detect display mode, and test on the exact AMOLED models you support.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Settings change but the face does not

Confirm that the setting is defined as a resource, the app reads the updated property, onSettingsChanged() refreshes cached values, and the next onUpdate() draws with them. Persistent storage alone is not a real-time settings notification mechanism.

The simulator looks right but the watch does not

Check the exact resolution, display type, color depth, font rendering, coordinate rounding, resource overrides, and low-power rendering. A high-power simulator preview does not validate the always-on or minute-update appearance.

Final checklist

  • Choose exact target watches and minimum API level.
  • Verify the display layout at every supported resolution.
  • Make the time readable in low-power mode.
  • Check 12/24-hour behavior, dates, time zones, and daylight-saving transitions.
  • Keep fonts and bitmaps within device memory and color limits.
  • Test sleep, wake, high-power, partial-update, and AMOLED always-on paths.
  • Test settings through the intended settings channel.
  • Build a signed .PRG and sideload it to a real watch.
  • Back up the RSA 4096-bit developer key.
  • Only advertise devices you have carefully tested.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Connect IQGarminGarmin DevelopmentMonkey Cwatch faces

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.