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/native-navigation

v8.0.8

Published

Capacitor plugin for native navbar, tabbar, and route transition chrome over a WebView.

Downloads

1,146

Readme

@capgo/native-navigation

Native navigation chrome for Capacitor apps. Render a native navbar, native tabbar, and native transition shell over a single full-screen WebView while your framework keeps owning routes and content.

Demo

Native navigation tap flow

SVG icon descriptors

What It Does

  • Renders native top navigation and bottom tab chrome from JavaScript state.
  • Emits native intent events such as navbarBack, navbarItemTap, and tabSelect.
  • Captures WebView snapshots for native-feeling push, back, root, and tab transition shells.
  • Writes CSS variables so web content can scroll behind native bars without being hidden.
  • Works with React, Vue, Angular, Svelte, Solid, vanilla JS, and any router that can call imperative methods.

What It Does Not Do

  • It does not create one native WebView per route.
  • It does not render React/Vue/Svelte icon nodes natively. Icons must be serializable descriptors such as SVG strings, SF Symbols, or native resource names.
  • It does not replace your router. JS still owns route state and web content rendering.

Compatibility

| Plugin version | Capacitor compatibility | Maintained | | -------------- | ----------------------- | ---------- | | v8.*.* | v8.*.* | Yes | | v7.*.* | v7.*.* | On demand | | v6.*.* | v6.*.* | On demand |

Install

bun add @capgo/native-navigation
bunx cap sync

Minimal Usage

import { NativeNavigation } from '@capgo/native-navigation';

await NativeNavigation.configure({
  contentInsetMode: 'css',
  animationDuration: 360,
});

await NativeNavigation.setNavbar({
  title: 'Home',
  subtitle: 'Native chrome',
  transparent: true,
  backButton: { visible: false },
  rightItems: [
    {
      id: 'compose',
      title: 'Compose',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>',
      },
    },
  ],
});

await NativeNavigation.setTabbar({
  selectedId: 'home',
  labels: true,
  icons: true,
  tabs: [
    {
      id: 'home',
      title: 'Home',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 10.5 12 3l9 7.5"/><path d="M5 10v10h14V10"/></svg>',
      },
    },
    {
      id: 'settings',
      title: 'Settings',
      icon: {
        svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg>',
      },
    },
  ],
});

NativeNavigation.addListener('tabSelect', ({ id }) => {
  router.navigate(id);
});

Transition Flow

const transition = await NativeNavigation.beginTransition({ direction: 'forward' });

router.navigate('/detail');
await router.ready?.();

await NativeNavigation.setNavbar({
  title: 'Detail',
  backButton: { visible: true, title: 'Back' },
});

await NativeNavigation.finishTransition({
  id: transition.id,
  direction: 'forward',
});

CSS Insets

With contentInsetMode: 'css', the plugin updates these variables on document.documentElement:

.app-scroll {
  height: 100dvh;
  overflow: auto;
  padding-top: calc(var(--cap-native-navigation-top) + 24px);
  scroll-padding-bottom: calc(var(--cap-native-navigation-bottom) + 24px);
}

.page {
  min-height: 100dvh;
  padding-bottom: calc(var(--cap-native-navigation-bottom) + 24px);
}

Available variables:

  • --cap-native-navigation-top
  • --cap-native-navigation-right
  • --cap-native-navigation-bottom
  • --cap-native-navigation-left
  • --cap-native-navbar-height
  • --cap-native-tabbar-height

Web Components

The package can register optional custom elements for framework-agnostic declarative setup:

import { defineNativeNavigationElements } from '@capgo/native-navigation';

defineNativeNavigationElements();
<cap-native-navigation-provider enabled="true" content-inset-mode="css"></cap-native-navigation-provider>

<cap-native-navbar
  title="Home"
  subtitle="Native chrome"
  transparent
  right-items='[{"id":"compose","title":"Compose","icon":{"ios":{"sfSymbol":"square.and.pencil"}}}]'
></cap-native-navbar>

