RepoPilotOpen in app →

happydog-intj/JsBridge

android java and javascript bridge, inspired by wechat webview jsbridge

Mixed

Slowing — last commit 11mo ago

weakest axis
Use as dependencyConcerns

no license — legally unclear

Fork & modifyConcerns

no license — can't legally use code

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isConcerns

no license — can't legally use code; last commit was 11mo ago

  • Last commit 11mo ago
  • 31+ active contributors
  • Distributed ownership (top contributor 43% of recent commits)
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Slowing — last commit 11mo ago
  • No license — legally unclear to depend on
What would change the summary?
  • Use as dependency ConcernsMixed if: publish a permissive license (MIT, Apache-2.0, etc.)
  • Fork & modify ConcernsMixed if: add a LICENSE file
  • Deploy as-is ConcernsMixed if: add a LICENSE file

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Great to learn from" badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/happydog-intj/jsbridge?axis=learn)](https://repopilot.app/r/happydog-intj/jsbridge)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/happydog-intj/jsbridge on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: happydog-intj/JsBridge

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/happydog-intj/JsBridge shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Slowing — last commit 11mo ago

  • Last commit 11mo ago
  • 31+ active contributors
  • Distributed ownership (top contributor 43% of recent commits)
  • CI configured
  • Tests present
  • ⚠ Slowing — last commit 11mo ago
  • ⚠ No license — legally unclear to depend on

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live happydog-intj/JsBridge repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/happydog-intj/JsBridge.

What it runs against: a local clone of happydog-intj/JsBridge — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in happydog-intj/JsBridge | Confirms the artifact applies here, not a fork | | 2 | Default branch master exists | Catches branch renames | | 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 4 | Last commit ≤ 359 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>happydog-intj/JsBridge</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of happydog-intj/JsBridge. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/happydog-intj/JsBridge.git
#   cd JsBridge
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of happydog-intj/JsBridge and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "happydog-intj/JsBridge(\\.git)?\\b" \\
  && ok "origin remote is happydog-intj/JsBridge" \\
  || miss "origin remote is not happydog-intj/JsBridge (artifact may be from a fork)"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java" \\
  && ok "library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java" \\
  || miss "missing critical file: library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java"
test -f "library/src/main/java/com/github/lzyzsd/jsbridge/WebViewJavascriptBridge.java" \\
  && ok "library/src/main/java/com/github/lzyzsd/jsbridge/WebViewJavascriptBridge.java" \\
  || miss "missing critical file: library/src/main/java/com/github/lzyzsd/jsbridge/WebViewJavascriptBridge.java"
test -f "library/src/main/assets/WebViewJavascriptBridge.js" \\
  && ok "library/src/main/assets/WebViewJavascriptBridge.js" \\
  || miss "missing critical file: library/src/main/assets/WebViewJavascriptBridge.js"
test -f "library/src/main/java/com/github/lzyzsd/jsbridge/BridgeHandler.java" \\
  && ok "library/src/main/java/com/github/lzyzsd/jsbridge/BridgeHandler.java" \\
  || miss "missing critical file: library/src/main/java/com/github/lzyzsd/jsbridge/BridgeHandler.java"
test -f "library/src/main/java/com/github/lzyzsd/jsbridge/Message.java" \\
  && ok "library/src/main/java/com/github/lzyzsd/jsbridge/Message.java" \\
  || miss "missing critical file: library/src/main/java/com/github/lzyzsd/jsbridge/Message.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 359 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~329d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/happydog-intj/JsBridge"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

JsBridge is an Android Java-to-JavaScript bridge library that enables safe, bidirectional communication between WebView code and native Java handlers. It provides handler registration on both sides (Java and JS) with callback support, inspired by WeChat's implementation, allowing JS to call Java methods and vice versa through a serialized message queue protocol implemented in WebViewJavascriptBridge.js. Standard Android library structure: library/ is the core JsBridge module (51KB Java, WebViewJavascriptBridge.js in assets/), example/ is a working reference app with MainActivity.java and demo.html/persistent_callback_demo.html in assets/. BridgeWebView is the main WebView subclass users integrate; handlers are registered via registerHandler() calls on both sides.

