Skip to content

Language overview

Screenplay is a business-oriented language for specifying the desired functionality of an information system. It describes concepts, commands, facts, views, queries, automations, policies, and specifications without making a particular runtime authoritative. Screenplay now owns the versioned semantic foundation; Stage, Studio, and generated applications are being migrated to consume it capability by capability.

Screenplay files use the .play extension.

  • Indentation-based — Python-style, no braces. Structure follows the offside rule: a construct owns everything indented beneath it.
  • Declarative first, bounded escape hatches — behavior remains meaningful without implementation code. Selected implementation points can carry inline code or file references as realization attachments.
  • Slices are the atom — everything lives inside a typed slice aligned with Event Modeling’s vocabulary.
  • First-class sub-languages — the Projection Declaration Language (PDL) and Change Data Capture Language (CDL) are built-in, independently consumable grammars. Inline language tags are extensible, while host construct keywords remain closed.
  • Concepts carry compliance — value types declare PII and sensitivity attributes once, with the reason they are personal data; all usages inherit them.
  • file is never required — a document must be expressible, and meaningful, before any code exists. Code pointers are realization metadata a slice gains once it is built.
<domain>
<imports>
<concepts and composite types>
<policies, personas, and authentication>
<triggers>
<layouts, themes, and UI profiles>
<module>+
<screen and dialog templates>
<forms and contributions>
<feature>+
<feature>* ← sub-features, arbitrarily deep
<contributions>
<slice>+
<construct>+ ← commands, events, read models, queries, projections, specifications, reactions, captures, screens, constraints
<seeds>

Cross-module references. Imported types are available by their short name within the module.

import Customers.CustomerRegistered
import Customers.CustomerDetailsReadModel

Line comments start with // and run to the end of the line.

TopicPage
The domain a file belongs toDomain
Formalized value types with compliance attributesConcepts
Composite value types - the shapes events carryTypes
Named authorization rulesPolicies
Roles interacting with the applicationPersonas
Modules, features, and the four slice typesModules, Features and Slices
Single-line and fenced multi-line descriptionsDescriptions
Event type declarationsEvents
Commands, validation, the produces block, and handlersCommands
Read-side entry points, parameters and performersQueries
What a handler, a performer, a rule and a policy are givenContexts
PDL-embedded projectionsProjections
CDL-embedded change data captureCaptures
Events seeded per event source idEvent seeding
Server-side rules enforced before commitConstraints
Reaction rulesReactions
What sets a reaction offTriggers
UI declarations at three abstraction levelsScreens
Built-in sub-languages and extensible inline language tagsSub-languages and inline code
The full EBNF grammarGrammar

The @cratis/screenplay-language NPM package provides a Monaco language service for .play files — syntax highlighting (including embedded C#/TypeScript/React/HTML blocks and the PDL/CDL sub-languages), IntelliSense completions, hover documentation, and diagnostics. The screenplay-editor app hosts the editor standalone.

The Screenplay VS Code extension brings the same language support to VS Code — a TextMate grammar with embedded-language and PDL/CDL highlighting, plus IntelliSense, hover, and diagnostics driven by the same shared language logic. .play files carry the Cratis icon.