It stays readable
The source still looks like a script, not a word processor export or a wall of tags.
Start Here
Downstage is a plain-text format for stage plays with a few small tools around
it. You write one .ds file, and the same file can be checked for mistakes,
rendered to PDF, turned into HTML, and edited with writing-aware assistance in
supported editors.
The source still looks like a script, not a word processor export or a wall of tags.
Acts, scenes, cues, stage directions, character lists, songs, and verse are native ideas.
You can render a manuscript, preview as HTML, and use editor support without rewriting the document.
Plain text makes it easy to compare drafts, review changes, and keep a readable history in Git.
Why
If Fountain feels too screenwriting-shaped and a word processor keeps nudging you into layout work, Downstage gives you a plain-text workflow built for plays.
You are writing the play, not wrestling with invisible spacing rules and style menus.
Plain text travels well, works with version history, and does not trap your script in one app.
Downstage is built for stage writing, so common playwriting structures do not feel bolted on.
It works on macOS, Windows, Linux, and in the Web Editor without locking your script to one device.
How
You do not need the whole spec before you begin. Start with a tiny script, then keep the docs open for the parts you actually need.
If you want the shortest path to a real script page, start in the Web Editor. It runs in the browser and gives you live preview plus PDF export.
Title: My Play
Author: You
JANE
I finally started the draft.Paste that into the Web Editor, make a small change, then export a PDF.
If VS Code is already your writing environment, install the extension and stay there.
1. Install the Downstage extension
2. Open or create a .ds file
3. Draft a scene
4. Use live preview or render to PDFIf you prefer terminal workflows, install Downstage and render from the command line.
brew tap jscaltreto/tap
brew install downstage
# Go users can install with:
# go install github.com/jscaltreto/downstage@latest
downstage render my-play.dsFirst Pass
A typical workflow is simple: write in plain text, preview when you want feedback, and export when you want pages.
Write cues, dialogue, headings, and stage directions in a single file.
Use the Web Editor or VS Code preview when you want immediate page feedback while drafting.
Export a PDF manuscript or acting edition from the same draft when it is ready to read or share.
Reference
The rest of this page is the language reference. Use it when you need to look up how a specific feature is written, not as the only way to understand what Downstage is.
ALICE
Hello, world!1
A Downstage document has an optional title page and then the play body. The body can contain a character list, acts, scenes, prose sections, dialogue, songs, comments, and page breaks.
ALICE
Hello, world!That minimal file is valid. No title page or headings required.
2
Title-page metadata lives at the top of the file as Key: Value pairs. Any key
name is accepted. Indented lines continue the previous value.
The title page ends when the file hits a heading, a page break, or a non-indented line that is not a metadata pair.
Title: The Last Curtain Call
Subtitle: A Drama in Two Acts
Author: Eleanor Vance
Date: 2025
Notes: Inspired by true events
and several missed cues.3
The character list is a dedicated section. Entries can include descriptions, aliases, and optional subgroup headings.
# Dramatis Personae
MARGARET — An aging actress
JAMES/JIM — Her estranged son
## The Crew
STAGEHAND 1 — Quiet, efficient
STAGEHAND 2 — Nervous and chattyNAME or NAME — Description are both valid.NAME/ALIAS defines a shorter dialogue alias inline.# Dramatis Personae, # Cast of Characters, and # Characters all start the same section type.
4
If you do not need acts or scenes, skip them. Downstage does not force a structure you are not using.
Acts are usually written as ## headings.
## ACT I
## ACT 2
## ACT: FinaleScenes are usually written as ### headings, though a non-act ## heading inside an act also becomes a scene.
### SCENE 1
### SCENE 1: The Palace
### A Bare Stage5
Dialogue starts with a character name on its own line, followed by an optional parenthetical and one or more speech lines.
Character names are uppercase and may contain spaces, punctuation like periods and apostrophes, digits, and slashes for alias-aware names.
HAMLET
(aside)
To be, or not to be, that is the question.
MARGARET
They used to fill every seat, you know.
Every last one.6
To mark simultaneous speech, add ^ to the end of the second character cue.
The first cue stays normal.
The ^ must be the last character on the line, preceded by a space, and only
the second cue gets the marker. Forced character cues also work, as in
@narrator ^. If there is no previous dialogue block to pair with, the cue is
treated as normal dialogue.
HORATIO
They're here.
HAMLET ^
Then let them come.7
Stage directions can stand on their own or live inside dialogue.
Standalone stage directions start with >. Use >> for bold non-structural callouts inside scene flow.
> The lights dim.
>> Midwinter. The room has not been heated for days.Inline parentheticals inside dialogue stay part of the speech block.
HAMLET
To be (pause) or not to be.8
Indent dialogue lines by two or more spaces to preserve line breaks as verse.
Prose and verse can be mixed inside the same speech block.
MARGARET
To stand upon this stage once more,
to feel the boards beneath my feet,
to hear the hush before the roar,
to know this moment, bittersweet.9
Songs wrap a block of theatrical content between SONG and SONG END.
Numbering and titles are optional. The contents can include dialogue, verse, and stage directions.
SONG 1: The Stagehand's Lament
JIM
Under the lights we never stand,
behind the curtain, close at hand.
SONG END10
Inline formatting works in dialogue, verse, and stage directions.
*text*
Italic
**text**
Bold
***text***
Bold italic
_text_
Underline
~text~
Strikethrough
11
These elements affect the working file and rendered pages differently.
Comments are ignored when rendering, so they will not appear in the PDF.
// A line comment
/* A block comment
spanning multiple lines */=== inserts a page break in rendered output.
===
### SCENE 212
When the parser would otherwise classify a line incorrectly, force it.
@name forces a character cue.
@horatio
My lord, I came to see your father's funeral..Heading forces a structural heading.
.The Next Evening13
This excerpt shows how the pieces fit together in a real script.
For the exhaustive reference, read the full spec.
Title: The Last Curtain Call
Author: Eleanor Vance
# Dramatis Personae
MARGARET — An aging actress, once famous
JAMES/JIM — Her estranged son
CLAIRE — The new director
# The Last Curtain Call
## ACT I
### SCENE 1
> The stage is bare except for a single chair.
MARGARET
(sitting in the chair)
They used to fill every seat, you know.
JAMES
Mother, the crew is waiting.Acknowledgements
Downstage is inspired by Fountain, which showed the value of a readable plaintext format for scripts, and by the archived TheatreScript specification, which explored theatre-native structure directly.
This project builds on those ideas with a more complete toolchain for stage writing: rendering, validation, and editor support around the same readable source format.
Downstage was created by Jake Scaltreto, a software developer and playwright who wanted a better way to write plays than fighting a word processor.