Sub House is a Cloudflare-based subscription management panel for nodes, collections, templates, rules, and end-user subscription delivery.
It provides:
- Admin UI at
/ - End-user subscription UI at
/user - Collection-based subscription outputs for:
baseclashsingbox
- Manage proxy nodes and organize them into collections
- Create collection credentials with optional expiry
- Generate
base,clash, andsingboxsubscription outputs - Maintain internal templates for Clash / Sing-box generation
- Maintain remote rule definitions and import built-in DustinWin presets
- QR preview and one-click copy for subscription links
- Session-based admin login and user login
This project no longer uses built-in default admin credentials.
On first visit, if app_settings in NODE_STORE does not contain:
adminUsernameadminPassword
the admin UI enters setup mode and requires you to create the first admin account before normal login becomes available.
Admin:
/
User:
/user
Subscription outputs:
/api/share/:collectionId/base
/api/share/:collectionId/clash
/api/share/:collectionId/singbox
Templates are stored internally in TEMPLATE_CONFIG.
- The active template is stored in app settings as
activeTemplateUrl - Only the currently selected internal template is used automatically
- If no active template is set,
singboxandclashexports run without atemplateparameter - There is no default remote template fallback anymore
The current active template is appended automatically for clash and singbox when it exists.
Manual formats are:
Internal subscription route with an internal template:
/api/share/:collectionId/singbox?internal=1&template=https%3A%2F%2Finner.template.secret%2Fid-<templateId>
/api/share/:collectionId/clash?internal=1&template=https%3A%2F%2Finner.template.secret%2Fid-<templateId>
Internal subscription route with an external template URL:
/api/share/:collectionId/singbox?internal=1&template=https%3A%2F%2Fexample.com%2Fcustom-template.txt
/api/share/:collectionId/clash?internal=1&template=https%3A%2F%2Fexample.com%2Fcustom-template.txt
If you are using an external converter through SUB_WORKER_URL, the same idea becomes:
https://your-converter.example.com/singbox?url=<encoded-share-url>&template=<encoded-template-url>
https://your-converter.example.com/clash?url=<encoded-share-url>&template=<encoded-template-url>
Notes:
basedoes not use thetemplateparameter- To use another internal template that is not the current one, copy its internal template address from the template manager and place it in the
template=parameter manually - The internal template URL format is:
https://inner.template.secret/id-<templateId>
The parser can ingest both single-node links and remote subscription/configuration content.
Each line can be a single node link such as:
vmess://...vless://...trojan://...ss://...ssr://...hysteria://...hysteria2://...hy2://...tuic://...anytls://...socks5://...socks://...http://...https://...
Examples:
vmess://eyJhZGQiOiJleGFtcGxlLmNvbSIsInBvcnQiOiI0NDMiLCJpZCI6InV1aWQiLCJwcyI6Ik5vZGUifQ==
vless://uuid@example.com:443?security=tls&type=ws#My-VLESS
trojan://password@example.com:443?security=tls#My-Trojan
ss://YWVzLTI1Ni1nY206cGFzc3dvcmQ=@example.com:8388#My-SS
The parser also supports plain-text subscriptions where each line is:
- a node link, or
- another remote subscription URL
This allows nested subscriptions within the recursion limit.
If a remote subscription body is plain Base64 text and the decoded result contains node schemes such as vmess:// or trojan://, it is treated as a standard base subscription and decoded automatically.
In practice, this usually means:
- the subscription response body itself is Base64
- the decoded content becomes multiple node links separated by line breaks
Clash-style YAML is supported when the content contains a top-level proxies: section. The parser reads proxy entries from that section and normalizes them into internal nodes.
sing-box style JSON is supported when the content contains an outbounds array. The parser reads supported outbound entries from outbounds and converts them into internal nodes.
The project also supports its own internal collection link format:
http://inner.nodes.secret/id-<collectionId>
This is resolved from KV and expanded into the nodes inside that collection.
Implemented in subscription/base.js:
vmessvlesstrojanssssrhysteriahysteria2tuicanytlssocks5http
Implemented in subscription/clash.js:
vmessvlesstrojansshysteriahysteria2tuicsocks5httpanytls
Sing-box export supports the common node types currently handled safely by project logic.
Known skips:
xhttpssrssnodes that require pluginsmieru- other unsupported or unimplemented node types
The project uses Cloudflare KV.
Namespaces:
NODE_STORETEMPLATE_CONFIGRULE_CONFIG
Main keys inside NODE_STORE:
nodescollectionsapp_settingsuser_tokensuser_sessionssession:<token>admin_session:<token>
sub_house/
- _worker.js
- config.js
- management.js
- services.js
- user.js
- middleware.js
- utils.js
- subscription/
- parser.js
- parser_v2.js
- base.js
- clash.js
- singbox.js
- wrangler.example.jsonc
- Node.js
- Wrangler
- Cloudflare account
- 3 KV namespaces:
NODE_STORETEMPLATE_CONFIGRULE_CONFIG
npm install -g wrangler
wrangler loginThis is the recommended deployment mode for this repository.
- Copy
wrangler.example.jsonctowrangler.jsonc - Fill in your Worker name and KV namespace IDs
- Keep your real
wrangler.jsonclocal only - Start local development:
wrangler dev- Deploy:
wrangler deployMinimal example:
No initial default admin credentials or default template variables are required.
This project can also run on Cloudflare Pages in advanced mode because it already uses _worker.js.
Recommended Pages setup:
- Create a Pages project
- Use advanced mode with
_worker.js - Set the build output directory to the repository root
.so_worker.jsand its imported modules are included - Bind the same KV namespaces in Pages:
NODE_STORETEMPLATE_CONFIGRULE_CONFIG
Git integration:
- Connect the GitHub repository
- Use the repository root as the output directory
- This project does not require a frontend build step
Direct Upload / Wrangler:
npx wrangler pages project create
npx wrangler pages deploy .Notes for Pages:
- Cloudflare Pages advanced mode supports
_worker.jsofficially - If you later add static assets, your
_worker.jsmust explicitly forward asset requests withenv.ASSETS.fetch(request) - For the current project structure, Worker deployment is still the simpler and recommended path
- Open
/ - If this is the first run, create the initial admin account
- Add nodes and create collections
- Manage templates and set the active template when needed
- Maintain rules
- Update admin settings and optional "other link"
- Open
/user - Log in with collection credentials
- Copy or scan the
base,singbox, orclashsubscription
- Admin login is session-based
- User access is collection-based
- Rule presets are imported from DustinWin remote sources
- Subscription naming tries to set headers such as
Profile-TitleandContent-Disposition
{ "name": "your-worker-name", "main": "_worker.js", "compatibility_date": "2026-04-07", "kv_namespaces": [ { "binding": "NODE_STORE", "id": "..." }, { "binding": "TEMPLATE_CONFIG", "id": "..." }, { "binding": "RULE_CONFIG", "id": "..." } ] }