Skip to content

Architecture Overview ​

⏱️ 10 min · Level: Intermediate

Harmony is a single-file Cloudflare Workers application that operates as a VLESS subscription generator β€” it does not proxy traffic itself, but rather produces ready-to-import configuration payloads that V2Ray/Xray-compatible clients consume. When a client hits the worker URL, Harmony executes a complete pipeline: fetch clean IPs β†’ generate VLESS links per configuration group β†’ encode as Base64 β†’ serve with subscription metadata headers. This page dissects that pipeline, the data model, and the execution model that binds them together.

Repository Structure ​

The project is intentionally minimal β€” one runtime file, one static data file, and a VitePress documentation site:

yaml
Harmony/
β”œβ”€β”€ worker.js       ← Complete runtime (1180 lines)
β”œβ”€β”€ cf-clean.json   ← Statically cached clean IP dataset (18k+ lines)
β”œβ”€β”€ package.json    ← VitePress dev dependencies only
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md       ← Persian-language setup guide
└── docs/           ← VitePress documentation site
    β”œβ”€β”€ index.md    ← Landing page
    β”œβ”€β”€ 1/
    β”‚   └── overview.md
    └── public/
        └── logo.svg

There is no build step for the worker itself β€” worker.js is deployed verbatim to Cloudflare. The package.json scripts (dev, build, preview) relate exclusively to the documentation site powered by VitePress.

High-Level Request Lifecycle ​

Every invocation of the worker follows the same deterministic path. The Mermaid diagram below illustrates the complete request-to-response flow, with the three parallel IP fetch operations highlighted as the key concurrency point:

The worker entry point is the standard Cloudflare Workers addEventListener("fetch", ...) pattern at line 1009. The handleRequest function receives the incoming Request, extracts an optional ?name= query parameter for profile titling, then orchestrates the full pipeline.

Three-Layer Code Architecture ​

The 1180-line worker.js is organized into three distinct layers, each with a clear responsibility boundary:

LayerLinesResponsibilityMutability
User Configuration30–95USER_SETTINGS object: UUID, ipCount, early data, and group definitionsUser edits before deploy
Static Data102–971staticIPs array: ~870 IPv6-mapped addresses + 25 CDN domains + 4 raw IPv4sUser may extend
Runtime Logic973–1180IP fetching, VLESS link builder, subscription encoder, utility functionsNever edited by user

NOTE

The User Configuration layer is the only section a deployer needs to touch β€” lines 32 (UUID), 55–56 (TLS host/SNI), 69 (TCP host), and 83–84 (emergency host/SNI). Everything below line 95 is infrastructure that operates autonomously.

Data Model: Configuration Groups ​

The central data structure is USER_SETTINGS.groups, an array of group objects. Each group defines a distinct VLESS configuration template that gets multiplied by ipCount (default: 10) during generation. The three default groups serve different network strategies:

Each group object contains the following fields, which map directly to VLESS URI parameters:

FieldPurposeExampleVLESS URI Param
nameRemark/label shown in client"Harmonyα΅€α΄ΈΛ’"#remark (fragment)
hostWebSocket Host header"index.harmonica01.workers.dev"host=
sniTLS Server Name IndicationSame as host (or empty for non-TLS)sni=
pathWebSocket path (supports random:N)"/random:18"path=
tlsEnables TLS security layertrue / falsesecurity=tls (if true)
allowInsecureSkip TLS verificationfalseallowInsecure=1 (if true)
portsCandidate ports for connection["443","8443","2053",...]Port in @ip:port
alpnApplication-Layer Protocol Negotiation"http/1.1"alpn=
fpClient fingerprint list["chrome"]fp=
dataSourceWhich IP source to use"dynamic1"β€” (determines @ip)
randomizeSniRandomize SNI character casingtrueAffects sni= value

The output cardinality is: groups.length Γ— ipCount configurations. With defaults (3 groups Γ— 10 IPs), every subscription refresh yields 30 distinct VLESS links.

IP Data Pipeline ​

The IP acquisition pipeline is the most architecturally significant subsystem. It operates in three stages β€” fetch, extract, and prepare β€” with a static fallback that guarantees output even when external sources are unreachable.

Stage 1: Parallel Fetch ​

Both dynamic sources are fetched concurrently via Promise.all with a 3-second timeout per request:

Source KeyURLResponse ShapeFallback on Failure
dynamic1raw.githubusercontent.com/NiREvil/vless/.../Cloudflare-IPs.json{ ipv4: [{ ip: "..." }] }{ ipv4: [] }
dynamic2strawberry.victoriacross.ir{ data: [{ ipv4: "..." }] }{ data: [] }

The fetchWithTimeout wrapper at line 1013 uses AbortController to enforce the timeout, ensuring a hung external API never blocks the worker beyond its CPU time limit.

Stage 2: Extract & Normalize ​

