Getting started
By the end of this page you’ll have a .play file that models a small feature — a command, the event it produces, and a screen that reads it — open in an editor that highlights the language, completes it as you type, and flags mistakes live. That editor is what this repository ships; running a .play as an application is Stage’s job, and this tutorial gets you to the point where a Screenplay is ready for it.
Before you start
Section titled “Before you start”You need Node.js 20 or newer. Clone the repository and open a terminal in its root:
git clone https://github.com/Cratis/Screenplay.gitcd ScreenplayRun the editor
Section titled “Run the editor”Install the workspace and start the standalone editor:
yarn installyarn buildyarn devyarn dev serves the editor at http://localhost:9200. It opens on a complete sample — the invoicing .play — so the very first thing you see is the language rendered with full syntax highlighting, including the embedded C#, TypeScript, and React blocks.
Model a slice
Section titled “Model a slice”Clear the editor and start a bounded context. A .play file is indentation-based — structure follows the offside rule, and a construct owns everything indented beneath it. Type the outline of a module with one feature and one slice:
module Library
feature Lending
slice StateChange BorrowBookAs you type slice, the completions offer the four slice types — StateChange, StateView, Automation, Translate. StateChange is the one that accepts a command and records what happened.
Add the command and the event
Section titled “Add the command and the event”Inside the slice, declare the command, the rule that guards it, and the fact it produces:
slice StateChange BorrowBook command BorrowBook bookId BookId borrowedBy MemberId authorize IsMember validate bookId not empty message "A book is required" produces BookBorrowed bookId = bookId borrowedBy = borrowedBy borrowedAt = $context.occurred
event BookBorrowed bookId BookId borrowedBy MemberId borrowedAt DateTimeNotice what the file is saying in one read: who may call it (authorize), what has to be true (validate), and the past-tense fact it appends (produces → event). The event never carries an identity of its own — $context.occurred and the event source come from the surrounding context, not the payload.
Watch a mistake get caught
Section titled “Watch a mistake get caught”That slice references a policy, IsMember, that you haven’t declared. The language service knows it: IsMember is underlined with a diagnostic — reference to an undeclared policy. This is the live feedback the editor gives you for the whole language — unknown slice types, unknown primitive types, references to undeclared policies or events, and tab indentation are all flagged as you type.
Declare the policy at the top of the file, above the module, and the diagnostic clears:
policy IsMember require authenticatedRead it back on a screen
Section titled “Read it back on a screen”A command that records facts is only half a feature. Add a second slice — a StateView — that projects the event into a read model and puts it on screen:
slice StateView OnLoan query BooksOnLoan => OnLoanReadModel[]
projection OnLoan => OnLoanReadModel from BookBorrowed key bookId borrowedBy = borrowedBy borrowedAt = borrowedAt
screen OnLoan data OnLoanReadModel[] via query BooksOnLoanThe projection uses the embedded Projection Declaration Language to fold events into a read model; the query exposes it; the screen renders it. No update code, no proxy to regenerate by hand — the whole read path is declared in six lines.
What you’ve built
Section titled “What you’ve built”You have a .play file that models a complete slice of behavior — command, event, projection, query, and screen — with authorization and validation, all in one file the editor understands. That file is a Screenplay ready to hand to Stage.
Where to go next:
- Language overview — the design principles and the full map of constructs.
- Modules, features, and slices — the four slice types and what goes in each.
- Why Screenplay — the reasoning behind modeling a bounded context in one file, and when not to.
- Glossary — the vocabulary, defined once.