<cap-native-tabbar
  selected-id="home"
  tabs='[{"id":"home","title":"Home","icon":{"ios":{"sfSymbol":"house.fill"}}}]'
></cap-native-tabbar>

Icon Descriptors

const icon = {
  svg: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 10.5 12 3l9 7.5"/></svg>',
  width: 24,
  height: 24,
  template: true,
  src: 'fallback_asset_name',
  ios: {
    svg: '<svg viewBox="0 0 24 24"><path d="M3 10.5 12 3l9 7.5"/></svg>',
    sfSymbol: 'house.fill',
    image: 'BundledAssetName',
  },
  android: {
    svg: '<svg viewBox="0 0 24 24"><path d="M3 10.5 12 3l9 7.5"/></svg>',
    resource: 'ic_menu_view',
    image: 'bundled_drawable_name',
  },
};

Inline SVG supports the icon-focused subset used by common sets such as Lucide and Feather: path, line, polyline, polygon, circle, and rect. The SVG is rendered as a template image by default, so native tint colors can recolor it without bundling a platform asset.

Platform Notes

  • iOS uses UINavigationBar and a floating native UIKit tab capsule. iOS 26+ relies on the system Liquid Glass effect where available; earlier versions use native translucent/material fallback styling.
  • Android uses an AppCompat Toolbar and a floating native tab capsule with edge-to-edge placement.
  • Web fallback does not draw native bars; it mirrors inset variables and events for development.

Example App

The example-app/ folder is a vanilla JS Capacitor demo linked with file:...

cd example-app
bun install
bun run build
bunx cap add ios
bunx cap add android
bunx cap sync

API

Framework-agnostic native navigation chrome API.

configure(...)

configure(options?: NativeNavigationConfigureOptions | undefined) => Promise<NativeNavigationInsetsResult>

Configure the native chrome host and content inset behavior.

| Param | Type | | ------------- | --------------------------------------------------------------------------------------------- | | options | NativeNavigationConfigureOptions |

Returns: Promise<NativeNavigationInsetsResult>


setNavbar(...)

setNavbar(options: NativeNavigationNavbarOptions) => Promise<NativeNavigationInsetsResult>

Render or update the native navbar.

| Param | Type | | ------------- | --------------------------------------------------------------------------------------- | | options | NativeNavigationNavbarOptions |

Returns: Promise<NativeNavigationInsetsResult>


setTabbar(...)

setTabbar(options: NativeNavigationTabbarOptions) => Promise<NativeNavigationInsetsResult>

Render or update the native tabbar.

| Param | Type | | ------------- | --------------------------------------------------------------------------------------- | | options | NativeNavigationTabbarOptions |

Returns: Promise<NativeNavigationInsetsResult>


beginTransition(...)

beginTransition(options?: NativeNavigationBeginTransitionOptions | undefined) => Promise<NativeNavigationTransitionResult>

Capture the current WebView and prepare a native transition.

| Param | Type | | ------------- | --------------------------------------------------------------------------------------------------------- | | options | NativeNavigationBeginTransitionOptions |

Returns: Promise<NativeNavigationTransitionResult>


finishTransition(...)

finishTransition(options?: NativeNavigationFinishTransitionOptions | undefined) => Promise<NativeNavigationTransitionResult>

Animate from the captured WebView snapshot to the current live WebView.

| Param | Type | | ------------- | ----------------------------------------------------------------------------------------------------------- | | options | NativeNavigationFinishTransitionOptions |

Returns: Promise<NativeNavigationTransitionResult>


getPluginVersion()

getPluginVersion() => Promise<PluginVersionResult>

Returns the platform implementation version marker.

Returns: Promise<PluginVersionResult>


addListener('navbarBack', ...)

