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

FieldMeaning
hostDestination domain (empty for bare-IP connections)
dst_ip / dst_portDestination IP and port
src_ip / src_portSource address (distinguish LAN devices with allow-lan)
networktcp / udp
process_nameOriginating 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.
Tip: time and port conditions are most concise as shortcuts; write a full main function only when you need resolution calls or multi-condition logic.