Rules form a static lookup table; script mode lets a piece of JavaScript decide the outbound for every connection dynamically - by time of day, port, resolved IP, any combination. A Premium-core feature, available out of the box in CFW.
Enabling
Add a top-level script section and set mode to script (a Script option appears in the client's mode switcher):
mode: script
script:
code: |
function main(ctx, metadata) {
// return an outbound name: group / "DIRECT" / "REJECT"
if (metadata.host && metadata.host.endsWith("company.com")) {
return "DIRECT";
}
// late-night game traffic direct, otherwise proxied
const hour = new Date().getHours();
if (metadata.dst_port === 3074 && hour >= 1 && hour <= 7) {
return "DIRECT";
}
// hand everything else to the rule engine
return ctx.resolveOutbound(metadata) ?? "Select";
}
Useful metadata fields
| Field | Meaning |
|---|---|
host | Destination domain (empty for bare-IP connections) |
dst_ip / dst_port | Destination IP and port |
src_ip / src_port | Source address (distinguish LAN devices with allow-lan) |
network | tcp / udp |
process_name | Originating process (under TUN) |
The context also provides helpers like ctx.geoip(ip) and ctx.resolveIP(host), enabling resolve-then-route logic that plain rules cannot express.
Script shortcuts: the lightweight option
Rather than taking over the whole mode, define shortcut expressions and reference them from ordinary rules - the best of both worlds:
script:
shortcuts:
late-night-game: dst_port == 3074 and now.hour < 7
rules:
- SCRIPT,late-night-game,DIRECT
- MATCH,Select
Caveats
- The script runs on every connection; heavy logic amplifies latency. Prefer rules for anything rules can express.
- A throwing script fails the connection; watch the Logs page after changes.
- Never run scripts from untrusted configs - the more powerful the feature, the bigger the risk in a malicious profile.