addListener(eventName: 'navbarBack', listenerFunc: (event: NativeNavigationBackEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | --------------------------------------------------------------------------------------------------- | | eventName | 'navbarBack' | | listenerFunc | (event: NativeNavigationBackEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('navbarItemTap', ...)

addListener(eventName: 'navbarItemTap', listenerFunc: (event: NativeNavigationBarItemTapEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | --------------------------------------------------------------------------------------------------------------- | | eventName | 'navbarItemTap' | | listenerFunc | (event: NativeNavigationBarItemTapEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('tabSelect', ...)

addListener(eventName: 'tabSelect', listenerFunc: (event: NativeNavigationTabSelectEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------------------------------- | | eventName | 'tabSelect' | | listenerFunc | (event: NativeNavigationTabSelectEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('safeAreaChanged', ...)

addListener(eventName: 'safeAreaChanged', listenerFunc: (event: NativeNavigationSafeAreaChangedEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | | eventName | 'safeAreaChanged' | | listenerFunc | (event: NativeNavigationSafeAreaChangedEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('transitionStart', ...)

addListener(eventName: 'transitionStart', listenerFunc: (event: NativeNavigationTransitionEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | --------------------------------------------------------------------------------------------------------------- | | eventName | 'transitionStart' | | listenerFunc | (event: NativeNavigationTransitionEvent) => void |

Returns: Promise<PluginListenerHandle>


addListener('transitionEnd', ...)

addListener(eventName: 'transitionEnd', listenerFunc: (event: NativeNavigationTransitionEvent) => void) => Promise<PluginListenerHandle>

| Param | Type | | ------------------ | --------------------------------------------------------------------------------------------------------------- | | eventName | 'transitionEnd' | | listenerFunc | (event: NativeNavigationTransitionEvent) => void |

Returns: Promise<PluginListenerHandle>


Interfaces

NativeNavigationInsetsResult

Returned by methods that may change safe content bounds.

| Prop | Type | | ------------ | ------------------------------------------------------------------------- | | insets | NativeNavigationInsets |

NativeNavigationInsets

Insets exposed to web content.

| Prop | Type | | ------------------ | ------------------- | | top | number | | right | number | | bottom | number | | left | number | | navbarHeight | number | | tabbarHeight | number |

NativeNavigationConfigureOptions

Global plugin configuration.

| Prop | Type | Description | | ----------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | enabled | boolean | Enables or disables the native chrome host. | | platformStyle | NativeNavigationPlatformStyle | Native style preference. auto uses the current platform. | | contentInsetMode | NativeNavigationContentInsetMode | When css, the plugin writes CSS variables on document.documentElement. | | animationDuration | number | Default native transition duration in milliseconds. | | colors | NativeNavigationColors | Shared color hints for native bars. |

NativeNavigationColors

Native bar colors. Use CSS-style hex strings (#RRGGBB or #AARRGGBB).

| Prop | Type | Description | | ------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------- | | tint | string | Tint color for active buttons/items. | | inactiveTint | string | Color for inactive tab items. | | background | string | Optional background tint. On iOS 26+ avoid setting this unless you want to override the system Liquid Glass appearance. |

NativeNavigationNavbarOptions

Native navbar state.

| Prop | Type | Description | | ----------------- | --------------------------------------------------------------------------------- | ------------------------------------------------ | | hidden | boolean | Hide the native navbar. | | title | string | Main title. | | subtitle | string | Secondary title where supported by the platform. | | large | boolean | Prefer a large iOS title style. | | transparent | boolean | Prefer transparent/scroll-edge style. | | backButton | NativeNavigationBackButton | Back button state. | | leftItems | NativeNavigationBarButton[] | Left-side action buttons. | | rightItems | NativeNavigationBarButton[] | Right-side action buttons. | | colors | NativeNavigationColors | Navbar color hints. | | animated | boolean | Animate native navbar changes. |

NativeNavigationBackButton

Native back button configuration.

| Prop | Type | Description | | ------------- | -------------------- | -------------------------------- | | visible | boolean | Show the native back affordance. | | title | string | Optional back title. |

NativeNavigationBarButton

A button shown in the native navbar.

| Prop | Type | Description | | ------------- | --------------------------------------------------------------------- | -------------------------------------------------- | | id | string | Stable id returned in navbarItemTap. | | title | string | Visible text label. | | icon | NativeNavigationIcon | Native icon descriptor. | | enabled | boolean | Whether the action is enabled. Defaults to true. |

NativeNavigationIcon

A serializable icon descriptor. Framework nodes are intentionally not accepted because icons are rendered by native UI.

| Prop | Type | Description | | -------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | src | string | Cross-platform asset path or URL fallback. | | svg | string | Cross-platform inline SVG markup. The native renderers support common icon shapes such as path, line, polyline, polygon, circle, and rect. SVG icons are rendered as template images by default so native tint colors still apply. | | width | number | Preferred rendered icon width in native points/dp. Defaults to 24. | | height | number | Preferred rendered icon height in native points/dp. Defaults to 24. | | template | boolean | When true, native tint colors are applied to the rendered SVG/image. Defaults to true. | | ios | { sfSymbol?: string; image?: string; svg?: string; } | iOS-specific SF Symbol, bundled image name, or inline SVG. | | android | { resource?: string; image?: string; svg?: string; } | Android-specific drawable resource, asset name, or inline SVG. |

NativeNavigationTabbarOptions

Native tabbar state.

| Prop | Type | Description | | ---------------- | ------------------------------------------------------------------------- | ------------------------------------- | | hidden | boolean | Hide the native tabbar. | | tabs | NativeNavigationTab[] | Tab definitions. | | selectedId | string | Currently selected tab id. | | labels | boolean | Show text labels. Defaults to true. | | icons | boolean | Show icons. Defaults to true. | | colors | NativeNavigationColors | Tabbar color hints. | | animated | boolean | Animate native tabbar changes. |

NativeNavigationTab

A native tab item.

| Prop | Type | Description | | ------------------ | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | id | string | Stable tab id returned in tabSelect. | | title | string | Visible tab label. | | icon | NativeNavigationIcon | Native icon descriptor. | | selectedIcon | NativeNavigationIcon | Optional selected-state icon. | | badge | string | number | Optional badge. Numeric badges are supported on both platforms; text badge support depends on platform capabilities. | | enabled | boolean | Whether the tab is enabled. Defaults to true. |

NativeNavigationTransitionResult

Native transition result.

| Prop | Type | | --------------- | --------------------------------------------------------------------------------------------------- | | id | string | | direction | NativeNavigationTransitionDirection | | duration | number |

NativeNavigationBeginTransitionOptions

Begin a native transition transaction before JS changes route content.

| Prop | Type | | --------------- | --------------------------------------------------------------------------------------------------- | | id | string | | direction | NativeNavigationTransitionDirection | | duration | number |

NativeNavigationFinishTransitionOptions

Finish a native transition transaction after JS has changed route content.

| Prop | Type | | --------------- | --------------------------------------------------------------------------------------------------- | | id | string | | direction | NativeNavigationTransitionDirection | | duration | number |

PluginVersionResult

Plugin version payload.

| Prop | Type | Description | | ------------- | ------------------- | ----------------------------------------------------------- | | version | string | Version identifier returned by the platform implementation. |

PluginListenerHandle

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

NativeNavigationBackEvent

| Prop | Type | | ------------ | --------------------- | | source | 'navbar' |

NativeNavigationBarItemTapEvent

| Prop | Type | | --------------- | ------------------------------ | | id | string | | title | string | | placement | 'left' | 'right' |

NativeNavigationTabSelectEvent

| Prop | Type | | ----------- | ------------------- | | id | string | | index | number | | title | string |

NativeNavigationSafeAreaChangedEvent

| Prop | Type | | ------------ | ------------------------------------------------------------------------- | | insets | NativeNavigationInsets |

NativeNavigationTransitionEvent

| Prop | Type | | --------------- | --------------------------------------------------------------------------------------------------- | | id | string | | direction | NativeNavigationTransitionDirection | | duration | number |

Type Aliases

NativeNavigationPlatformStyle

Platform rendering preference for the native bars.

'auto' | 'ios' | 'android'

NativeNavigationContentInsetMode

How the plugin exposes native bar sizes to web content.

'css' | 'none'

NativeNavigationTransitionDirection

Navigation animation direction.

'forward' | 'back' | 'root' | 'tab' | 'none'