Introduction
RECALL is a declarative web interface language with COBOL-inspired syntax. It compiles .rcl source files to self-contained, zero-dependency HTML. Every page embeds its source in an HTML comment — view source, see origin.
RECALL is not a framework, runtime, or templating engine. It is a compiler. Source in. HTML out.
Quick Start
npm install -g @semanticintent/recall-compiler
"IDENTIFICATION DIVISION
No config file. No build pipeline. Open the .html output directly in any browser.
Divisions
Every RECALL program has exactly five divisions, declared in order. Borrowed directly from COBOL — explicit, readable, non-negotiable. COMPONENT DIVISION is optional; all others are required.
| DIVISION | REQUIRED | DESCRIPTION |
|---|---|---|
| IDENTIFICATION DIVISION | REQUIRED | Program metadata — PROGRAM-ID, PAGE-TITLE, AUTHOR, DATE-WRITTEN, DESCRIPTION, FAVICON. |
| ENVIRONMENT DIVISION | REQUIRED | Theme and config — VIEWPORT, COLOR-MODE, PALETTE, FONT, STYLE-BLOCK. Supports COPY FROM for theme inheritance. |
| DATA DIVISION | REQUIRED | Fields and groups — WORKING-STORAGE for scalars, ITEMS for groups. LOAD FROM ingests JSON or CSV at compile time. |
| COMPONENT DIVISION | OPTIONAL | Component definitions — DEFINE, ACCEPTS, END DEFINE. COPY FROM imports .rcpy libraries. WITH DATA binds fields at invocation. |
| PROCEDURE DIVISION | REQUIRED | Render logic — named sections with DISPLAY statements. Must end with STOP RUN. |
Divisions must appear in order: IDENTIFICATION, ENVIRONMENT, DATA, COMPONENT, PROCEDURE. Omitting COMPONENT DIVISION is valid. Omitting any other aborts compilation.
PIC Types
Every DATA DIVISION field carries a PIC type. The compiler validates every DISPLAY statement against the element's type contract — wrong type, wrong format, no output. Run recall schema to query the live registry.
| DECLARATION | KIND | USAGE |
|---|---|---|
| PIC X(n) | string | Text up to n characters. Used by HEADING-1, PARAGRAPH, LABEL, BUTTON, and most elements. |
| PIC X | string | Single character. Shorthand for PIC X(1). Also used with VALUE BLOCK for auto-sized strings. |
| PIC 9(n) | numeric | Integer up to n digits. Use LABEL or STAT-GRID for display. Non-numeric VALUE triggers RCL-012. |
| PIC 9 | boolean-numeric | 0 or 1. Boolean flag. Single-digit numeric. |
| PIC DATE | date | ISO 8601 date string (YYYY-MM-DD). Malformed values trigger RCL-009. |
| PIC URL | url | Must begin with http, https, or /. Malformed values trigger RCL-010. |
| PIC PCT | percent | Integer 0-100. Out-of-range values trigger RCL-011. |
| GROUP | group | Named group declared in ITEMS SECTION. Referenced by USING clause in TABLE, STAT-GRID, CARD-LIST, NAVIGATION. |
"DATA DIVISION
Run `recall schema --json` to see the live element type contracts — which PIC types each element accepts.
Elements
RECALL provides 20 built-in elements invoked with DISPLAY. Run recall schema to query the live element registry from the installed compiler.
| ELEMENT | ARGUMENTS | DESCRIPTION |
|---|---|---|
| HEADING-1/2/3 | value WITH STYLE MONO/SANS | Heading at level 1, 2 or 3. Expects PIC X. |
| PARAGRAPH | value WITH COLOR MUTED/TEXT/ACCENT | Body paragraph. Expects PIC X. Accepts `citations YES` for inline footnote links. |
| LABEL | value | Uppercase eyebrow label. Use before headings to add section context. Accepts PIC X or PIC 9. |
| CODE-BLOCK | value WITH LANGUAGE bash/cobol/json | Monospace code block with optional language hint for syntax display. |
| BUTTON | value ON-CLICK GOTO href | Link styled as a button. WITH STYLE PRIMARY, GHOST, or OUTLINE. |
| LINK | value WITH HREF url | Inline anchor. WITH TARGET BLANK opens in a new tab. |
| IMAGE | WITH SRC url WITH ALT text | Image element. WITH SIZE FULL or HALF sets display width. SRC must be PIC URL. |
| DIVIDER | WITH STYLE DASHED | Horizontal rule. WITH SPACING SMALL or LARGE controls vertical margin. |
| BANNER | value | Full-width accent-coloured banner bar. |
| CALLOUT | value WITH TYPE NOTE/TIP/WARNING/DANGER | Highlighted callout block with typed accent colour. Expects PIC X. |
| INPUT | value WITH TYPE text/email/search | Text input field. The value sets the placeholder label. |
| CARD-LIST | USING group WITH COLUMNS 2/3 | Card grid from an ITEMS group. WITH HOVER-LIFT YES adds card lift on hover. |
| TABLE | USING group WITH COLUMNS col1, col2 | Data table from an ITEMS group. COLUMNS sets header labels; cells map to level-10 fields by position. |
| STAT-GRID | USING group WITH COLUMNS 3/4/6 | Metric display grid. Detects -VALUE and -LABEL field pairs per row automatically. |
| TIMELINE | USING group | Chronological timeline rendered from an ITEMS group. |
| TABS | USING group | Interactive tabbed panels. Each item in the group becomes one tab with a label and content. |
| NAVIGATION | USING group WITH LOGO text | Top navigation bar with logo and links. WITH STICKY YES fixes it while scrolling. |
| SIDEBAR-NAV | USING group WITH LOGO text | Sidebar navigation panel. Only valid inside LAYOUT SIDEBAR. WITH STICKY YES keeps it fixed. |
| FOOTER | WITH TEXT value WITH ALIGN CENTER | Page footer with centred or left-aligned text. |
| SECTION | ID id WITH LAYOUT type WITH PADDING size | Layout container. LAYOUT: CENTERED, STACK, GRID, SIDEBAR, SPLIT. Supports nesting. Closed with STOP SECTION. |
SECTION elements close with STOP SECTION. All other elements are single-line DISPLAY statements.
Copybooks
Copybooks use the .rcpy extension — a reference to COBOL's .cpy format. They are never compiled standalone; only COPY FROM'd into .rcl programs at compile time. recall build skips .rcpy files automatically.
COPY FROM components/nav.rcpy.
A copybook can contain any RECALL division content. COPY FROM is resolved at compile time — the result is one self-contained HTML file.
Use `recall check --inspect` to see what DATA symbols are generated after all COPY FROM and LOAD FROM statements are resolved.
Components
Components are reusable layout fragments defined in COMPONENT DIVISION. Each declares an ACCEPTS list — the DATA DIVISION field names it expects. Callers bind fields with WITH DATA at invocation.
Defining a component
"COMPONENT DIVISION
Invoking with WITH DATA
"DATA DIVISION
REQUIRED parameters
"ACCEPTS PAGE-TITLE REQUIRED, SUBTITLE, BADGE
REQUIRED on an ACCEPTS parameter makes it a compile-time contract. Calling the component without that parameter fires RCL-017 — no output is written.
COMMENT clause
"01 FETCH-SCORE PIC X(10) VALUE 2978
COMMENT clauses surface in `recall check --inspect` output and `--format json` under fieldIntent. They have no effect on compiled HTML — intent only.
Value Language
"Three features modernise the data layer. VALUE BLOCK supports multi-line string literals. RECORD types define reusable group shapes declared once and expanded anywhere.
VALUE BLOCK — multi-line strings
01 BODY-TEXT PIC X VALUE BLOCK. First paragraph of content here. Second paragraph continues here. END VALUE.
PIC X declared without a size (PIC X VALUE BLOCK.) is auto-sized by the compiler to fit the block content exactly.
RECORD types — reusable group shapes
RECORD CARD-SHAPE WITH FIELDS CARD-TITLE PIC X(60) CARD-BODY PIC X(200). 01 CARDS RECORD CARD-SHAPE ROWS 4.
RECORD types are expanded at compile time. Use LIKE to stamp a defined shape onto a group field. All field names are generated deterministically.
Data Loading
LOAD FROM reads a JSON or CSV file at compile time and injects its contents into the DATA DIVISION. Scalars become WORKING-STORAGE fields. Arrays become ITEMS groups. No runtime — values are baked into the compiled HTML.
Load from JSON
DATA DIVISION. LOAD FROM brief.json. * brief.json keys map to field names: { HERO-TITLE: Streaming Consolidation, STATS: [ { VALUE: 2451, LABEL: FETCH Score } ] }
Load from CSV
DATA DIVISION. LOAD FROM metrics.csv. * header row becomes column names: NAME,SCORE,LAYER Revenue (D3),75,origin Quality (D5),62,momentum * Auto-generates METRICS group.
LOAD FROM runs at compile time. No data files are bundled into the HTML — only the resolved field values are embedded.
Multiple LOAD FROM statements in one DATA DIVISION are supported. Data from all files is merged into a single symbol table.
Error Codes
RECALL enforces 26 structured diagnostic codes. Each code is stable, searchable, and documentable. If a program compiles, it is valid. If not, the compiler tells you exactly what is wrong, where, and how to fix it.
Every diagnostic has a stable code. RCL-001 means the same thing forever. Use `recall explain RCL-001` for the full reference on any code.
Errors — abort compilation, no output written
| CODE | CATEGORY | DESCRIPTION |
|---|---|---|
| RCL-001 | type-mismatch | Element received a field of the wrong PIC type. |
| RCL-002 | value-constraint | VALUE string exceeds declared PIC X(n) length. |
| RCL-003 | unknown-element | DISPLAY references an unregistered element name. |
| RCL-004 | unknown-identifier | Variable or group not declared in DATA DIVISION. |
| RCL-005 | missing-required | PROCEDURE DIVISION is empty or absent. |
| RCL-006 | missing-required | PROGRAM-ID or PAGE-TITLE absent from IDENTIFICATION DIVISION. |
| RCL-007 | group-shape | USING references a scalar field — a group is required. |
| RCL-008 | group-shape | Group used where scalar expected, or LAYOUT SPLIT structure invalid. |
| RCL-009 | format | PIC DATE value does not match ISO 8601 (YYYY-MM-DD). |
| RCL-010 | format | PIC URL value does not begin with http, https, or /. |
| RCL-011 | format | PIC PCT value is outside the 0-100 range. |
| RCL-012 | value-constraint | PIC 9 field VALUE contains non-numeric characters. |
| RCL-013 | structural | STOP RUN. is absent from PROCEDURE DIVISION. |
| RCL-014 | structural | Component used in PROCEDURE before its DEFINE block appears. |
| RCL-015 | unknown-identifier | COPY FROM path cannot be resolved on disk or in node_modules. |
| RCL-016 | type-mismatch | WITH DATA passes a name not declared in the component ACCEPTS list. |
| RCL-017 | missing-required | Component called without a REQUIRED ACCEPTS parameter. |
| RCL-018 | structural | Circular COPY detected — file includes itself directly or transitively. |
| RCL-019 | structural | RECORD type referenced but never defined in DATA DIVISION. |
| RCL-020 | value-constraint | VALUE BLOCK encoding error. |
| RCL-021 | unknown-identifier | LOAD FROM file not found or parse failed. |
| RCL-022 | format | Palette key has a trailing period — colour lookup fails silently. |
Warnings — shown but compilation continues
| CODE | CATEGORY | DESCRIPTION |
|---|---|---|
| RCL-W01 | group-shape | Group declared but has no items — element will render empty. |
| RCL-W02 | value-constraint | VALUE string uses over 90% of declared PIC X(n) length. |
| RCL-W03 | missing-required | AUTHOR or DATE-WRITTEN absent from IDENTIFICATION DIVISION. |
| RCL-W04 | structural | Procedure section defined but contains no DISPLAY statements. |
| RCL-W05 | type-mismatch | Numeric PIC 9 field used in a string-accepting element — implicit coercion. |
All 26 codes are actively enforced. Silent failures are errors. If a program compiles, it is valid.
Strict Mode
Strict mode promotes all warnings to errors — zero tolerance for CI pipelines. Machine-readable JSON output includes source lines and caret strings so editor integrations and AI tools can render diagnostics without parsing ANSI sequences.
Terminal output
"ERROR [RCL-001] type-mismatch — my-site.rcl:14:8
JSON output
"recall check my-site.rcl --format json
Exit codes
"0 — clean, no errors or warnings
Use `--quiet` in CI for exit-code-only validation with no terminal output. Use `--strict` to promote all warnings to errors.
Command Reference
The RECALL CLI provides commands for compilation, validation, auto-fix, history diffing, and introspection. All commands accept .rcl files. Copybooks (.rcpy) are resolved automatically during compilation.
recall compile — single file
"recall compile my-site.rcl
recall build — directory
"recall build src/ --out public/
recall check — validate without compiling
"recall check my-site.rcl
recall check is the primary quality gate. --strict for CI. --format json for editor integrations. --inspect to see LOAD FROM symbols before type-checking.
recall fix — auto-apply safe fixes
"recall fix my-site.rcl --dry-run * show what would change
Safe fixes include: PIC resize when VALUE exceeds declared length (RCL-002), AUTHOR insertion (RCL-W03), and empty section removal (RCL-W04).
recall history — git-aware DATA field diff
"recall history my-site.rcl
recall stats — orientation snapshot
recall stats my-site.rcl
recall schema — live element registry
"recall schema * list all elements and PIC types
recall schema queries the installed compiler directly. The output reflects the actual compiler state — drift between docs and implementation is structurally impossible.
recall explain — per-code reference
"recall explain RCL-001
Component Library
@semanticintent/recall-ui is the standard component library. Install once and COPY FROM its .rcpy files — the dark theme, nav, hero, stat-section, card-section, and footer are ready to use.
npm install @semanticintent/recall-ui
"ENVIRONMENT DIVISION
recall-ui components declare strict ACCEPTS contracts. Your DATA DIVISION field names must match exactly. Run `recall check` after adding components.
Themes (dark.rcpy) go in ENVIRONMENT DIVISION via COPY FROM. Components go in COMPONENT DIVISION. The separation is enforced by the compiler.