Every shotknows its scene

A screenplay editor and a shot list that actually talk to each other.

Roll soundSpeedRoll cameraMark itActionCutCheck the gateMoving onRoll soundSpeedRoll cameraMark itActionCutCheck the gateMoving onRoll soundSpeedRoll cameraMark itActionCutCheck the gateMoving on
Write the scriptPlan the shotsWrap on timeWrite the scriptPlan the shotsWrap on time
Sc. 01The problem

Your script lives in one app, your shot list lives in a spreadsheet, and the second someone rewrites scene 12 they stop agreeing.

Sc. 02The fix

Shots that staywith their scene.

Shotlist pins every shot to its scene with a permanent ID. Renumber, rename, cut and paste all you want. When a scene’s text changes, its shots get a scene changed badge so you know to check them.
Go on, try to break it. ↓
midnight-diner
Midnight DinerDraft 3 · p. 7
Shot list10 shots
11EXT. ROOFTOP - NIGHT
  • 11AWSSkyline in the rain
  • 11BMCUMaya counting windows
  • 11CPOVThe window goes dark
12INT. STAIRWELL - CONTINUOUS
  • 12AMSMaya descends, handheld
  • 12BInsertDoor slams shut
13INT. DINER - NIGHT
  • 13AWSDiner, neon through rain
  • 13BMSLeo and Maya at the counter
  • 13CInsertCoffee pours
14EXT. ALLEY - LATER
  • 14ACUPhone screen
  • 14BWSMaya runs through the steam
Click a scene in the script, then move it, rewrite it, or add a shot.
Sc. 03In the can

Alreadyin the can.

Everything here works today. Point it at Postgres, open the editor, and start writing.
Dialogue
↵ Enter⇥ Tab
int. diner - night
Leo pours two coffees. Waits.
Maya
You kept my cup.

A real screenplay editor

Proper formatting in Courier Prime. Enter and Tab move between elements, INT. and EXT. are detected as you type, and characters and locations autocomplete.

12A
12B
12C
12D
12E
12F
12G
12H
12I
12J
12K
12L
12M
12N
12O
12P

Labels like a real slate

A table or storyboard cards, grouped by scene and labeled 12A, 12B, 12C. It skips I and O, because on a slate they read as 1 and 0.

Saved· just now
.fountain ↓

Autosave that won't eat your pages

Keeps a local copy when you're offline, refuses stale saves from other tabs, and exports to Fountain.

12  INT. DINER - NIGHT12

Neon flickers. LEO (60s) already has two cups poured. Maya slides onto a stool.

LEO

Same as always, Maya? Black, two sugars, and whatever pie is left?

⌘KMake Leo colder. Fewer words.

Suggested edit · Scene 12

Same as always, Maya? Black, two sugars, and whatever pie is left?

You're late.

Accept ↵Discard esc

AI that has read your script

Press ⌘K to write or rewrite at the cursor, draft a whole script from your logline, chat with an assistant that proposes edits, or Tab through inline suggestions. Nothing lands until you accept it.

Scene 12 · 3 shots

  • 12ADiner, neon
  • 12BLeo and Maya
  • 12CCoffee pours
+ Add shot

Shots next to the script

A side panel shows the shots for whatever scene your cursor is in, and you can add more from there.

4.8 MB → 310 KB, then straight to s3://your-bucket

Reference frames

Drop, paste or click to add an image to any shot. The browser shrinks it, then it goes straight to your own S3 bucket. Try it with any image.

ABC
1ShotSizeDescription
212AWSDiner, neon through rain
312BMSLeo and Maya at the counter
412CInsertCoffee pours
513AMSMaya descends, handheld

CSV export

For the AD who lives in Sheets.

Sc. 04On the call sheet

What we'reshooting next.

Script versions and diffs, shoot days and setups, PDF export and a phone-friendly on-set view. The whole plan lives in docs/spec.md.

Prod. Shotlist v1
Office: GitHub

CALL SHEET

Day 02 of ∞

Crew call: Soon

Shoot call: TBA

Weather: Clear

Sc.Set / DescriptionD/NPgs
21

INT. VERSION HISTORY

Script versions and diffs. Save named drafts, compare any two, restore safely.

D2 4/8
22

INT. PRODUCTION OFFICE

Shoot days and setups. Group shots into setups, order them, see time estimates.

D3/8
23

INT. PRINT SHOP

PDF export, ready to hand out with the call.

N1/8
24

EXT. ON SET

A phone-friendly on-set view for the floor.

D5/8
Notes: full plan in docs/spec.md1st AD: tushgaurav
Sc. 05Rolling

Roll yourown.

Shotlist is open source and runs wherever you run Node. Five commands and you’re writing.
  • Node 22+

    Runs the app.

    Required
  • Postgres

    Holds your projects.

    Required
  • S3 bucket

    Only needed for shot images.

    Optional
  • OPENROUTER_API_KEY

    Turns on AI writing. Get one at openrouter.ai/keys.

    Optional
~/shotlist
$git clone git@github.com:tushgaurav/shotlist.git && cd shotlist
$npm install
$cp .env.example .env.local # set DATABASE_URL and BETTER_AUTH_SECRET at minimum
$npm run db:migrate
$npm run dev
✓ Ready on localhost:3000

Open localhost:3000 and create your account. Then set DISABLE_SIGNUP=true so nobody else can.

npm test runs the Vitest suite and npm run typecheck runs the type checker.

Built with

Roll credits.

Directed by
tushgaurav
Framework
Next.js 16
Starring
React 19
Screenplay editor
TipTap
Continuity
Drizzle + Postgres
Security
Better Auth
Wardrobe
Tailwind 4 + shadcn/ui
Props department
S3
Script doctor
AI SDK + OpenRouter