npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@capgo/capacitor-webview-version-checker

v8.2.0

Published

Capacitor plugin for checking outdated Android WebView engines, emitting status events, and presenting native update prompts.

Readme

@capgo/capacitor-webview-version-checker

Capacitor plugin for checking whether the app WebView engine is up to date, emitting realtime status events, and optionally showing a native update prompt that redirects users to the proper update destination.

Install

bun add @capgo/capacitor-webview-version-checker
bunx cap sync

Usage

Main use case: Browserslist-style compatibility checks by default.

The plugin uses this strategy out of the box, even if you do not add any plugin options:

  • minimumDeviceSharePercent defaults to 3
  • version-share data comes from a built-in dataset generated at build time from caniuse
  • no runtime version-share URL call is required for the default flow

Default setup (no plugin settings):

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {},
  },
};

export default config;

Simple config-only setup with native prompt:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {
      autoPromptOnOutdated: true,
      autoPromptDismissible: false,
    },
  },
};

export default config;

Advanced mode with custom threshold and custom dataset:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  plugins: {
    WebviewVersionChecker: {
      autoCheckOnLoad: true,
      autoPromptOnOutdated: true,
      minimumDeviceSharePercent: 3,
      versionShareByMajor: {
        '137': 58.2,
        '136': 21.3,
        '135': 4.6,
        '134': 2.1,
      },
    },
  },
};

export default config;

What this means:

  • minimumDeviceSharePercent: 3 means "consider a version compatible only if that major version still represents at least 3% of devices in my dataset".
  • versionShareByMajor is your own dataset map where:
    • key = major version (for example 137)
    • value = share percent (0..100)
  • If you do not provide versionShareByMajor, the plugin uses its built-in generated dataset.

You can provide share data in two ways:

  • Inline with versionShareByMajor (as shown above)
  • Remote with versionShareApiUrl returning one of these shapes:
    • { "versionShareByMajor": { "137": 54.2, "136": 23.8 } }
    • { "shareByMajor": { "137": 54.2, "136": 23.8 } }
    • { "versions": [{ "major": 137, "share": 54.2 }, { "version": "136.0.0.0", "percent": 23.8 }] }

If you set versionShareApiUrl, the plugin fetches that URL at runtime and uses it as override.

Evaluation order:

  1. Browserslist-style threshold mode (minimumDeviceSharePercent + share dataset) is used first. By default this is 3% with the built-in generated dataset.
  2. Else the plugin compares against latestVersion / latestVersionApiUrl.
  3. Else it falls back to minimumMajorVersion.

Advanced usage with JavaScript (manual check, listeners, custom prompt):

import { WebviewVersionChecker } from '@capgo/capacitor-webview-version-checker';

const listener = await WebviewVersionChecker.addListener('webViewOutdated', (status) => {
  console.log('Outdated WebView detected', status);
});

const status = await WebviewVersionChecker.check({
  latestVersionApiUrl:
    'https://versionhistory.googleapis.com/v1/chrome/platforms/android/channels/stable/versions?page_size=1',
  minimumMajorVersion: 124,
  showPromptOnOutdated: true,
  autoPromptDismissible: false,
  promptTitle: 'Update WebView',
  promptMessage: 'Your WebView is outdated. Please update to continue safely.',
  promptUpdateButtonText: 'Update now',
  promptCancelButtonText: 'Later',
});

console.log('WebView status', status);

// later
listener.remove();

Why WebView Version Checker?

Capacitor already provides a built-in WebView minimum check through config:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  android: {
    minWebViewVersion: 124,
  },
  server: {
    errorPath: 'unsupported-webview.html',
  },
};

export default config;

Why we're doing this instead

  • android.minWebViewVersion is static config; it does not give runtime plugin events like webViewOutdated.
  • With server.errorPath, users are redirected to a static error page (hard block UX) instead of seeing a native modal in your normal app flow.
  • Without server.errorPath, Capacitor only logs the issue, but does not provide a native update prompt + store deep link UX.
  • This plugin gives soft enforcement: users can still open/use the app, get a native update modal, and you decide whether to require update later.
  • Main use case: this plugin brings Browserslist-style compatibility logic to Android WebView (for example, "support versions still used by at least 3% of devices"), while keeping your app usable.

Android Provider Handling

The plugin resolves the active WebView provider package and version, then routes update links to the correct package:

  • Android 5-6 and 10+: Android System WebView (com.google.android.webview)
  • Android 7-9: Google Chrome (com.android.chrome)

When provider detection is unavailable, fallback routing follows the same API-range rule above.

API

Public API for checking WebView freshness and guiding users to updates.

check(...)

check(options?: CheckWebViewOptions | undefined) => Promise<WebViewVersionStatus>

Runs a version check and returns the latest known status.

| Param | Type | | ------------- | ------------------------------------------------------------------- | | options | CheckWebViewOptions |

Returns: Promise<WebViewVersionStatus>


startMonitoring(...)

startMonitoring(options?: StartMonitoringOptions | undefined) => Promise<MonitoringStateResult>

Enables background monitoring (typically on app resume).

| Param | Type | | ------------- | ------------------------------------------------------------------------- | | options | StartMonitoringOptions |

Returns: Promise<MonitoringStateResult>


stopMonitoring()

stopMonitoring() => Promise<MonitoringStateResult>

Disables monitoring.

Returns: Promise<MonitoringStateResult>


getLastStatus()

getLastStatus() => Promise<LastStatusResult>

Returns the last resolved status, or null if no check was run yet.

Returns: Promise<LastStatusResult>


showUpdatePrompt(...)

showUpdatePrompt(options?: ShowUpdatePromptOptions | undefined) => Promise<ShowUpdatePromptResult>

