A web-based presentation tool built with Lively. Write your slides in Markdown, present them in the browser, and control everything from a separate presenter display.
- Markdown slides with YAML frontmatter for metadata and template selection.
- Presenter display with current slide, next slide preview, notes, and timing.
- Real-time sync between display and presenter via WebSockets.
- Code highlighting with @socketry/syntax, including animated focus regions for code walkthroughs.
- Multiple templates — title, section, two-column, code, translation, image, and default.
- Colocated styles — presentation, directory, and slide-specific CSS can live beside the slides it styles.
- Timing and pacing — per-slide duration metadata with elapsed/remaining time and pacing indicators.
- Slide narration — record, review, and retake one audio track per slide from a dedicated recording interface.
- Narrated playback — automatically play each slide with its recorded narration, including slide scripts and transitions.
- Full-screen support — press
Fon the display view. - Keyboard navigation — arrow keys, space, Page Up/Down.
Please see the project documentation for more details.
-
Getting Started - This guide explains how to use
presentlyto create and deliver web-based presentations using Markdown slides. -
Animating Slides - This guide explains how to animate content within slides using the slide scripting system.
-
Animated Diagrams - This guide explains how to design responsive, lifecycle-safe animated diagrams in Presently using semantic markup, slide-specific CSS, and Anime.js choreography.
Open http://localhost:9292/record to record narration separately from the live presenter interface. Presently stores one WebM/Opus recording per slide under audio/, mirroring the slide's relative path:
slides/020-problem/010-overview.md
audio/020-problem/010-overview.webm
The interface preserves the microphone's dynamics for offline normalization and excludes mouse clicks at the recording boundaries using a short delayed audio pipeline. An existing recording is preserved until a completed retake is explicitly saved.
After recording, normalize every completed take to a consistent -16 LUFS target:
bundle exec bake presently:recordings:normalizeThe task preserves the original files under audio/ and writes normalized copies to matching paths under audio-normalized/. It requires FFmpeg.
Open http://localhost:9292/playback to watch the narrated presentation. Playback uses normalized audio when available, falls back to the original recording, and advances when each track ends.
For automated capture, use http://localhost:9292/playback?autoplay=true&controls=false. The page exposes window.__PRESENTLY_PLAYBACK_READY and window.__PRESENTLY_PLAYBACK_FINISHED, and dispatches matching presently:playback-ready and presently:playback-finished events.
To export playback directly to an MP4 file using a Chromium build that supports Page.startScreenRecording:
PRESENTLY_CHROME_PATH=/path/to/chromium \
PRESENTLY_CHROMEDRIVER_PATH=/path/to/chromedriver \
bundle exec bake presently:export:video output=presentation.mp4The task records the presentation at 1920×1080 and 30 frames per second by default. Use width, height, and frame_rate to select different limits. If explicit browser paths are omitted, Presently tries the current Chrome for Testing canary build.
Please see the project releases for all releases.
- Support language-prefixed inline code such as
ruby:for syntax highlighting. - Preserve blank lines within consistently indented HTML blocks in slide Markdown.
- Render slides on a responsive 16:9 canvas across the display, presenter, recording, playback, and export interfaces.
- Center diagram content by default, add optional diagram titles, and make free-form absolute positioning explicit with
.diagram-freeform. - Prevent slide backgrounds and content from flickering during view transitions.
- Add lifecycle-managed Anime.js animation scopes, reusable diagram setup scripts, and guidance for authoring animated diagrams.
- Truncate long slide paths responsively while preserving their filenames in presenter controls.
- Preserve the complete saved presentation state when restoring the controller.
- Fix slide rendering events for generated view identifiers that begin with a digit.
- Add slide-scoped resource cleanup with
Slide#defer,Slide#signal, and idempotentSlide#dispose. Existing tracked timeouts now use the same disposal lifecycle. - Web Packages
- Add support for organizing slides in nested directories. Every directory and slide filename must begin with a numeric prefix, and slides are ordered by relative path.
q
- Export works from current working directory.
- Remove explicit support for
morphtransition.
- Remove explicit support for
- Increase code font size by 50%.
- Add support for includes using
![[path]]syntax. - Add
bake presently:rehearsetasks for updating timing information.
- Change zoom to 50% on slide preview (presenter display).
- Add support for translation to code slide.
- Add
Slide#elementandSlideContext#elementgetters — expose the slide body DOM element directly for cases wherefind()is not sufficient, such as measuring dimensions, attaching event listeners, or integrating third-party libraries.
- lively — The real-time application framework that powers Presently.
- falcon — The web server used to host presentations.
- syntax-js — Syntax highlighting for code slides.
- markly — CommonMark parser used for slide content.
We welcome contributions to this project.
- Fork it.
- Create your feature branch (
git checkout -b my-new-feature). - Commit your changes (
git commit -am 'Add some feature'). - Push to the branch (
git push origin my-new-feature). - Create new Pull Request.
To run the test suite:
bundle exec susTo make a new release:
bundle exec bake gem:release:patch # or minor or majorIn order to protect users of this project, we require all contributors to comply with the Developer Certificate of Origin. This ensures that all contributions are properly licensed and attributed.
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
