Syntax basics
This page describes the basic syntax used throughout sprig.
It is not a complete language reference. It is a guide to reading and writing prose comfortably.
Blocks
Sprig is built around blocks.
A block names something and optionally contains more information:
concept Greenhouse { } Blocks always have:
- a type (
concept) - a name (
Greenhouse) - optional contents inside
{ }
Block contents
A block may contain:
- descriptive text
- nested blocks
- fields
- or nothing at all
For example:
concept Greenhouse {
describe {
A small greenhouse that exists across seasons.
}
} Whitespace and formatting are not significant. Sprig cares about meaning, not layout.
Identifiers
Identifiers name things.
They are written as plain words, without quotes:
concept TomatoPlant { } Identifiers:
- are case-sensitive
- must be unique within their scope
- are resolved based on relationships, not file location
You’ll learn more about resolution and scoping later.
Strings and prose
Sprig supports two kinds of text, used for different purposes.
Prose blocks
Blocks like describe, note, and title contain free prose.
describe {
A small basil plant with bright green leaves.
} Prose:
- is not parsed
- is not interpreted
- may contain any text
- exists only to be read by humans
Sprig does not inspect or validate the contents of prose blocks.
Strings
Strings are used in places where sprig expects structured values.
status { 'experimental' } Strings:
- are parsed
- are interpreted based on context
- must appear only where a string value is expected
Strings are not interchangeable with prose blocks.
Choosing between them
Use prose blocks when you are describing something.
Use strings when you are providing a value.
If sprig expects structure, use strings. If sprig expects meaning, use prose.
Fields
Fields attach simple information to a block.
They consist of a name and a value:
version { '0.1' } Fields are not behavior. They are annotations.
Commas
Commas are optional.
Commas in prose are treated as visual separators only. You may include them for readability, or omit them entirely.
relationships {
'become'
'are produced by'
} …is equivalent to…
relationships {
'become',
'are produced by',
} Nesting
Blocks may be nested inside other blocks:
series Gardening {
book Plants { }
} Nesting expresses containment, not ownership. It is a convenience for organization.
The same relationship can be expressed without nesting using in, which is covered later.
Notes and titles
Sprig provides a small set of blocks that exist purely for humans.
They do not affect meaning, structure, or resolution.
Notes
The note block is used for comments.
concept TomatoPlant {
note {
This concept might be split later.
}
} Notes:
- are ignored by the compiler
- do not appear in projections unless explicitly included
- exist only to help authors think
Titles
The title block provides a human-friendly title when a name does not read well.
concept CountBasedEffects {
title { 'Count-Based Effects' }
} Titles:
- do not change identity
- do not affect naming or resolution
- exist to improve presentation in projections
Files
A sprig repository may contain many .prose files.
Files do not define scope. They exist only to help humans organize prose.
Sprig reads all prose files together as a single universe.
What syntax is not
Sprig syntax is intentionally limited.
It does not try to be:
- a general-purpose programming language
- an execution model
- a control-flow system
- a data serialization format
There are no expressions, conditions, or imperative steps.
Sprig can be used to describe configuration, structure, or systems that later drive behavior—but the syntax itself remains descriptive.
Sprig is about describing what exists, not specifying how it runs.
What comes next
Now that you can read sprig prose, the next step is understanding where meaning lives.
Every sprig repository begins by declaring a universe.
The universe establishes the semantic boundary within which all names are resolved.
That foundation is described in the universe overview.