docs / Language

Statement Mode

Markup and control flow directly as statements: bare JSX, if/for/while/switch/try, guard-clause returns, and for-key/index clauses.

Statement mode is a first-class component body style: markup and control flow appear directly as statements, no `return` wrapper required. Every feature that works in expression mode also works in statement mode, and vice versa.

app/components/List.vsk
										
											component List(props: { items: string[] }) {
  let &[filter] = track("");

  if (filter !== "") {
    <p>Filtered by: {filter}</p>
  }

  for (const item of props.items; key item) {
    <div>{item}</div>
  } empty {
    <p>No items.</p>
  }
}
										
									

Statements the compiler understands

Statement IR handling
Bare JSX element / fragment rendered, tracked
{expr} expression container rendered; .map() calls become a MapRegion
if / else conditional region
for...of, for...in, classic for loop region
while / do...while loop region
switch switch region
try / catch try region (fallback content on error)
return <jsx> guard-clause early return — renders and stops
{#server} / {#client} blocks client-boundary regions
let &[x] = track(0) TrackDecl
Anything else preserved verbatim as a runtime statement

`class Foo {}` inside a component body raises a compiler error — components are markup/state units, not class containers.

for key / index clauses

app/components/Table.vsk
									
										component Table(props: { rows: Row[] }) {
  for (const row of props.rows; key row.id; index i) {
    <Row data={row} index={i} />
  } empty {
    <p>No rows.</p>
  }
}
									
								
  • `; key <expr>` sets the reconciliation key expression.
  • `; index <ident>` binds the loop index to an identifier.
  • Clauses are optional and combinable; only for...of/for...in headers may carry them (classic `for` keeps its normal semicolons).
  • The compiler blanks the clause text before parsing and recovers it from annotations, preserving source offsets.

Guard-clause early returns

app/components/List.vsk
										
											component List(props: { items: string[] }) {
  let &[filter] = track("");

  if (filter !== "") {
    <p>Filtered by: {filter}</p>
  }

  for (const item of props.items; key item) {
    <div>{item}</div>
  } empty {
    <p>No items.</p>
  }
}