Language Tour
A practical walkthrough of `.quire` syntax, model binding, blocks, expressions, and composition.
Quire is line-oriented and intentionally small. Newlines separate statements; semicolons are not part of the language.
View shape
Each file starts with a quire document and one model:
quire ProductPage {
model {
product: Product
cart: Cart
}
route "/products/{product.slug}"
title product.title
section hero {
text heading {
value product.title
}
}
}
route and title are view attributes. Built-in view attributes are validated by the active schema.
Blocks and attributes
Block syntax is:
<blockType> <id> { ...attributes or children... }
Built-in block types include:
section,stack,grid,cardtext,richtext,image,button,price,regionbadge,divider(reserved for existing block IDs)
Attributes attach to blocks via name valueExpression lines:
button addToCart {
label "Add to cart"
action commerce.cart.add(product.defaultVariant.id)
}
Typed model fields and bindings
The model block declares symbols for a view. let creates typed compile-time bindings:
let pageTitle: String = product.title
title pageTitle
Bindings are substituted in emitted IR; they are not runtime functions.
Expressions and operators
Supported source-level expression forms include:
- Literals: string, number, boolean,
null - Field paths:
product.title,cart.lineCount - Logical and comparison operators:
and,or,!,==,!=,<,<=,>,>= - Numeric operators:
+,-,*,/,% - Safe ternary:
condition ? then : else - Filter pipe syntax, e.g.
product.price | money - Declarative helper calls (
i18n,plural,locale,token, etc.) - Capability calls with schema-registered action names, e.g.
commerce.cart.add(...)
Conditionals and repeats
if product.available {
button addToCart {
label "Add to cart"
action commerce.cart.add(product.defaultVariant.id)
}
} else {
text unavailable {
value "Unavailable"
}
}
repeat collection.products as product filter product.available sort product.title limit 8 {
card productCard {
text productTitle {
value product.title
}
}
}
List operations are declarative descriptors (filter, sort, limit, group, paginate), not callbacks.
Components and imports
component ProductCard(item: Product, showPrice: Boolean) {
card productCard {
text productTitle {
value item.title
}
}
}
use ProductCard featured {
item product
showPrice true
}
import resolves local .quire files, component package manifests, or installed package names:
import { ProductCard, PriceBadge as Badge } from "./cards.quire"
include and partial are aliases for component definition/use when authoring template-style composition.
Slots
Slots are compile-time named placeholders:
partial HeroBanner(item: Product) {
slot media {
image fallback {
src item.featuredImage.url
alt item.featuredImage.alt
}
}
}
include HeroBanner hero {
item product
slot media {
image productImage {
src product.altImage.url
alt product.altImage.alt
}
}
}
If no slot is supplied, the slot body in the partial/default emits as-is.
Localization and advanced authoring helpers
title i18n("product.title", "Product", locale("en-US"))
text cartCount {
value plural("cart.items", cart.count, "1 item", "{count} items", locale("ar-EG", "rtl"))
}
Other built-in helpers include:
computed(key, value)bind(source, fallback?)when(condition, consequent, alternate)responsive(base, sm?, md?, lg?, xl?)seo(title, description, canonical?, image?)a11y(label, role?, describedBy?)
Language limits
Quire is not a general-purpose runtime language:
- no arbitrary loops beyond
repeat/for - no mutation primitives
- no module/network/OS execution in source
- no inline script execution via source