👥Who it's for

Android developers building hybrid applications who need to expose native Java functionality (sensors, file I/O, hardware access) to JavaScript running in WebViews, or who need to invoke JavaScript functions from Java code without dealing with raw WebView JavaScript injection APIs.

🌱Maturity & risk

Mature but dormant. The project reached stable v1.0.4 (available on JitPack), has comprehensive example code in example/src/main/java/com/github/lzyzsd/jsbridge/example/ with MainActivity and CustomWebView implementations, and includes CI via GitHub Actions (android.yml). However, no recent commit timestamps are visible and the inspiration notes suggest it's a maintained-but-not-actively-evolved implementation of WeChat's proven pattern.

Low risk for baseline use, moderate risk for maintenance. Single maintainer (lzyzsd), no visible test suite in the file list, and dependency on legacy Android WebView APIs that Google has evolved. The Gson dependency (visible in README examples) is standard but add-on. No lock-in risk since the bridge protocol is straightforward and documented.

Active areas of work

No active development signals visible in the provided data. The repository appears stable and complete for its stated scope; maintenance is likely reactive (bug fixes if reported) rather than feature-driven.

🚀Get running

Clone: git clone https://github.com/lzyzsd/JsBridge.git && cd JsBridge. Build: ./gradlew build (gradlew provided). Run example: open example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java in Android Studio and deploy to a device/emulator.

Daily commands: Android Studio: File → Open → select JsBridge root. Sync Gradle. Right-click example module → Run 'app'. Or via CLI: ./gradlew example:installDebug && adb shell am start -n com.github.lzyzsd.jsbridge.example/.MainActivity.

🗺️Map of the codebase

  • library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java — Core WebView subclass that implements the JS-Java bridge; entry point for all Android-side integration
  • library/src/main/java/com/github/lzyzsd/jsbridge/WebViewJavascriptBridge.java — Main bridge orchestrator managing handler registration, message queuing, and JS-Java communication protocol
  • library/src/main/assets/WebViewJavascriptBridge.js — JavaScript bridge implementation injected into WebView; handles JS→Java message dispatch and callback routing
  • library/src/main/java/com/github/lzyzsd/jsbridge/BridgeHandler.java — Interface contract for handlers that receive calls from JavaScript with async response capability
  • library/src/main/java/com/github/lzyzsd/jsbridge/Message.java — Data model for all bridge messages exchanged between Java and JavaScript layers
  • example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java — Complete integration example showing handler registration, WebView setup, and bidirectional calls

🛠️How to make changes

Add a new Java handler callable from JavaScript

  1. Create handler implementation in your Activity/Fragment by implementing BridgeHandler interface with handler(String data, CallBackFunction function) method (example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java)
  2. Register handler on BridgeWebView instance via webView.registerHandler("handlerName", new BridgeHandler() { ... }) (example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java)
  3. Call from JavaScript: WebViewJavascriptBridge.callHandler('handlerName', {data}, function(response) { ... }) (example/src/main/assets/demo.html)

Add a new JavaScript function callable from Java

  1. Define JavaScript handler in your HTML/JS: WebViewJavascriptBridge.registerHandler('jsHandlerName', function(data, responseCallback) { ... }) (example/src/main/assets/demo.html)
  2. Call from Java code: webView.callHandler('jsHandlerName', {jsonData}, new OnBridgeCallback() { ... }) (library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java)

Setup BridgeWebView in a new Activity

  1. Add BridgeWebView to layout XML with id and standard WebView attributes (example/src/main/res/layout/activity_main.xml)
  2. In Activity onCreate: find BridgeWebView, create DefaultHandler or custom handler, call setDefaultHandler() and registerHandler() (example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java)
  3. Load HTML page: webView.loadUrl('file:///android_asset/your_page.html') or remote URL (example/src/main/java/com/github/lzyzsd/jsbridge/example/MainActivity.java)