Shows a native prompt asking the user to update the WebView.

| Param | Type | | ------------- | --------------------------------------------------------------------------- | | options | ShowUpdatePromptOptions |

Returns: Promise<ShowUpdatePromptResult>


openUpdatePage(...)

openUpdatePage(options?: OpenUpdatePageOptions | undefined) => Promise<OpenUpdatePageResult>

Opens the configured update page directly.

| Param | Type | | ------------- | ----------------------------------------------------------------------- | | options | OpenUpdatePageOptions |

Returns: Promise<OpenUpdatePageResult>


addListener('statusChanged', ...)

addListener(eventName: 'statusChanged', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired for every successful status evaluation.

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------------ | | eventName | 'statusChanged' | | listenerFunc | (status: WebViewVersionStatus) => void |

Returns: Promise<PluginListenerHandle>


addListener('webViewLatest', ...)

addListener(eventName: 'webViewLatest', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired when the state resolves to latest.

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------------ | | eventName | 'webViewLatest' | | listenerFunc | (status: WebViewVersionStatus) => void |

Returns: Promise<PluginListenerHandle>


addListener('webViewOutdated', ...)

addListener(eventName: 'webViewOutdated', listenerFunc: (status: WebViewVersionStatus) => void) => Promise<PluginListenerHandle>

Fired when the state resolves to outdated.

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------------ | | eventName | 'webViewOutdated' | | listenerFunc | (status: WebViewVersionStatus) => void |

Returns: Promise<PluginListenerHandle>


Interfaces

WebViewVersionStatus

Snapshot of the currently detected WebView status.

| Prop | Type | Description | | -------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | platform | WebViewPlatform | Native platform that generated the status. | | state | WebViewVersionState | Resolved version state. | | isLatest | boolean | Convenience boolean equivalent to state === 'latest'. | | checkedAt | string | ISO-8601 timestamp of the check. | | reason | string | Human-readable explanation for the reported state. | | currentVersion | string | Current WebView (or iOS system WebKit) version string. | | currentMajorVersion | number | Current detected major version (if parseable). | | latestVersion | string | Resolved latest version used for comparison. | | latestMajorVersion | number | Resolved latest major version (if parseable). | | currentVersionSharePercent | number | Device-share percentage for the installed WebView major version. Present only when a version-share dataset is available and includes the current major version. | | minimumDeviceSharePercent | number | Configured threshold used by compatibility-threshold mode. Present only when minimumDeviceSharePercent was requested for that check. | | versionShareSource | string | Source used for version-share data. Values: - versionShareByMajor (inline dataset) - versionShareApiUrl (remote dataset) - generatedVersionShareByMajor (built-in dataset generated at build time) | | deviceShareError | string | Diagnostic message for compatibility-threshold mode. Present when minimumDeviceSharePercent was requested but the threshold check could not be fully evaluated. | | providerPackage | string | Android package name of the active WebView provider. | | updateUrl | string | URL that should be opened to update when outdated. | | source | string | Internal source identifier for the check implementation. |

CheckWebViewOptions

Options for running a WebView version check.

| Prop | Type | Description | Default | | -------------------------- | -------------------- | --------------------------------------------------------------------------------- | --------------------- | | showPromptOnOutdated | boolean | Force showing a native prompt if an outdated WebView is detected. | false | | source | string | Optional tag included in the status payload so you can identify the check origin. | "manual" |

MonitoringStateResult

Result payload for monitor controls.

| Prop | Type | Description | | -------------------------- | -------------------- | ------------------------------------------------------------ | | monitoring | boolean | Whether monitoring is currently active. | | checkOnResume | boolean | Whether checks run on app resume while monitoring is active. | | autoPromptOnOutdated | boolean | Whether outdated checks auto-trigger the native prompt. |

StartMonitoringOptions

Options for starting monitor mode.

| Prop | Type | Description | Default | | ------------------- | -------------------- | ----------------------------------------------------------------- | ----------------- | | checkOnStart | boolean | Run a check immediately when monitoring starts. | true | | checkOnResume | boolean | Whether foreground checks should run while monitoring is enabled. | true |

LastStatusResult

Last known check snapshot.

| Prop | Type | Description | | ------------ | ----------------------------------------------------------------------------- | ------------------------------------- | | status | WebViewVersionStatus | null | Null until the first check completes. |

ShowUpdatePromptResult

Result payload for showUpdatePrompt().

| Prop | Type | Description | | ---------------------- | -------------------- | ---------------------------------------------------------- | | shown | boolean | Whether a native prompt was actually shown. | | openedUpdatePage | boolean | Whether the update page was opened from the prompt action. |

ShowUpdatePromptOptions

Options for showing the native update prompt.

| Prop | Type | Description | | ---------------------- | ------------------- | ------------------------------------------------------ | | title | string | Prompt title. | | message | string | Prompt message. | | updateButtonText | string | Update CTA label. | | cancelButtonText | string | Cancel CTA label. | | updateUrl | string | Optional URL to open if the update action is selected. |

OpenUpdatePageResult

Result payload for openUpdatePage().

| Prop | Type | Description | | ------------ | -------------------- | ----------------------------------------- | | opened | boolean | Whether opening the update URL succeeded. | | url | string | URL that was attempted. |

OpenUpdatePageOptions

Options for opening the update page directly.

| Prop | Type | Description | | --------------- | ------------------- | ---------------------- | | updateUrl | string | Optional URL override. |

PluginListenerHandle

| Prop | Type | | ------------ | ----------------------------------------- | | remove | () => Promise<void> |

Type Aliases

WebViewPlatform

'android' | 'ios' | 'web'

WebViewVersionState

'latest' | 'outdated' | 'unknown'