Skip to content

Network

Package: @alchemy-unifi/network@0.1.2-nightly.20261027100339.gc70dd7b.0 · Source: Network.ts

A network (VLAN). management picks the kind:

management Routed by Has
"GATEWAY" The gateway DHCP, a zone, internet access and isolation
"SWITCH" A layer-3 switch (device) DHCP on the switch
"UNMANAGED" Another router (carried, not routed) Just the VLAN

Existing networks are adopted by VLAN ID with --adopt, and renamed to match your props.

A guest network with DHCP

import * as UnifiNetwork from "@alchemy-unifi/network";
import * as Alchemy from "alchemy";
import * as Effect from "effect/Effect";
export default Alchemy.Stack(
"HomeNetwork",
{ providers: UnifiNetwork.providers(), state: UnifiNetwork.state() },
Effect.gen(function* () {
yield* UnifiNetwork.Network("guests", {
management: "GATEWAY",
name: "Guests",
vlanId: 40,
enabled: true,
cellularBackupEnabled: false,
internetAccessEnabled: true,
isolationEnabled: true,
zone: UnifiNetwork.FirewallZone.HOTSPOT,
ipv4Configuration: {
autoScaleEnabled: false,
hostIpAddress: "192.168.40.1",
prefixLength: 24,
dhcpConfiguration: {
mode: "SERVER",
ipAddressRange: { start: "192.168.40.100", stop: "192.168.40.250" },
leaseTimeSeconds: 86400,
pingConflictDetectionEnabled: true,
},
},
});
}),
);

An unmanaged VLAN

import * as UnifiNetwork from "@alchemy-unifi/network";
import * as Effect from "effect/Effect";
export const ispHandoff = UnifiNetwork.Network("isp-handoff", {
management: "UNMANAGED",
name: "ISP handoff",
vlanId: 99,
enabled: true,
}).pipe(Effect.asVoid);

isolationEnabled and internetAccessEnabled create system firewall policies. Isolation adds “Isolated Networks” BLOCK policies from the network to every internal zone, its own included. Turning internet access off adds a “Block … Internet Access” policy to External. Your policies that should win over them must come first: list them in beforeSystemDefined of the pair’s FirewallPolicyOrdering.

mdnsForwardingEnabled is the gateway’s mDNS proxy, which repeats discovery between networks. Unset, it’s true, as the console defaults it.

Every site has a default network on VLAN 1. To manage it, declare a Network with vlanId: 1 and its current settings, check that plan --adopt shows no update for it, then deploy once with --adopt. Props may rename it, but it’s never deleted: destroying the stack leaves it in place, and a change that would replace it (management, site) fails the plan.

Adopting the default network, with a new console’s settings

import * as UnifiNetwork from "@alchemy-unifi/network";
import * as RemovalPolicy from "alchemy/RemovalPolicy";
import * as Effect from "effect/Effect";
// Copy your console's current values: a prop left out changes the live network.
export const defaultNetwork = UnifiNetwork.Network("default", {
management: "GATEWAY",
name: "Default",
vlanId: 1,
enabled: true,
cellularBackupEnabled: true,
internetAccessEnabled: true,
isolationEnabled: false,
zone: UnifiNetwork.FirewallZone.INTERNAL,
ipv4Configuration: {
autoScaleEnabled: true,
hostIpAddress: "192.168.1.1",
prefixLength: 24,
dhcpConfiguration: {
mode: "SERVER",
ipAddressRange: { start: "192.168.1.6", stop: "192.168.1.254" },
leaseTimeSeconds: 86400,
domainName: "localdomain",
pingConflictDetectionEnabled: true,
},
},
}).pipe(RemovalPolicy.retain(), Effect.asVoid);

Network.lookup({ name }) or Network.lookup({ vlanId }) finds a network the stack uses but doesn’t manage.

The default network as a reference

import * as UnifiNetwork from "@alchemy-unifi/network";
import * as Effect from "effect/Effect";
export const lan = Effect.gen(function* () {
const network = yield* UnifiNetwork.Network.lookup({ vlanId: 1 });
return network.networkId;
});

Props are authoritative: every update sends the whole network, with explicit defaults for unset fields (mdnsForwardingEnabled: true, and a DHCP server’s domainName: ""), so changes made in the UI are put back. The config attribute mirrors the console’s object, so alchemy drift sees them.