Implement persistent callbacks (handler called multiple times)

  1. Register handler that does not call function.onCallBack() immediately; instead store callback reference (library/src/test/java/com/github/lzyzsd/jsbridge/PersistentCallbackTest.java)
  2. Later, invoke function.onCallBack(data) multiple times with flag parameter to indicate persistence (library/src/test/assets/test_persistent_callback.html)

🔧Why these technologies

  • Android WebView — Native container for hybrid apps; provides secure JavaScript execution and Java interop hooks
  • JavaScriptInterface annotation — Android's built-in bridge mechanism (used internally); allows Java methods to be invoked from JavaScript
  • URL scheme interception — Legacy fallback for JS→Java calls on older Android versions; enables custom protocol handling
  • Message queue pattern — Decouples timing of JS and Java execution; ensures calls complete even if WebView is busy loading

⚖️Trade-offs already made

  • Synchronous JavaScript injection vs. asynchronous callback handling

    • Why: Bridge must synchronously inject JS to guarantee availability before page scripts run, but handler responses use async callbacks to avoid blocking
    • Consequence: Slight latency on initial page load for JS injection; handlers must adopt callback-based patterns rather than blocking calls
  • Message envelope (Message class) vs. direct data passing

    • Why: Unified message format with metadata (callbackId, handler name, isResponse flag) enables request-response correlation and error handling
    • Consequence: Small serialization overhead; simplifies implementation at cost of slightly larger JSON payloads
  • DefaultHandler pattern vs. throwing exceptions for unknown handlers

    • Why: DefaultHandler provides graceful fallback for unregistered methods; improves developer experience
    • Consequence: Developers may silently ignore missing handlers unless DefaultHandler logs explicitly

