Constraints and Scoped Names
bino supports constraints that let you conditionally include documents and inline layout children based on the target ReportArtefact’s labels, spec, or the current execution mode.
This enables scenarios like mode-specific pages (preview-only debug views), environment-specific data sources, artefact-specific layouts, or conditional components within a page.
How constraints work
Section titled “How constraints work”When building or previewing a specific ReportArtefact, bino evaluates the metadata.constraints on:
- Every non-artefact document (DataSource, DataSet, LayoutPage, Asset, etc.)
- Inline children of
LayoutPageandLayoutCard(nested components)
A document or inline child is included only if all its constraints evaluate to true. Items without constraints are always included.
Constraint syntax
Section titled “Constraint syntax”Constraints can be written in two equivalent formats. Both are fully supported and maintained.
String format (concise)
Section titled “String format (concise)”Quick and readable for simple constraints:
Each constraint is a string with the format: <field> <operator> <value>
Structured format (IDE-friendly)
Section titled “Structured format (IDE-friendly)”Better IDE support with autocomplete and validation:
Mixed format
Section titled “Mixed format”You can mix both formats in the same document:
Both formats have identical evaluation behavior and performance.
Field reference
Section titled “Field reference”The left side (or field property) determines what is being checked:
| Field Path | Description | Example Values |
|---|---|---|
mode |
Current execution mode | build, preview, serve |
artefactKind |
Type of artefact being built | report, screenshot, document, livereport |
labels.<key> |
Artefact’s metadata.labels.<key> |
Any string value |
spec.<field> |
Artefact’s spec.<field> |
Format, orientation, etc. |
Operators
Section titled “Operators”| Operator | Description | Value Type | String Example | Structured Example |
|---|---|---|---|---|
== |
Equals | string, bool | labels.env==prod |
{field: "labels.env", operator: "==", value: "prod"} |
!= |
Not equals | string, bool | mode!=preview |
{field: "mode", operator: "!=", value: "preview"} |
in |
Value in array | array | labels.env in [dev,prod] |
{field: "labels.env", operator: "in", value: ["dev", "prod"]} |
not-in |
Value not in array | array | mode not-in [serve] |
{field: "mode", operator: "not-in", value: ["serve"]} |
Value types
Section titled “Value types”- String: For
==and!=operators - Boolean: Use
trueorfalse(in string format, write them without quotes) - Array: For
inandnot-inoperators (in string format:[value1,value2])
Constraint context
Section titled “Constraint context”Constraints are evaluated against the target ReportArtefact:
mode: The current execution mode:build,preview, orservelabels: The artefact’smetadata.labelsmapspec: The artefact’sspecfields (e.g.,format,orientation,language)
Execution modes
Section titled “Execution modes”| Mode | Description | Command |
|---|---|---|
build |
Building artefacts for production output (PDF/HTML) | bino build |
preview |
Live preview during development with hot reload | bino preview |
serve |
Production serving via LiveReportArtefact | bino serve |
Artefact kinds
Section titled “Artefact kinds”| Kind | Description | Artefact Type |
|---|---|---|
report |
Standard data-driven PDF reports | ReportArtefact |
screenshot |
Component screenshots for testing | ScreenshotArtefact |
document |
Markdown-based documents | DocumentArtefact |
livereport |
Interactive web reports with routes | LiveReportArtefact |
Example artefact with labels
Section titled “Example artefact with labels”Documents can now reference these labels and spec fields:
Multiple constraints
Section titled “Multiple constraints”When multiple constraints are specified, all must match for the document to be included.
This page is included only when:
- The artefact has
labels.region: europe, AND - The command is
bino build(not preview)
Common patterns
Section titled “Common patterns”Preview-only content
Section titled “Preview-only content”Show debug information or work-in-progress pages only during development:
Or using structured format:
Environment-specific data sources
Section titled “Environment-specific data sources”Use different data sources for development vs production:
Multiple environments with in operator
Section titled “Multiple environments with in operator”Match multiple environments at once:
Or using structured format:
Exclude specific modes with not-in
Section titled “Exclude specific modes with not-in”Include a document in all modes except specific ones:
Artefact kind filtering
Section titled “Artefact kind filtering”Include components only for specific artefact types:
Or exclude from specific artefact types:
Format-specific layouts
Section titled “Format-specific layouts”Create different layouts for different output formats:
Or using in for multiple formats:
Inline child constraints
Section titled “Inline child constraints”Constraints also work on inline children of LayoutPage and LayoutCard. This allows you to conditionally include or exclude specific components within a layout:
Inline child constraints support the same syntax as document-level constraints, including structured format:
Choosing a format
Section titled “Choosing a format”| Use Case | Recommended Format | Why |
|---|---|---|
| Simple equality check | String | More concise: labels.env==prod |
Multiple values (in operator) |
Either | Both work well; structured has clearer array syntax |
| Want IDE autocomplete | Structured | JSON Schema provides field/operator suggestions |
| Quick prototyping | String | Faster to type |
| Team prefers YAML validation | Structured | Better schema enforcement |
| Mixed team (devs + analysts) | Both | Let each choose their preference |
Name scoping
Section titled “Name scoping”With constraints, metadata.name uniqueness is per artefact after filtering, not global.
This means:
- The same name can appear multiple times in your configuration
- After applying constraints for a specific artefact, each kind must have unique names
- Different artefacts can include different documents with the same name (if constraints prevent both from matching the same artefact)
Example: Same name, different artefacts
Section titled “Example: Same name, different artefacts”With two artefacts:
Conflict example
Section titled “Conflict example”If constraints allow two documents with the same name and kind to match a single artefact, bino fails with an error:
Registry package names
Section titled “Registry package names”Documents installed from a registry keep their scoped package name
(e.g. @acme/base-layout) as metadata.name, so @scope/name is a valid
document name. Installed packages participate in the same per-artefact
uniqueness rules: a registry package that collides with a local document of
the same kind fails the duplicate-name validation. See the
Registry and dependencies guide.
Error handling
Section titled “Error handling”Constraints are validated at build/preview/serve time. Errors are reported immediately with helpful hints:
Invalid syntax
Section titled “Invalid syntax”Missing label
Section titled “Missing label”Unknown spec field
Section titled “Unknown spec field”Invalid array format (string format)
Section titled “Invalid array format (string format)”Limitations
Section titled “Limitations”ReportArtefactdocuments cannot have constraints (they define the context, not consume it)- Only top-level and nested
specfields are accessible; arrays are not traversable - All constraints in a list must pass (AND logic); OR logic requires multiple documents
Best practices
Section titled “Best practices”- Use labels for logical groupings: Define labels like
env,region, orvarianton artefacts rather than relying solely on spec fields - Keep constraints simple: Complex filtering logic is hard to debug; prefer clear, single-purpose constraints
- Use
infor multiple values: Instead of multiple documents, uselabels.env in [dev,staging]to match multiple values - Document your constraints: Add comments explaining why a constraint exists, especially for non-obvious cases
- Test with preview first: Use
bino previewto verify constraint behavior before building - Avoid duplicate names when possible: Even though scoped names are supported, unique names reduce confusion
- Choose format consistently: Pick string or structured format for your project and use it consistently