{"id":13727061,"url":"https://github.com/kt3k/lepont","last_synced_at":"2025-08-22T07:31:17.828Z","repository":{"id":38849205,"uuid":"242054046","full_name":"kt3k/lepont","owner":"kt3k","description":"🌉 A native \u003c-\u003e browser (webview) bridge library for react-native","archived":false,"fork":false,"pushed_at":"2024-12-02T08:28:21.000Z","size":2164,"stargazers_count":28,"open_issues_count":1,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-12-10T08:10:36.465Z","etag":null,"topics":["lepont","native-bridge","react-native","webview"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kt3k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-21T04:28:42.000Z","updated_at":"2024-12-02T08:28:23.000Z","dependencies_parsed_at":"2023-02-05T18:01:34.120Z","dependency_job_id":"74f1a1d4-ae31-4be0-bc83-23550bf3da95","html_url":"https://github.com/kt3k/lepont","commit_stats":{"total_commits":139,"total_committers":2,"mean_commits":69.5,"dds":"0.28057553956834536","last_synced_commit":"1cdd9b84f1aa21a07b725fa1fc91b5de32763707"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Flepont","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Flepont/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Flepont/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kt3k%2Flepont/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kt3k","download_url":"https://codeload.github.com/kt3k/lepont/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230568591,"owners_count":18246378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lepont","native-bridge","react-native","webview"],"created_at":"2024-08-03T01:03:38.026Z","updated_at":"2024-12-20T10:09:05.203Z","avatar_url":"https://github.com/kt3k.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/kt3k/lepont/master/design/lepont.png\" width=\"150\" /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  A native \u003c-\u003e browser (webview) bridge library for react-native\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/kt3k/lepont/workflows/ci/badge.svg?branch=master\"\u003e\n  \u003ca href=\"https://codecov.io/gh/kt3k/lepont\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/kt3k/lepont/branch/master/graph/badge.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Current Version: v0.11.4\n\u003c/p\u003e\n\n\u003e Sous **le pont** Mirabeau coule la Seine et nos amours -- Guillaume Apollinaire\n\n*Le pont* means \"the bridge\" in French.\n\nYou can bridge the webview and react-native by using `lepont` i.e. you can invoke the functions of react-native from the inside of browser (webview) and pass information back to browser (webview) from react-native side.\n\nDo you remember [PhoneGap (Cordova)](https://en.wikipedia.org/wiki/Apache_Cordova)? `lepont` is something like PhoneGap on top of react-native.\n\nReact Native already have large swathe of library ecosystem. You can leverage its power from browser by using `lepont`.\n\n# Usage\n\nFirst install it:\n\n```sh\nnpm install --save lepont\n# or\nyarn add lepont\n```\n\nLet's vibrate your phone from browser (using React Native's Vibration module).\n\nOn react-native side:\n\n```tsx\nimport { useBridge } from 'lepont'\nimport { Vibration } from 'react-native'\nimport { WebView } from 'react-native-webview'\n\nconst App = () =\u003e {\n  const [ref, onMessage] = useBridge(\n    (registry) =\u003e {\n      // Registers the `vibrate` handler on react-native side\n      registry.register('vibrate', () =\u003e Vibration.vibrate(1000))\n    }\n  )\n\n  return (\n    \u003cWebView\n      // Loads html.\n      source={{ uri: 'Web.bundle/index.html' }}\n      // Sets \"ref\" to send the messages to the browser\n      ref={ref}\n      // Sets \"onMessage\" to receive the messages from the browser\n      onMessage={onMessage}\n      javaScriptEnabled\n    /\u003e\n  )\n}\n\nexport default App\n```\n\nThen send `vibrate` message from the browser:\n\n```ts\nimport { sendMessage } from 'lepont/browser'\n\nawait sendMessage({ type: 'vibrate' })\n```\n\nThis makes the phone vibrate for 1000 milliseconds! 👍\n\n## Sends multiple events from react-native side\n\nOn react-native side\n\n```tsx\nimport { useBridge } from 'lepont'\nimport { WebView } from 'react-native-webview'\n\nconst App = () =\u003e {\n  const [ref, onMessage] = useBridge((registry) =\u003e {\n    registry.register('streaming-message', (_, bridge) =\u003e {\n      setInterval(() =\u003e {\n        bridge.sendMessage({\n          type: 'streaming-event',\n          payload: 'stream data!',\n        })\n      }, 1000)\n    })\n  })\n\n  return (\n    \u003cWebView\n      source={{ uri: 'Web.bundle/index.html' }}\n      ref={ref}\n      onMessage={onMessage}\n      javaScriptEnabled\n    /\u003e\n  )\n}\n\nexport default App\n```\n\nBrowser side\n```ts\nimport { sendMessage, on } from 'lepont/browser'\n\n// This triggers the event streaming\nsendMessage({ type: 'streaming-message' })\n\non('streaming-event', (payload) =\u003e {\n  // This fires every second from react-native side! :)\n  console.log(`payload=${payload}`)\n})\n```\n\n# Package html in the App\n\nYou can package your html and all other assets (css, js) into your app, and we strongly recommend that strategy for reducing significantly the app load time.\n\nSee [this article](https://medium.com/@caphun/react-native-load-local-static-site-inside-webview-2b93eb1c4225) for how to bundle the static web assets in your react-native apps.\n\n# Module (LePont bridge) ecosystem\n\nLePont aims to have wide range of plugin ecosystem. A lepont plugin is called *a lepont bridge*.\n\nCurrently LePont supports a few of plugins, but tries to support as many as possible in future.\n\nThe example of plugin usage:\n\n```tsx\nimport React from 'react'\nimport { WebView } from 'react-native-webview'\nimport { useBridge } from 'lepont'\nimport { AsyncStorageBridge } from '@lepont/async-storage/bridge'\nimport AsyncStorage from '@react-native-community/async-storage'\n\nconst App = () =\u003e {\n  const [ref, onMessage] = useBridge(\n    AsyncStorageBridge(AsyncStorage)\n  )\n\n  return (\n    \u003cWebView\n      source={{ uri: 'Web.bundle/index.html' }}\n      ref={ref}\n      onMessage={onMessage}\n      javaScriptEnabled\n    /\u003e\n  )\n}\n```\n\nThe browser side:\n\n```ts\nimport { setItem, getItem } from '@lepont/async-storage'\n\nawait setItem('key', 'value')\nawait getItem('key') // =\u003e 'value'\n```\n\n# API\n\n## `lepont` module\n\n`lepont` module is for react-native side.\n\n### `useBridge(...bridgeOptions: BridgeOption[]): [WebViewRef, WebViewOnMessage, { registry: Registry }]`\n\nRegisters the bridge to the registry by the given `BridgeOption`s. This returns `ref` and `onMessage` of WebView. You need to set these to `WebView` component to communicate with it.\n\nexample:\n\n```tsx\nconst [ref, onMessage] = useBridge(registry =\u003e {\n  registry.register('my-bridge', MyBridgeImpl)\n})\n\nreturn \u003cWebView ref={ref} onMessage={onMessage} /\u003e\n```\n\n### `type BridgeOption = (registry: Registry) =\u003e unknown`\n\nYou can pass BridgeOpion functional option to `useBridge` hook. In this function you can register your bridge type and implementation through `registry.register` method.\n\n### `Registry.register\u003cT\u003e(type: string, impl: BridgeImpl\u003cT\u003e): void`\n\nYou can register your bridge type and implementation with this method.\n\n### `type BridgeImpl = \u003cT\u003e(payload: T, brdige: Bridge) =\u003e unknown`\n\nThis is the type of bridge implemetation. The 1st param is the payload of your bridge call. The second param is the bridge object. The returned value is serialized and sent back to browser as the result of bridge call. If you like to send back data multiple times to browser you can use `bridge.sendMessage` method.\n\n### `bridge.sendMessage(message: Message): void`\n\nSends the message to browser side. To handle this message, you can register `on(type, handler)` call on browser side.\n\n## `lepont/browser` module\n\n`lepont/browser` module is for browser side.\n\n### `sendMessage\u003cT\u003e(message: Message): Promise\u003cT\u003e`\n\nSends the message to react-native side.\n\n### `on(type: string, handler: any =\u003e void)`\n\nRegisters the handler to the event of the given `type` name.\n\n### `off(type: string, handler: any =\u003e void)`\n\nUnregisters the handler from the event of the given `type` name.\n\n# Write `lepont` plugin\n\nYou can write reusable `lepont` plugin by using the above APIs.\n\nSee the following official plugins and their implementations for how to write a plugin. We also have [yeoman generator](https://github.com/kt3k/generator-lepont-bridge) for lepont plugin.\n\nYou can scaffold the plugin repository by hitting the following command:\n\n```\nnpm i -g yo generator-lepont-bridge\nyo lepont-bridge\n```\n\n# Official Plugins\n\n- [@lepont/async-storage][]\n  - Store data up to 6MB.\n- [@lepont/share][]\n  - Share text and files.\n- [@lepont/permissions-android][]\n  - Check and request permissions on Android devices.\n- [@lepont/platform][]\n  - Get the platform information.\n\n# TODO Plugins (contributions welcome)\n- `@lepont/cameraroll`\n  - Wrapper of `@react-native-community/cameraroll`\n- `@lepont/fs`\n  - Wrapper of `react-native-fs`\n- `@lepont/device-info`\n  - Access device information from browser\n  - based on [react-native-device-info](https://github.com/react-native-community/react-native-device-info)\n- `@lepont/communications`\n  - Communication utilities\n  - based on [react-native-communications](https://github.com/anarchicknight/react-native-communications)\n\n# License\n\nMIT\n\n[@lepont/async-storage]: https://github.com/kt3k/lepont-async-storage\n[@lepont/share]: https://github.com/kt3k/lepont-share\n[@lepont/permissions-android]: https://github.com/kt3k/lepont-permissions-android\n[@lepont/platform]: https://github.com/kt3k/lepont-platform\n[AsyncStorage]: https://github.com/react-native-community/async-storage\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkt3k%2Flepont","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkt3k%2Flepont","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkt3k%2Flepont/lists"}