Each source has a different response schema. The extraction logic at lines 1042–1043 normalizes them into flat string arrays:

  • dynamic1: response.ipv4[].ip β€” array of objects, extract .ip field
  • dynamic2: response.data[].ipv4 β€” array of objects, extract .ipv4 field

Stage 3: Deduplicate & Shuffle ​

All three sources (including static) are passed through a two-step preparation:

  1. new Set(...) β€” removes duplicate IPs within each source
  2. shuffleArray() β€” Fisher-Yates shuffle for random distribution across configs

NOTE

The static IP list at lines 102–971 contains IPv6-mapped IPv4 addresses in the format [::ffff:XXXX:XXXX], 25 CDN-backed domains (like time.is, fbi.gov, cdnjs.com), and a few raw IPv4 addresses. These serve as the zero-dependency fallback β€” if both dynamic fetches fail, Group 3 still produces output from static data.

The createVlessLink(ip, group, settings) function at line 1097 is the core output generator. It transforms a single IP + group template into a complete vless:// URI:

text
vless://{uuid}@{ip}:{randomPort}?path={path}&encryption=none&type=ws&host={host}&fp={fp}&ed={ed}&eh={eh}[&security=tls&sni={sni}&alpn={alpn}]#{name}

Three randomization mechanisms operate during link construction:

MechanismImplementationAnti-Detection Purpose
Port selectionRandom pick from group.ports arrayDistributes across Cloudflare edge ports
Path obfuscationrandom:18 β†’ 18-char random alphanumeric stringPrevents path-based fingerprinting
SNI case randomization50% chance to uppercase each characterDefeats case-sensitive SNI filters

The TLS conditional block at lines 1125–1138 adds security=tls, sni, and alpn parameters only when group.tls is true. For non-TLS groups, these parameters are omitted entirely rather than set to empty values β€” this is a protocol requirement, not a design choice.

Subscription Output Format ​

The final response is a Base64-encoded newline-joined list of VLESS URIs, served with HTTP headers that client applications interpret as subscription metadata:

HeaderValueClient Behavior
Content-Typetext/plain; charset=utf-8Standard text response
Profile-Update-Interval6Client refreshes every 6 hours
Subscription-UserinfoDynamic fake statsShows simulated usage in client UI
Profile-TitleFrom ?name= param or "Harmony"Names the subscription profile

The fake subscription info generated by generateCakeSubscriptionInfo() at line 991 serves a practical purpose: many V2Ray clients display traffic statistics from the Subscription-Userinfo header, and missing or zero values can cause UI glitches. The function produces realistic-looking numbers that vary throughout the day based on the current hour, simulating gradual traffic consumption.

Utility Layer ​

Three utility functions support the main pipeline:

  • generateRandomPath(length) β€” Generates a lowercase-alphanumeric string of the given length using abcdefghijklmnopqrstuvwxyz0123456789. Called when a group path contains the random:N directive.

  • randomizeCase(str) β€” Iterates each character with a 50% probability of uppercasing. Applied to SNI values when group.randomizeSni is true.

  • shuffleArray(array) β€” Implements the Fisher-Yates shuffle (O(n) in-place) to randomize IP order before configuration generation, ensuring consecutive subscription refreshes produce different IP-to-port mappings.

Execution Model & Constraints ​

Harmony runs on the Cloudflare Workers runtime, which imposes specific constraints that shaped the architecture:

ConstraintImpact on Design
No persistent storageAll IP data must be fetched per-request or hardcoded
CPU time limit (10ms free / 30ms paid)3s fetch timeout + Fisher-Yates shuffle is fast enough
Single request scopeNo caching between requests; each refresh is a fresh pipeline run
Subrequest limit (50 free / 1000 paid)Only 2 external fetches per invocation β€” well within limits
No setTimeout/setIntervalTimeout implemented via AbortController on fetch()

The stateless, per-request execution model means there is no warm cache β€” every client refresh triggers a full IP fetch + config generation cycle. This is by design: it ensures the IP list is always fresh, which is critical for avoiding blocked Cloudflare IPs in restrictive network environments.

Architectural Summary ​

AspectDesign Decision
Deployment targetSingle Cloudflare Worker, no build step
Configuration modelJavaScript object literal, edited in-source
IP sourcing3-tier: 2 dynamic APIs + 1 static fallback
ConcurrencyPromise.all for parallel IP fetches
Output formatBase64-encoded VLESS URI list
RandomizationPort, path, and SNI β€” all per-request
Error strategyGraceful degradation: empty arrays on fetch failure, static IPs as last resort

Next Steps ​

Now that you understand the end-to-end architecture, dive into the configuration layer that you'll interact with when deploying:

β†’ β€” Understand each group field and how to customize them

β†’ β€” Replace the default identity parameters

β†’ β€” Deep dive into how each IP source works and when to prefer one over another