Getting Started
This guide explains how to use presently to create and deliver web-based presentations using Markdown slides.
Installation
Add the gem to your project:
$ gem install presently
Core Concepts
Presently has several core concepts:
- A
class Presently::Presentationwhich loads and manages slide content from Markdown files. - A
class Presently::PresentationControllerwhich manages the mutable state of a presentation: current slide, clock, and listeners. - A
class Presently::Slidewhich represents a single slide parsed from a Markdown file with YAML frontmatter. - A
class Presently::DisplayViewwhich renders the audience-facing full-screen display. - A
class Presently::PresenterViewwhich renders the presenter console with notes, timing, and slide previews.
Creating Your First Presentation
Create a new directory for your presentation:
$ mkdir my-talk
$ cd my-talk
$ mkdir slides
Writing Slides
Each slide is a Markdown file in the slides/ directory. Files are ordered alphabetically, so prefix them with numbers:
---
template: title
duration: 30
---
# Title
Welcome to My Talk
# Subtitle
A presentation built with Presently
---
These are presenter notes — only visible in the presenter view.
Each slide has three parts:
- YAML frontmatter between
---markers at the top, specifying the template, duration, and other metadata. - Content with Markdown headings that become named sections for the template.
- Presenter notes after a
---separator in the body (optional).
Running the Presentation
Start the server from your presentation directory:
$ presently
Then open two browser windows:
http://localhost:9292/— the audience display.http://localhost:9292/presenter— the presenter console.
Advancing slides in either window updates both in real-time via WebSockets.
Keyboard Controls
- Arrow Right / Space / Page Down — next slide.
- Arrow Left / Page Up — previous slide.
- F — toggle full-screen (display view).
Templates
Templates define the visual layout of each slide. Select a template using the template field in the frontmatter.
Default
A general-purpose content slide. All content without a heading goes into the body section.
---
template: default
duration: 60
---
- First point
- Second point
- Third point
Title
A large title with a subtitle, centered on the slide.
---
template: title
duration: 30
---
# Title
My Presentation Title
# Subtitle
A subtitle or tagline
Section
A section divider slide with a large heading and accent background.
---
template: section
duration: 15
---
# Heading
Part Two
Two Column
A side-by-side layout with left and right sections.
---
template: two_column
duration: 90
---
# Left
**Server Side**
- Ruby + Lively
- WebSocket connections
# Right
**Client Side**
- Live DOM updates
- CSS animations
Code
A syntax-highlighted code slide with optional focus regions for code walkthroughs. Use the focus frontmatter to specify which lines to highlight (1-based). Lines outside the focus range are dimmed, and the code scrolls to center the focused region.
---
template: code
duration: 60
focus: 2-8
title: Constructor
---
```ruby
class Presentation
def initialize
@slides = []
@current_index = 0
end
def advance!
@current_index += 1
end
end
```
Create animated walkthroughs by using multiple slides with the same code but different focus ranges. The transition between them smoothly scrolls and shifts the dim overlays.
Statement
A prominent statement or quote, centered on the slide. Supports an optional # Translation section.
---
template: statement
duration: 30
---
The best way to predict the future is to create it.
# Translation
未来を予測する最善の方法は、それを創ることである。
Translations
All templates support an optional # Translation section. When present, the translation is displayed below the main content in a lighter style. This works with title, section, statement, and image templates.
Image
A centered image with an optional caption.
---
template: image
duration: 30
---

# Caption
System architecture overview
Diagram
A free-form layout slide with a position: relative container. Direct <div> children are position: absolute by default, so you can place elements precisely using inline styles. Use this for custom diagrams, annotated layouts, or any slide that doesn't fit a standard template.
---
template: diagram
duration: 60
---
<div style="left: 10%; top: 20%; width: 35%; height: 25%;">
Browser
</div>
<div style="left: 55%; top: 20%; width: 35%; height: 25%;">
Server
</div>
All other templates also support absolutely positioned overlays since the slide container is position: relative. This lets you add callouts, badges, or annotations on top of any template's normal content.
Transitions
Slides transition instantly by default. Add a transition key to the frontmatter to animate between slides:
---
template: default
transition: fade
---
Available transitions:
| Transition | Effect |
|---|---|
fade |
Crossfade between slides |
slide-left |
Current slide exits left, next enters from right |
slide-right |
Current slide exits right, next enters from left |
morph |
Matched elements animate between positions; everything else crossfades |
The morph transition uses the browser's View Transitions API to smoothly animate individual elements between slides. Elements with the same view-transition-name across two consecutive slides are matched and interpolated.
Presenter Notes
Presenter notes appear after a --- separator in the slide body. They support standard Markdown including bold and italic. Italic text is styled as a stage direction — use it for cues that shouldn't be spoken aloud:
---
*Take a breath and wait for the room to settle.*
Hi everyone, thanks for being here.
*Make eye contact with the front row.*
Presenter Console
The presenter view at /presenter provides:
- Current and next slide previews — see what's coming without switching windows.
- Presenter notes — notes from the slide's
---separator section. - Timer controls — Start, Pause, Resume, and Reset buttons.
- Pacing indicator — shows whether you're on time, ahead, or behind based on per-slide
durationmetadata. - Progress bar — visual indicator of time consumed for the current slide.
- Reload button — reload slides from disk without restarting the server.
Custom Templates
You can provide your own .xrb template files by configuring the templates root:
# In your environment configuration:
service "presently" do
include Presently::Environment::Application
def templates_root
File.expand_path("templates", self.root)
end
end
Templates receive a class Presently::TemplateScope with access to self.slide (the class Presently::Slide instance) and self.section(name) for retrieving named content sections.
Customizing the Application
For advanced customization, create an application.rb and run with presently application.rb:
#!/usr/bin/env presently
class Application < Presently::Application
def title
"My Conference Talk"
end
end