vaxilu/x-ui
支持多协议多用户的 xray 面板
Stale — last commit 2y ago
weakest axiscopyleft license (GPL-3.0) — review compatibility; last commit was 2y ago…
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.
- ✓8 active contributors
- ✓GPL-3.0 licensed
- ✓CI configured
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 74% of recent commits
- ⚠GPL-3.0 is copyleft — check downstream compatibility
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Failing → 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.
Earn the “Healthy” badge
Current signals for vaxilu/x-ui are Mixed. The embed flow is reserved for repos showing Healthy signals — the rest stay informational on this page so we're not putting a public call-out on your README. Address the items in the What would change the summary? dropdown above, then return to grab the embed code.
Common quick wins: green CI on default branch, no Critical CVEs in dependencies, recent commits on the default branch, a permissive license, and a published README.md with a quickstart.
Onboarding doc
Onboarding: vaxilu/x-ui
Generated by RepoPilot · 2026-05-06 · 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/vaxilu/x-ui 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 — Stale — last commit 2y ago
- 8 active contributors
- GPL-3.0 licensed
- CI configured
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 74% 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 vaxilu/x-ui
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/vaxilu/x-ui.
What it runs against: a local clone of vaxilu/x-ui — 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 vaxilu/x-ui | 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 main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 655 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of vaxilu/x-ui. If you don't
# have one yet, run these first:
#
# git clone https://github.com/vaxilu/x-ui.git
# cd x-ui
#
# 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 vaxilu/x-ui and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "vaxilu/x-ui(\\.git)?\\b" \\
&& ok "origin remote is vaxilu/x-ui" \\
|| miss "origin remote is not vaxilu/x-ui (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 main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "main.go" \\
&& ok "main.go" \\
|| miss "missing critical file: main.go"
test -f "web/controller/index.go" \\
&& ok "web/controller/index.go" \\
|| miss "missing critical file: web/controller/index.go"
test -f "database/db.go" \\
&& ok "database/db.go" \\
|| miss "missing critical file: database/db.go"
test -f "config/config.go" \\
&& ok "config/config.go" \\
|| miss "missing critical file: config/config.go"
test -f "web/entity/entity.go" \\
&& ok "web/entity/entity.go" \\
|| miss "missing critical file: web/entity/entity.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 655 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~625d)"
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/vaxilu/x-ui"
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
x-ui is a multi-protocol, multi-user management panel for Xray (a VMESS/VLESS/Trojan proxy fork), written in Go with a JavaScript web UI. It provides a visual dashboard for managing VPN/proxy inbound configurations, user accounts, traffic statistics, and protocol routing without editing raw Xray JSON configs directly. Monolithic Go backend (main.go entry point) with pkg structure: config/ handles Xray template/setting persistence, database/ wraps SQLite via GORM, web/assets serves pre-built JavaScript frontend, v2ui/ handles migration from v2-ui, and util/ contains common helpers. Web UI is separate pre-compiled asset bundle (not dev-built here).
Who it's for
System administrators and VPS operators who deploy Xray proxy servers and need a web-based control panel to manage multiple users across protocols (VMESS, VLESS, Trojan, Shadowsocks, HTTP, SOCKS, Dokodemo-door) without CLI expertise. Contributors are primarily Go/JavaScript developers maintaining Chinese-language open-source infrastructure.
Maturity & risk
Actively developed and widely deployed (evident from installation script and Docker support), but repo maturity signals are mixed: no visible test suite in file list, CI/CD exists (release.yml), but single maintainer (vaxilu) and v1.x version indicate pre-production polish. Production-ready for experienced operators, but lacking comprehensive test coverage.
Moderate-to-high risk: single active maintainer (vaxilu), sparse dependency governance (TOML/gopsutil/GORM without pinned versions pre-go.mod), integrations with Telegram bot and Cloudflare DNS (added attack surface), and custom Xray core vendoring (bin/xray-linux-*) means upstream CVEs in Xray require manual recompilation. No visible security advisory process.
Active areas of work
Release workflow is automated (release.yml), suggesting regular builds. v2-ui migration path is documented, indicating active user base coming from older panels. Telegram bot feature marked 'in development' (not ready). Primary focus appears to be stability and feature requests rather than architectural refactoring.
Get running
Clone and build: git clone https://github.com/vaxilu/x-ui.git && cd x-ui && go build -o x-ui main.go. Or use the installation script: bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh). For Docker: docker run -itd --network=host -v $PWD/db/:/etc/x-ui/ enwaiax/x-ui:latest.
Daily commands:
go run main.go or go build -o x-ui && ./x-ui. Service mode on Linux: systemctl start x-ui (after install.sh). Panel access: http://localhost:54321 (or configured port). Logs: journalctl -u x-ui or stdout.
Map of the codebase
main.go— Application entry point that initializes the server, database, and xray service; every developer must understand the startup flowweb/controller/index.go— Main HTTP request router and handler dispatcher; essential for understanding request routing and authenticationdatabase/db.go— Database abstraction layer managing SQLite persistence; critical for all data operations and model lifecycleconfig/config.go— Configuration management and xray core initialization; load-bearing for runtime behavior and protocol supportweb/entity/entity.go— Core domain models (Inbound, Outbound, User) representing the data schema; required to understand API contractsweb/global/global.go— Global state management including xray service instance and configuration; affects all subsystemsgo.mod— Dependency manifest; xtls/xray-core and gin-gonic are critical dependencies shaping architecture
How to make changes
Add a new API endpoint
- Create handler function in the appropriate controller file (e.g., web/controller/inbound.go for inbound-related endpoints) (
web/controller/inbound.go) - Register the route in the router setup within web/controller/index.go using gin routing methods (e.g., engine.POST("/api/path", handler)) (
web/controller/index.go) - Use the base controller response utilities from web/controller/base.go for consistent JSON responses (RespSuccess, RespError) (
web/controller/base.go) - Add corresponding data model to web/entity/entity.go if introducing new domain objects (
web/entity/entity.go)
Add support for a new proxy protocol
- Define protocol configuration templates and rules in config/config.go's protocol handling functions (
config/config.go) - Extend the InboundConfig or OutboundDetour model in database/model/model.go to support protocol-specific fields (
database/model/model.go) - Update the xray service wrapper in v2ui/v2ui.go to construct xray-core API calls for the new protocol (
v2ui/v2ui.go) - Add UI form and validation in web/assets/js/model/xray.js and corresponding HTML templates (
web/assets/js/model/xray.js)
Add a new dashboard monitoring widget
- Create a new endpoint in web/controller/server.go to fetch the required system or traffic data (
web/controller/server.go) - Use util/sys/psutil.go utilities to retrieve CPU, memory, or network statistics (
util/sys/psutil.go) - Query database models via database/model/model.go for traffic statistics or user quotas (
database/model/model.go) - Create Vue component in web/assets/js/ folder and register it in the main HTML template to display the data (
web/html)
Modify the xray core configuration template
- Edit the protocol configuration builders and template generation in config/config.go (
config/config.go) - Update the corresponding database schema or model if new persistent fields are required in database/model/model.go (
database/model/model.go) - Sync the UI model definitions in web/assets/js/model/xray.js to reflect new configuration options (
web/assets/js/model/xray.js)
Why these technologies
- Gin Web Framework — Lightweight, high-performance HTTP router for Go; suitable for REST API and session management with middleware support
- xtls/xray-core — Core proxy engine supporting multiple protocols (VLESS, VMess, Trojan, Shadowsocks); enables traffic forwarding and protocol handling
- SQLite — Embedded relational database requiring no separate service; ideal for single-server deployments with traffic stats and configuration persistence
- Vue.js 2.6.12 — Progressive frontend framework for real-time dashboard UI; facilitates interactive inbound/user management without full page reloads
- gRPC with google.golang.org/grpc — Efficient binary protocol for communication with xray-core daemon; enables dynamic configuration updates without restart
- gopsutil — Cross-platform system statistics library; provides CPU, memory, and network monitoring for server health dashboard
Trade-offs already made
-
Embedded SQLite vs. external database
- Why: Reduces deployment complexity and operational overhead for single-server deployments
- Consequence: Limited horizontal scalability; not suitable for multi-server clustering; potential I/O contention under high traffic stat writes
-
Single xray-core instance per panel vs. multi-instance
- Why: Simplified configuration management and state consistency within the panel
- Consequence: Single point of failure; maximum throughput limited by one core instance; no built-in load balancing across multiple proxies
-
Go backend + vanilla Vue.js frontend vs. full-stack framework
- Why: Minimal dependencies; small binary size; no build step required for frontend assets
- Consequence: Limited IDE support and type safety on frontend; no client-side routing or bundling; larger JS file serving overhead
-
Session-based authentication via gin-contrib/sessions
- Why: Stateful, server-side session security; straightforward for single-server deployments
- Consequence: Sessions not portable across multiple backend instances; session storage tied to in-memory or filesystem backends
Non-goals (don't propose these)
- Multi-server deployment or distributed clustering
- Real-time gRPC bidirectional streaming for metrics (polling-based instead)
- OAuth/SAML/LDAP authentication integration (local credentials only)
- Data replication or failover
- Cross-platform ARM64 automatic selection (manual architecture choice at install)
- WebSocket support (HTTP long-polling fallback via AJAX)
Traps & gotchas
- Web UI is pre-compiled (web/assets/); rebuilding requires Node.js toolchain not included—source likely separate. 2. Xray binaries (bin/xray-linux-*) must be manually synced with upstream Xray releases for security patches; no auto-update mechanism visible. 3. Database is SQLite at /etc/x-ui/x-ui.db (systemd service default); backup before updates. 4. Port 54321 is hardcoded default (config/name); change requires config file edit or env var (not visible in code). 5. Cloudflare SSL cert auto-renewal requires valid API key stored in database; silent failure if key expires. 6. Telegram bot tokens stored plaintext in database—no encryption layer.
Architecture
Concepts to learn
- Xray protocol multiplexing — x-ui's core value is managing multiple inbound protocols (VLESS, VMESS, Trojan, Shadowsocks) simultaneously on one server without config file editing; understanding protocol negotiation/routing is essential to modify inbound templates
- gRPC unary and streaming calls — x-ui communicates with Xray daemon via gRPC to hot-reload configs and fetch stats; modifying traffic monitoring or config deployment logic requires gRPC client knowledge
- SQLite transaction isolation and connection pooling — x-ui uses GORM with SQLite for account/traffic persistence; high-concurrent user operations (adding accounts, updating quotas) can cause lock contention if transactions aren't scoped correctly
- Cron expression parsing (robfig/cron) — Telegram notifications and traffic quota resets use robfig/cron/v3 for scheduling; adding new periodic tasks or custom schedules requires understanding cron syntax and task registration
- Let's Encrypt DNS-01 ACME challenge — x-ui automates SSL cert provisioning via Cloudflare DNS API (DNS-01 challenge); understanding ACME flow is needed to support other DNS providers or diagnose cert renewal failures
- Token bucket rate limiting — x-ui implements traffic quota enforcement (limiting bytes/expiry per user); the quota check logic likely uses token bucket or similar algorithm to prevent burst exploitation
- systemd service lifecycle and socket activation — x-ui.service manages the daemon (start/stop/restart); understanding systemd socket options and ExecStart hooks is essential for deployment and debugging service startup failures
Related repos
xtls/xray-core— The core routing/protocol engine that x-ui manages via gRPC; x-ui is a control plane for Xray2dust/v2rayX— Native macOS V2Ray client; represents the client-side ecosystem that x-ui's managed inbounds serveChasing66/docker-x-ui— Official Docker image builder referenced in README; community-maintained containerization of x-uiallinone/goxray— Alternative Xray management panel; closest direct competitor in the same problem spacev2fly/v2ray-core— Predecessor to Xray; x-ui can migrate v2-ui panels which manage v2ray-core, showing backwards compatibility
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 unit tests for database model operations (database/model/model.go)
The repo has a database layer with GORM models but no visible test files. Adding unit tests for model CRUD operations, validations, and relationships would improve reliability of data persistence. This is critical since the panel manages user accounts, traffic limits, and expiration times.
- [ ] Create database/model/model_test.go with table-driven tests for Create, Read, Update, Delete operations
- [ ] Add tests for model validations (e.g., validating user protocol types against supported ones: vmess, vless, trojan, shadowsocks, etc.)
- [ ] Test traffic limit and expiration time calculations using database/model/model.go structs
- [ ] Set up a test SQLite database using gorm.io/driver/sqlite for isolated testing
Add GitHub Actions workflow for multi-architecture builds (extend .github/workflows/release.yml)
The repo supports multiple architectures (amd64, arm64 evident from bin/ directory), but the release.yml workflow is minimal. Adding a comprehensive build matrix for linux-amd64, linux-arm64, darwin-amd64, windows-amd64 would automate cross-platform releases and catch architecture-specific issues early.
- [ ] Expand .github/workflows/release.yml to include a build matrix with GOOS/GOARCH combinations (linux/amd64, linux/arm64, darwin/amd64, windows/amd64)
- [ ] Add steps to build xray binaries for each architecture using CGO_ENABLED=0 for portability
- [ ] Create release artifacts as .tar.gz for Unix and .zip for Windows, matching the install.sh expectations
- [ ] Add checksums (SHA256) generation for release artifacts for security verification
Add integration tests for util/common and util/json_util packages
Utility packages like err.go (error handling), format.go (formatting), and json.go (JSON parsing) are foundational but lack visible tests. Given the panel handles user input and configurations, robust utility testing is essential for stability.
- [ ] Create util/common/common_test.go with tests for stringUtil.go functions (case conversion, trimming, validation)
- [ ] Add util/common/err_test.go testing multi_error.go's error aggregation and formatting for Telegram bot notifications
- [ ] Create util/json_util/json_test.go testing JSON marshal/unmarshal with nested config structures from config/config.go
- [ ] Test edge cases like malformed JSON, missing fields, and type mismatches that could crash the web panel
Good first issues
- Add unit tests for database/model/model.go GORM struct validation and util/common/err.go error handling; currently no test files visible for these core data layers: medium: Improves reliability of account/inbound CRUD operations
- Document the Xray config template syntax in config/config.go and create examples for custom protocol configurations (currently v2-ui users have no guide for new templating): low: Unblocks migration of v2-ui users and reduces GitHub issues from configuration confusion
- Add environment variable overrides for hardcoded defaults (port 54321, database path, log level) to support containerized/12-factor deployments without recompile: small: Makes Docker and cloud deployments cleaner; currently relies on manual config file editing
Top contributors
- @vaxilu — 59 commits
- [@Misaka No](https://github.com/Misaka No) — 8 commits
- @FranzKafkaYu — 6 commits
- @kerry — 2 commits
- @GSWXXN — 2 commits
Recent commits
9c1be8c— Merge pull request #165 from KerryJi/feature/dev (vaxilu)e5d08bb— add alpn into tlsSetting, fix fallback bug (kerry)77d8444— fix fallback bug (kerry)d350728— Merge pull request #163 from FranzKafkaYu/develop (vaxilu)b616a5b— 1.optimize Tg bot notify info (FranzKafkaYu)1787160— Merge pull request #162 from FranzKafkaYu/develop (vaxilu)580dca2— Delete Tg Bot Control Part in Shell Scripts (FranzKafkaYu)c06ccba— Merge branch 'main' of https://github.com/vaxilu/x-ui into main (vaxilu)dfc6b56— 网页端设置电报机器人开关 (vaxilu)91c4cef— Update README.md (vaxilu)
Security observations
- Critical · Outdated Go Dependencies with Known Vulnerabilities —
go.mod. The project uses Go 1.16 with multiple outdated dependencies. Critical vulnerabilities exist in: gin-gonic/gin v1.7.1 (released 2021, multiple CVEs including gin-gonic/gin#2797), gorm.io/gorm v1.21.9 (SQL injection vulnerabilities), and google.golang.org/grpc v1.38.0 (authentication bypass CVEs). These versions are from 2021 and have numerous publicly disclosed vulnerabilities. Fix: Immediately upgrade all dependencies to latest stable versions: gin to v1.9+, gorm to v1.24+, grpc to v1.50+. Run 'go get -u ./...' and conduct thorough regression testing. Implement automated dependency scanning with tools like Dependabot or Snyk. - Critical · Insecure Direct Object Reference (IDOR) & Missing Authentication Validation —
web/assets/js/util, web/assets/js/model/, gin-gonic/gin middleware configuration. The web interface uses Vue.js and Axios without visible authentication/authorization middleware. The file structure shows database models (database/model/) and API endpoints but no apparent role-based access control (RBAC) implementation. Users could potentially manipulate IDs in requests to access other users' data or configurations. Fix: Implement proper authentication middleware on all API endpoints. Add request-level authorization checks that validate user permissions before accessing resources. Use UUID or opaque identifiers instead of sequential IDs. Implement proper session management with secure, httpOnly cookies. - Critical · Hardcoded Binary and Potential Unsafe Xray Core Execution —
bin/xray-linux-amd64, bin/xray-linux-arm64, config/config.go, main.go. The project includes pre-compiled xray binaries (bin/xray-linux-amd64, bin/xray-linux-arm64) without signature verification. The application executes external binaries with user-controlled configuration, creating a potential code execution vector. No input validation is visible for xray configuration templates. Fix: Verify binary signatures using GPG before execution. Implement strict input validation for all xray configuration parameters. Run xray in a sandboxed container or with restricted capabilities. Never execute user-supplied configuration directly. Implement a configuration schema validation system. - High · Missing HTTPS/TLS Enforcement and Default Credentials —
install.sh, main.go, Dockerfile. While the README mentions HTTPS support is optional (user must provide cert), the default installation likely runs over HTTP. No evidence of default password enforcement or secure credential initialization. Users may deploy with default/weak credentials. Fix: Enforce HTTPS by default with certificate auto-generation. Require password change on first login. Implement rate limiting on authentication endpoints. Use strong, randomly generated default credentials that must be changed immediately upon first access. - High · SQL Injection via ORM Misuse —
database/db.go, v2ui/db.go, database/model/model.go. While using GORM (ORM), the codebase may still be vulnerable to SQL injection if raw SQL queries are used without proper parameterization. The v2ui/db.go and database/db.go files likely interact with database, and vulnerable patterns could exist (e.g., string concatenation in queries). Fix: Audit all database queries for raw SQL usage. Always use parameterized queries and GORM's query builder methods. Never concatenate user input into SQL strings. Implement code review process to catch SQL injection patterns. Use static analysis tools like gosec. - High · Cross-Site Scripting (XSS) Vulnerabilities in Frontend —
web/assets/js/, web/assets/css/custom.css, web/assets/vue@2.6.12/. Vue.js application loads external JavaScript libraries (axios, moment, qrcode, etc) with potential XSS vectors. User-controlled data (proxy configs, traffic stats) is rendered without evidence of proper sanitization. The custom.css and Vue templates could have unsafe bindings. Fix: Use Vue's built-in v-text or :textContent instead of v-html for user data. Implement Content Security Policy (CSP) headers. Sanitize all user inputs using DOMPurify. Keep all JavaScript libraries updated. Implement proper output encoding based on context (HTML, JavaScript, CSS). - undefined · undefined —
undefined. undefined Fix: undefined
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.