Deterministic by design
The same source always compiles to byte-identical output — no clocks, no randomness, no I/O. Every loop, conditional and function is evaluated as the drawing is built.
A small declarative language that compiles to professional SVG floor plans. Zero-dependency, deterministic, isomorphic.
# A compact studio apartment — the canonical ArchLang example.
#
# Architecturally sound (passes `arch lint`): every room opens off a central hall,
# so the bath is never reached through the bedroom; the bath is fully enclosed and
# fitted with real fixtures; and no door leaf sweeps onto furniture. Self-contained
# (no imports) so it compiles from a single file.
plan "Studio 1BR" {
units mm
grid 50
scale 1:50
north up
# Exterior shell + partitions. The x=4000 divider runs the FULL height so the bath
# is walled off from the living space; the right column splits into bedroom / hall / bath.
wall exterior thickness 200 { (0,0) (7000,0) (7000,6000) (0,6000) close }
wall partition thickness 100 { (4000,0) (4000,6000) }
wall partition thickness 100 { (4000,3000) (7000,3000) }
wall partition thickness 100 { (4000,4400) (7000,4400) }
room id=r_living at (0,0) size 4000x6000 label "Living / Kitchen" uses living kitchen
room id=r_bed at (4000,0) size 3000x3000 label "Bedroom" uses bedroom
room id=r_hall at (4000,3000) size 3000x1400 label "Hall" uses hall
room id=r_bath at (4000,4400) size 3000x1600 label "Bath" uses bath
# Entrance into the living space; the hall links it to the bedroom and the bath.
# Living ↔ hall is a cased opening (circulation needs no door leaf); the bedroom
# and bath each get a real door off the hall.
door id=d_main at (3000,6000) width 1000 wall exterior hinge left swing in
opening id=o_living at (4000,3700) width 900 wall partition
door id=d_bed at (6400,3000) width 800 wall partition hinge right swing out
door id=d_bath at (4600,4400) width 800 wall partition hinge left swing out
window at (0,2000) width 1500 wall exterior
window at (7000,1500) width 1200 wall exterior
window at (7000,5200) width 700 wall exterior
# Kitchen run along the north wall: sink · counter · stove · fridge (drawn as symbols).
furniture kitchen_sink at (300,250) size 800x600
furniture counter at (1200,250) size 600x600
furniture stove at (1950,250) size 600x600
furniture fridge at (2700,250) size 600x650
# Living + bedroom furniture, kept clear of the door swings.
furniture sofa at (350,4300) size 2000x900 label "Sofa"
furniture bed at (4300,300) size 1500x2000 label "Bed"
# Bathroom fixtures, kept clear of the door's entry path (the door swings out into
# the hall): shower in the far corner, basin against the partition, WC on the south
# wall — the left third of the room stays open so you can actually step inside.
furniture shower at (6000,5000) size 900x900 # against the E + S walls (corner)
furniture basin at (5200,4450) size 600x450 # back to the hall partition
furniture wc at (5200,5200) size 400x700 # back to the south wall
# Dimension strings: room widths above, overall extents around. The reference
# (witness) points sit on the building's OUTER faces (x=-100/7100, y=-100/6100 for
# the 200mm shell) so the extension lines start at the wall face and read outward,
# never poking back into the building — while the spans still measure centerline to
# centerline (4000 · 3000 · 7000 · 6000).
dim (4000,-100)->(0,-100) offset 250 text "4000"
dim (7000,-100)->(4000,-100) offset 250 text "3000"
dim (0,6100)->(7000,6100) offset 500 text "7000"
dim (7100,6000)->(7100,0) offset 500 text "6000"
title {
project "Studio Apartment"
drawn_by "ArchCanvas"
date "2026-06-27"
}
}
The same source always compiles to byte-identical output — no clocks, no randomness, no I/O. Every loop, conditional and function is evaluated as the drawing is built.
The default SVG path pulls no runtime dependencies. Optional power — PNG raster, vector PDF, angled-wall geometry — loads lazily and is never required.
Layers, line weights, wall poché, openings that void walls, real fixture symbols, dimensions, a north arrow, scale bar and a title block. Export to SVG, DXF, PDF or PNG.
Values, arithmetic, arrays, for / if / while and pure functions — plus relational placement (right-of / below / …) resolved by deterministic topological arithmetic.
describe() returns rooms, areas, adjacency, an access graph and circulation facts; lint() flags habitability problems — image-free, so an agent can verify intent without an image.
describe() & lint
A plan compiles to a drawing — and to facts. describe() returns rooms, areas, adjacency, a modelled access graph and circulation figures; lint() flags habitability and circulation problems. Both are image-free, so an agent can confirm what it drew without rendering a pixel.
| Room | Use | Area | Adj. |
|---|---|---|---|
| Living / Kitchen | living, kitchen | 14.4 m² | 1 |
| Bedroom | bedroom | 9.6 m² | 1 |
| Total | 2 rooms | 24 m² | 4 |
2 doors · 2 windows · entrance verified · every room reachable
// built for agents
ArchLang answers on an agent's own terms. Every arch command takes --json with deterministic exit codes; arch context prints the whole language, workflow and error catalog as one system-prompt-ready bundle (llms-full.txt); and SKILL.md is the write → compile → describe → repair loop it follows. No pixels required to verify intent.