🚫Non-goals (don't propose these)

  • Does not implement authentication or permission checks—assumes WebView content is trusted
  • Does not provide state serialization or persistence across app restart
  • Does not handle WebWorkers or multiple WebView contexts within one app
  • Not designed for real-time bidirectional streaming or high-frequency polling
  • Does not support TypeScript or compile-to-JS languages natively

🪤Traps & gotchas

No explicit version constraints documented; relies on Gradle to resolve library dependencies. WebView API surface differs across Android API levels (15+); the bridge assumes WebView JS injection is available and enabled. No obfuscation by default in library/proguard-rules.pro, so keep handler method names stable if you apply ProGuard. The persistent callback demo (persistent_callback_demo.html) is present but not documented in README—check it for advanced use cases. Message queue is in-memory and non-persistent; app backgrounding will drop queued messages.

🏗️Architecture

💡Concepts to learn

  • JavaScript Bridge / WebView JS Interface — The core pattern JsBridge implements; understanding how native and JS code communicate across the WebView boundary is essential to using or extending this library
  • Callback ID Correlation in Async Messaging — JsBridge uses unique callback IDs to match responses to requests in the message queue; this pattern is crucial for bidirectional async RPC and appears throughout the code
  • Message Queue / Event Loop Integration — JsBridge queues messages and injects them into the WebView's JS engine; understanding how the queue buffers calls before JS is ready prevents race conditions
  • Handler Registration Pattern — Both Java and JS sides use registerHandler() to expose functions; this loose coupling pattern decouples caller from implementation and is central to the API design
  • JSON Serialization for IPC — All data crossing the Java-JS boundary is serialized to JSON (visible in MainActivity examples with Gson); this ensures cross-language type safety and is why Gson is a de facto dependency
  • WebView JavaScript Injection / evalJs — JsBridge injects WebViewJavascriptBridge.js and executes JS code from Java via WebView.loadUrl(); understanding the injection timing and security model is critical for custom extensions
  • Tencent/VasSonic — WeChat's hybrid WebView framework; the original inspiration and sibling ecosystem—JsBridge implements the JS bridge pattern Tencent pioneered
  • hashrabbit/android-jsBridge — Another Android-WebView-to-JS bridge; useful for understanding alternative design choices (message format, threading model) in the same problem domain
  • airbnb/epoxy — Modern Android view binding library; relevant for developers who want to replace custom WebView management with declarative Epoxy bindings in new projects
  • square/okhttp — HTTP client often paired with JsBridge for secure server communication from hybrid apps; bridges typically delegate API calls to OkHttp from JS handlers

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for BridgeWebView.java and WebViewJavascriptBridge.java

The library has test assets (test_persistent_callback.html) but no visible Java unit tests in library/src/test/java/com. Core bridge functionality like message passing, handler registration, and callback mechanisms need JUnit tests to ensure reliability and prevent regressions.

  • [ ] Create test classes in library/src/test/java/com/github/lzyzsd/jsbridge/ for BridgeWebView, WebViewJavascriptBridge, and Message classes
  • [ ] Add unit tests covering: handler registration/invocation, JavaScript callback persistence, message serialization, and error handling
  • [ ] Add Mockito or similar mocking framework to build.gradle for WebView mocking
  • [ ] Verify tests run in CI pipeline via .github/workflows/android.yml

Create Android Instrumentation Tests for Java-JavaScript bridge integration

The example app has demo.html and persistent_callback_demo.html but there are no androidTest integration tests. These would validate end-to-end bridge behavior on actual Android devices/emulators, testing real WebView-to-Java communication.

  • [ ] Create library/src/androidTest/java/com/github/lzyzsd/jsbridge/ directory with AndroidTestCase classes
  • [ ] Add instrumentation tests that load HTML files from library/src/test/assets/ and verify bidirectional calls work
  • [ ] Test persistent callbacks, handler registration, and error scenarios with actual WebView instances
  • [ ] Add android instrumentation test task to .github/workflows/android.yml

Add ProGuard/R8 configuration documentation and update proguard-rules.pro with bridge-specific rules

The project has proguard-rules.pro files in both library/ and example/, but they're likely incomplete. JsBridge uses reflection for handler registration and JavaScript bridges, which commonly break under obfuscation. Missing rules could cause silent failures in production builds.

  • [ ] Review library/proguard-rules.pro and add keep rules for BridgeHandler, BridgeWebView, and any classes used via reflection in WebViewJavascriptBridge.java
  • [ ] Add rules to preserve handler method signatures and bridge callback mechanism
  • [ ] Create a troubleshooting section in README.md documenting ProGuard gotchas with example configurations
  • [ ] Add a test variant in library/build.gradle with minifyEnabled=true to catch ProGuard issues early

🌿Good first issues

  • Add unit tests for BridgeHandler and CallBackFunction in library/src/test/ to verify handler invocation and callback serialization match the WebViewJavascriptBridge.js protocol
  • Document the message queue protocol by adding JSDoc comments to WebViewJavascriptBridge.js (currently minimal) explaining the JSON structure, callback ID mapping, and handler dispatch algorithm
  • Create a second example app (example-kotlin/) that mirrors MainActivity.java but uses Kotlin and showcases coroutine-based async handler responses instead of callback functions

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 78291ba — Merge pull request #282 from uknownothingsnow/openhands-workspace-4mkmbnes (happydog-intj)
  • a4a18ce — Fix issue #280: Add support for persistent callbacks (openhands-agent)
  • a4c5078 — Merge pull request #281 from uknownothingsnow/improve-readme-documentation (happydog-intj)
  • a4a95bb — Update android.yml (happydog-intj)
  • aaf4042 — Improve README documentation (openhands-agent)
  • a0239f1 — Merge pull request #272 from thorjay/master (happydog-intj)
  • 124af30 — Merge pull request #270 from thorjay/fixcustomview (happydog-intj)
  • 50ed361 — Merge pull request #276 from liu-wanshun/patch-1 (happydog-intj)
  • 7a7a210 — Delete library/src/main/res directory (liu-wanshun)
  • 44f5c65 — [update]:[update README,更新CustomWebview的教程] (leijie)

🔒Security observations

This Android JsBridge library has moderate security concerns, primarily related to outdated dependencies (Gradle 4.1.3, JCenter repository), insufficient WebView origin validation, and lack of documented input validation patterns. The core risk

  • High · Outdated Gradle Build Tool — build.gradle. The project uses Gradle 4.1.3 (classpath 'com.android.tools.build:gradle:4.1.3'), which is significantly outdated and contains known security vulnerabilities. This version was released in 2018 and no longer receives security updates. Fix: Update to the latest stable version of Android Gradle Plugin (currently 8.x). This ensures access to security patches and improved build safety.
  • High · Deprecated JCenter Repository — build.gradle (allprojects section). The build configuration uses JCenter repository which was shut down in May 2021. Using deprecated repositories can lead to dependency resolution issues and inability to receive critical security updates. Fix: Remove jcenter() repository references and rely on Maven Central or Google Maven repositories exclusively.
  • High · WebView Bridge without Origin Validation — library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebView.java, library/src/main/java/com/github/lzyzsd/jsbridge/BridgeWebViewClient.java. The JsBridge implementation provides JavaScript-to-Java bridging capabilities. Without proper origin validation in BridgeWebView and BridgeWebViewClient, malicious scripts could potentially execute arbitrary Java code if the WebView loads untrusted content. Fix: Implement strict origin validation, restrict JavaScript bridge access to whitelisted domains only, and disable JavaScript from untrusted sources.
  • High · Insecure JavaScript Bridge Exposure — library/src/main/assets/WebViewJavascriptBridge.js. The JavaScript bridge (WebViewJavascriptBridge.js) is stored as a web asset and could be vulnerable to Man-in-the-Middle attacks or injection if the WebView loads content over HTTP instead of HTTPS. Fix: Enforce HTTPS-only connections in WebView, implement Content Security Policy headers, and validate all loaded content.
  • Medium · Missing ProGuard Configuration for Sensitive Methods — library/proguard-rules.pro, example/proguard-rules.pro. While proguard-rules.pro files exist, there is no explicit indication that bridge handler methods are properly obfuscated and protected from reverse engineering, which could expose sensitive Java methods callable from JavaScript. Fix: Add ProGuard rules to keep bridge handler implementations and ensure proper obfuscation of sensitive methods to prevent reverse engineering.
  • Medium · No Input Validation Documentation — library/src/main/java/com/github/lzyzsd/jsbridge/BridgeHandler.java, library/src/main/java/com/github/lzyzsd/jsbridge/Message.java. The bridge handler pattern (BridgeHandler.java) lacks clear documentation or enforced input validation patterns. Without proper validation of parameters passed from JavaScript to Java, the application could be vulnerable to injection attacks. Fix: Implement comprehensive input validation for all bridge handler parameters. Document security best practices for custom handler implementations.
  • Medium · Insecure HTTP Repository URLs — build.gradle. The Javadoc configuration uses HTTP (not HTTPS) for the Oracle Java documentation link, which could potentially be subject to MITM attacks during documentation generation. Fix: Change 'http://docs.oracle.com/javase/7/docs/api' to 'https://docs.oracle.com/javase/7/docs/api'.
  • Low · Unencrypted Communication in Demo — example/src/main/assets/demo.html, example/src/main/assets/persistent_callback_demo.html. The example application (example/src/main/assets/demo.html) may contain demo code that loads content insecurely. Without HTTPS enforcement in the example, developers might copy patterns that lead to insecure implementations. Fix: Ensure all demo HTML files use HTTPS protocols and include security best practice comments for developers.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · happydog-intj/JsBridge — RepoPilot