JingMatrix/Vector
Modern Xposed Framework
Single-maintainer risk — review before adopting
weakest axiscopyleft license (GPL-3.0) — review compatibility; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 4d ago
- ✓9 active contributors
- ✓GPL-3.0 licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ⚠Single-maintainer risk — top contributor 85% of recent commits
- ⚠GPL-3.0 is copyleft — check downstream compatibility
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
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 "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/jingmatrix/vector)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/jingmatrix/vector on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: JingMatrix/Vector
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/JingMatrix/Vector 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 — Single-maintainer risk — review before adopting
- Last commit 4d ago
- 9 active contributors
- GPL-3.0 licensed
- CI configured
- ⚠ Single-maintainer risk — top contributor 85% of recent commits
- ⚠ GPL-3.0 is copyleft — check downstream compatibility
- ⚠ No test directory detected
<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 JingMatrix/Vector
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/JingMatrix/Vector.
What it runs against: a local clone of JingMatrix/Vector — 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 JingMatrix/Vector | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 34 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of JingMatrix/Vector. If you don't
# have one yet, run these first:
#
# git clone https://github.com/JingMatrix/Vector.git
# cd Vector
#
# 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 JingMatrix/Vector and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "JingMatrix/Vector(\\.git)?\\b" \\
&& ok "origin remote is JingMatrix/Vector" \\
|| miss "origin remote is not JingMatrix/Vector (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-3.0" \\
|| miss "license drift — was GPL-3.0 at generation time"
# 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 "app/src/main/java/org/lsposed/manager/ConfigManager.java" \\
&& ok "app/src/main/java/org/lsposed/manager/ConfigManager.java" \\
|| miss "missing critical file: app/src/main/java/org/lsposed/manager/ConfigManager.java"
test -f "app/src/main/java/org/lsposed/manager/App.java" \\
&& ok "app/src/main/java/org/lsposed/manager/App.java" \\
|| miss "missing critical file: app/src/main/java/org/lsposed/manager/App.java"
test -f "app/src/main/java/org/lsposed/manager/ui/activity/MainActivity.java" \\
&& ok "app/src/main/java/org/lsposed/manager/ui/activity/MainActivity.java" \\
|| miss "missing critical file: app/src/main/java/org/lsposed/manager/ui/activity/MainActivity.java"
test -f "app/src/main/java/org/lsposed/manager/util/ModuleUtil.java" \\
&& ok "app/src/main/java/org/lsposed/manager/util/ModuleUtil.java" \\
|| miss "missing critical file: app/src/main/java/org/lsposed/manager/util/ModuleUtil.java"
test -f "app/src/main/java/org/lsposed/manager/repo/RepoLoader.java" \\
&& ok "app/src/main/java/org/lsposed/manager/repo/RepoLoader.java" \\
|| miss "missing critical file: app/src/main/java/org/lsposed/manager/repo/RepoLoader.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 34 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~4d)"
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/JingMatrix/Vector"
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).
⚡TL;DR
Vector is a Zygisk-based ART hooking framework for Android that maintains Xposed API compatibility, allowing modules to instrument and modify system/app behavior at the native level without modifying APK files. Built on LSPlant, it enables non-destructive, runtime code injection across Android 8.1–17 with ROM-agnostic compatibility. Hybrid monorepo: app/ contains the manager UI (Java + Kotlin in app/src/main/java/org/lsposed/manager/) with adapters, repos, and activities; native hooking logic in separate C++ modules (236KB); WebView assets for UI templates in app/src/main/assets/webview/; build orchestrated via Gradle Kotlin DSL (app/build.gradle.kts).
👥Who it's for
Android module developers and power users who need to create Xposed modules for system behavior modification; reverse engineers and security researchers requiring runtime instrumentation; ROM developers and custom Android enthusiasts seeking a modern, stable hooking framework alternative to legacy Xposed.
🌱Maturity & risk
Active and production-ready: the project has recent CI/CD pipelines (GitHub Actions in .github/workflows/core.yml), multi-language codebase (~768KB Java, ~280KB Kotlin, ~236KB C++), structured issue templates, and Crowdin localization integration. Actively maintained with canary builds from master branch and stable releases on GitHub.
Single-maintainer risk (JingMatrix as primary author); depends on external Zygisk/Magisk ecosystem stability and LSPlant submodule (LSPlant referenced in README). No visible test suite in file structure, increasing regression risk. Breaking changes possible across Android versions (supports 8.1–17 Beta with ART variations).
Active areas of work
Active development on the manager UI (see app/src/main/java/org/lsposed/manager/ structure) and module repository integration (RepoLoader.java, model classes for OnlineModule, Release, Collaborator). CI workflows trigger on push to master. Crowdin integration indicates ongoing localization effort.
🚀Get running
Clone with submodules: git clone --recursive https://github.com/JingMatrix/Vector.git. Build with Gradle: ./gradlew build (requires JDK, Gradle, Android SDK). Install as Magisk/KernelSU module via your root manager after building the APK output.
Daily commands:
Build: ./gradlew assembleDebug (or assembleRelease). The manager app APK is generated in app/build/outputs/apk/. Install on rooted device with Zygisk: adb install app/build/outputs/apk/*/app-*.apk, then access via system notification post-reboot. Debug builds recommended for troubleshooting (see README caution on PR builds).
🗺️Map of the codebase
app/src/main/java/org/lsposed/manager/ConfigManager.java— Central configuration manager that bridges the LSPosed framework and manager UI—all module and system state flows through hereapp/src/main/java/org/lsposed/manager/App.java— Application entry point and lifecycle controller—required for understanding initialization, theme setup, and global stateapp/src/main/java/org/lsposed/manager/ui/activity/MainActivity.java— Main UI activity and navigation hub—orchestrates fragment transitions and manages toolbar/drawer UI patterns used throughoutapp/src/main/java/org/lsposed/manager/util/ModuleUtil.java— Core module discovery, loading, and metadata extraction logic—essential for understanding how modules are parsed and managedapp/src/main/java/org/lsposed/manager/repo/RepoLoader.java— Handles remote module repository fetching and caching—critical for update and discovery featuresapp/build.gradle.kts— Build configuration, dependencies, and target SDK versions—determines compatibility and required libraries for all development
🛠️How to make changes
Add a new manager fragment/tab
- Create a new Fragment class extending BaseFragment in app/src/main/java/org/lsposed/manager/ui/fragment/ (
app/src/main/java/org/lsposed/manager/ui/fragment/NewFeatureFragment.java) - Override onViewCreated() and implement UI using Material Design components; follow the pattern in ModulesFragment.java (
app/src/main/java/org/lsposed/manager/ui/fragment/BaseFragment.java) - Register the fragment in MainActivity.java's navigation setup (menu/navigation drawer) (
app/src/main/java/org/lsposed/manager/ui/activity/MainActivity.java) - Add menu item XML resource in app/src/main/res/ (drawable icons + menu definitions) (
app/src/main/res/drawable/ic_baseline_extension_24.xml)
Add a new module management operation
- Extend or add a new method in ModuleUtil.java to perform the operation (e.g., enable, disable, delete) (
app/src/main/java/org/lsposed/manager/util/ModuleUtil.java) - Call ConfigManager's corresponding IPC bridge method to communicate with the LSPosed framework (
app/src/main/java/org/lsposed/manager/ConfigManager.java) - Invoke the operation from the UI layer (Fragment or Adapter) and handle success/error callbacks (
app/src/main/java/org/lsposed/manager/ui/fragment/ModulesFragment.java)
Integrate a new online module repository source
- Add a new data model class in app/src/main/java/org/lsposed/manager/repo/model/ extending or mirroring OnlineModule.java structure (
app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java) - Extend RepoLoader.java with a new network client method that fetches from your repository API (
app/src/main/java/org/lsposed/manager/repo/RepoLoader.java) - Update the RepoFragment UI to display modules from the new source, following the existing adapter pattern in ScopeAdapter.java (
app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java) - Add configuration constants in Constants.java for the new repository URL or API keys (
app/src/main/java/org/lsposed/manager/Constants.java)
Add a new settings option
- Create preference entries in app/src/main/res/xml/ (or add to existing preferences file) (
app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java) - Extend SettingsFragment.java to handle the new preference and bind it to ConfigManager or local SharedPreferences (
app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java) - Store/retrieve the setting using ThemeUtil or a new utility if it affects app behavior globally (
app/src/main/java/org/lsposed/manager/util/ThemeUtil.java)
🔧Why these technologies
- Android Jetpack (Fragment, Navigation, LiveData) — Provides modern lifecycle management, reactive data binding, and standardized navigation patterns for the manager UI
- Material Design Components — Ensures consistent, accessible, and polished UI across all manager screens with built-in dark/light theme support
- Binder IPC (LSPManagerServiceHolder) — Low-latency inter-process communication with the LSPosed framework daemon running with elevated privileges
- Gradle Kotlin DSL (build.gradle.kts) — Type-safe build configuration and dependency management with modern Kotlin-based tooling
- RecyclerView + Adapter pattern — Efficient, scrollable lists for modules and apps with automatic diffing and smooth animations
⚖️Trade-offs already made
-
Monolithic ConfigManager as central state broker
- Why: Simplifies IPC communication and centralizes framework interaction logic in one place
- Consequence: ConfigManager can become a God Object; consider refactoring into domain-specific managers for large feature additions
-
Synchronous file I/O in ModuleUtil (module discovery)
- Why: Straightforward parsing
- Consequence: undefined
🪤Traps & gotchas
Zygisk environment required: Cannot run on stock Android; requires Magisk/KernelSU with Zygisk enabled (NeoZygisk referenced in README). ART version variance: Android 8.1–17 Beta have divergent ART internals; native C++ hooks must target specific versions. Submodule dependency: LSPlant is a git submodule—missing --recursive clone fails native compilation. No test suite evident: Verify against real devices; emulator behavior may differ. GitHub CI artifact access: Debug/canary builds require GitHub login.
🏗️Architecture
💡Concepts to learn
- ART Runtime Hooking — Vector's core capability: understanding ART (Android Runtime) method resolution and native instrumentation is essential to grasp how Vector intercepts and modifies code execution without recompiling APKs
- Zygisk Module System — Vector operates as a Zygisk module loaded during Zygote process initialization; understanding Zygisk's lifecycle and process injection model is critical to deploying and debugging Vector
- In-Memory Code Injection — Vector's core technique: replacing bytecode or native functions at runtime without persistent APK modification; understanding why this enables non-destructive, ROM-agnostic changes is fundamental
- Xposed Framework API Compatibility — Vector maintains legacy Xposed method signatures (e.g.,
XposedHelpers,XC_MethodHook) to allow existing modules to run unmodified; knowing this compatibility layer is essential for writing Vector modules - Gradle Multi-Language Builds (Java/Kotlin/C++) — Vector's build orchestrates Java UI, Kotlin utilities, and C++ native hooks via Gradle + CMake; understanding cross-language compilation and artifact linking is necessary for modifying or extending the framework
- WebView-Based UI Templating — Vector's manager UI renders module documentation and HTML templates via WebView with injected CSS themes (
colors_dark.css,syntax.css); modifying UI requires understanding WebView sandboxing and CSS asset management - GitHub Actions CI/CD for Multi-Target Builds — Vector's
.github/workflows/core.ymlbuilds against multiple Android versions and architectures; understanding matrix builds and artifact publishing is necessary to contribute to release engineering
🔗Related repos
JingMatrix/LSPlant— Direct dependency: Vector's native hooking engine is built on LSPlant's ART instrumentation librarytopjohnwu/Magisk— Runtime environment: Vector requires Magisk or KernelSU with Zygisk as the module loader and privilege escalation frameworkrovo89/Xposed— Spiritual predecessor: Vector maintains Xposed API compatibility while modernizing the framework for current Android versionsJingMatrix/NeoZygisk— Companion project: Optimized Zygisk implementation recommended in README for stable Vector module operationElderDrivers/EdXposed— Alternative Xposed implementation: post-Xposed modernization attempt, shares similar goals of API-compatible hooking on current Android
🪄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 instrumentation tests for UI fragments and activities
The repo contains multiple UI components (MainActivity, AppListFragment, ModulesFragment, RepoFragment, etc.) but no visible test files in app/src. Android framework apps benefit significantly from instrumentation tests to catch regressions in UI state, navigation, and user interactions. This is especially critical for a framework app that modifies system behavior.
- [ ] Create app/src/androidTest/java/org/lsposed/manager/ui/activity/ directory structure
- [ ] Add instrumentation tests for BaseActivity lifecycle and configuration changes
- [ ] Add fragment tests for AppListFragment, ModulesFragment, and RepoFragment covering adapter interactions and list operations
- [ ] Configure androidTest in app/build.gradle.kts with androidx.test dependencies
- [ ] Add test configuration to .github/workflows/core.yml to run instrumentation tests
Add unit tests for repo model classes and RepoLoader
The repo/model/ directory contains data classes (OnlineModule, Release, ReleaseAsset, Collaborator) and RepoLoader handles network/parsing logic. These classes lack visible unit test coverage. Testing the model deserialization and RepoLoader error handling would catch JSON parsing regressions and API contract violations early.
- [ ] Create app/src/test/java/org/lsposed/manager/repo/ directory structure
- [ ] Add unit tests for OnlineModule, Release, ReleaseAsset, Collaborator JSON deserialization with sample fixtures
- [ ] Add unit tests for RepoLoader covering success cases, network errors, and malformed responses
- [ ] Configure test dependencies in app/build.gradle.kts (JUnit, Mockito, JSON test fixtures)
- [ ] Add test execution to .github/workflows/core.yml
Add localization validation and completeness checks in CI
The repo uses Crowdin for localization (evident from .github/workflows/crowdin.yml and assets like colors_dark.css, colors_light.css), but there's no automated check to validate that all string resources are properly translated or catch missing translations. This prevents incomplete locale files from being merged.
- [ ] Create a custom GitHub Action or script at scripts/validate-strings.gradle or scripts/check-translations.py
- [ ] Scan app/src/main/res/values*/strings.xml (once created) to verify completeness against base strings.xml
- [ ] Add validation step to .github/workflows/core.yml to run before build
- [ ] Configure action to fail the build if any locale is missing >5% of strings
- [ ] Document localization guidelines in CONTRIBUTING.md (create if missing)
🌿Good first issues
- Add unit test coverage for
app/src/main/java/org/lsposed/manager/repo/RepoLoader.javato verify parsing of GitHub release API responses (currently no tests visible for this critical module). - Implement missing error handling UI in
MainActivity.javafor failed module installations and display user-friendly error messages (currently minimal error handling visible). - Expand WebView CSS themes in
app/src/main/assets/webview/(add system dark-mode detection and adaptive color scheme support beyond current light/dark pair).
⭐Top contributors
Click to expand
Top contributors
- @JingMatrix — 85 commits
- @dependabot[bot] — 8 commits
- @HdShare — 1 commits
- @kiber-io — 1 commits
- @AnatolyJacobs — 1 commits
📝Recent commits
Click to expand
Recent commits
cf1153e— Fix original method invocation argument spreading (#701) (HdShare)b71c33d— Disable dex obfuscation for debug builds (#670) (JingMatrix)6990e7e— Implement missingauto_includefeature in daemon (#681) (JingMatrix)846527e— EnsuremiscPathis initialized for system_server modules (#678) (kiber-io)ec3e6f2— Clarifylibxposedmodules loading process (#662) (JingMatrix)1983e00— Correctly handle null thisObject in VectorChain for static methods (#658) (JingMatrix)ddcfa3d— Fix Binder IPC side-channel detection in CallBooleanMethodV hook (#655) (JingMatrix)9d89508— Startserialregistration in early daemon initialization (#648) (JingMatrix)e811522— Resolve Picocli InitializationException in release builds (#645) (AnatolyJacobs)0b0d740— Update project references and polish content of docs (#639) (JingMatrix)
🔒Security observations
- High · Potential Web-based XSS Vulnerability in WebView Components —
app/src/main/java/org/lsposed/manager/ui/widget/ScrollWebView.java, app/src/main/assets/webview/template.html, app/src/main/assets/webview/template_dark.html. The codebase includes WebView components (ScrollWebView.java) and HTML templates for rendering dynamic content (template.html, template_dark.html). Without proper input sanitization and content security policies, these could be vulnerable to XSS attacks if user-controlled data is rendered in the WebView. Fix: 1) Implement Content Security Policy (CSP) headers in HTML templates. 2) Sanitize all user input before rendering in WebView. 3) Use WebView.addJavascriptInterface() carefully and mark interfaces with @JavascriptInterface. 4) Disable file:// protocol access if not necessary via setAllowFileAccess(false). - High · Unsafe Network Communication via Custom DNS Factory —
app/src/main/java/org/lsposed/manager/util/CloudflareDNS.java, app/src/main/java/org/lsposed/manager/util/NoSniFactory.java. CloudflareDNS.java and NoSniFactory.java implement custom network configurations. These could potentially bypass certificate pinning or introduce MITM vulnerabilities if not properly implemented. Custom DNS handling without validation could expose the application to DNS spoofing attacks. Fix: 1) Implement certificate pinning for critical API endpoints. 2) Validate all DNS responses. 3) Use modern TLS 1.3 with proper cipher suites. 4) Audit custom network factory implementations for security flaws. 5) Consider using standard HTTPS without custom DNS resolution unless absolutely necessary. - High · Potential Code Injection via Module Loading —
app/src/main/java/org/lsposed/manager/repo/RepoLoader.java, app/src/main/java/org/lsposed/manager/repo/model/OnlineModule.java, app/src/main/java/org/lsposed/manager/repo/model/ReleaseAsset.java. RepoLoader.java handles loading of online modules (OnlineModule.java) from remote repositories. Without proper signature verification, this could allow loading of malicious code. The repo model includes ReleaseAsset.java which likely handles binary downloads. Fix: 1) Implement cryptographic signature verification for all downloaded modules. 2) Maintain a whitelist of trusted repository sources. 3) Verify checksums (SHA256) of downloaded assets. 4) Implement sandboxing for module execution. 5) Log all module installation/loading activities. - Medium · Insecure Data Handling in Backup Utilities —
app/src/main/java/org/lsposed/manager/util/BackupUtils.java. BackupUtils.java handles backup functionality. Backups of sensitive data (module configurations, logs) may not be encrypted, potentially exposing sensitive information if the backup files are accessed. Fix: 1) Encrypt all backup files using a strong cipher (AES-256-GCM). 2) Implement access controls for backup files (restrict to app UID). 3) Use Android KeyStore for key management. 4) Implement integrity verification (HMAC) for backups. - Medium · Potential Information Disclosure via Logs —
app/src/main/java/org/lsposed/manager/ui/fragment/LogsFragment.java. LogsFragment.java handles display of logs, which may contain sensitive information including module names, hook points, or system internals. Logs may be accessible to other applications with READ_LOGS permission. Fix: 1) Implement log filtering to remove sensitive data. 2) Set logs to not be world-readable. 3) Implement log rotation and deletion policies. 4) Consider disabling verbose logging in production builds. 5) Warn users about log privacy implications. - Medium · Missing ProGuard Configuration for Sensitive Code —
app/proguard-rules.pro. While app/proguard-rules.pro exists, the framework handles hooking and code injection. Inadequate obfuscation could expose hook implementation details, making it easier to reverse engineer protection mechanisms. Fix: 1) Apply aggressive ProGuard rules to hook-related code. 2) Use name obfusc
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.