Americo73 downloadsScroll notes as a teleprompter with mobile remote control, Stream Deck integration, countdown timer, and voice tracking.
Professional teleprompter for Obsidian — Stream Deck hardware control, mobile remote, neural text-to-speech, and full Markdown support.
Built for video recording, presentations, podcasts, speeches, and content creation.
Teleprompter Plus turns any Obsidian note into a professional teleprompter. Auto-scroll at adjustable speed, highlight your reading position, control playback from the keyboard, an Elgato Stream Deck, or a phone, and optionally read your script aloud with high-quality neural voices. Designed for creators who already live in Obsidian and want a teleprompter that speaks the same Markdown they write in.
say, Web Speech fallback, sentence-by-sentence highlighting[@ries2011] spoken as "(Ries, 2011)" using your .bib files
Clean reading display with hierarchical navigation panel, eyeline guide, and real-time position tracking.
Touch-friendly remote — phone, tablet, or second computer on the same network.
55+ hardware actions with live state synchronization across all controls.
Six-tab settings: Dashboard, Toolbar, Features, Profiles, Connection, About.
Obsidian → Settings → Community plugins → Browse → search Teleprompter Plus → Install → Enable.
main.js, styles.css, and manifest.json from the latest release.<your-vault>/.obsidian/plugins/teleprompter-plus/ (create the folder if needed).git clone https://github.com/JuracyAmerico/obsidian-teleprompter-plus.git
cd obsidian-teleprompter-plus
bun install
bun run build
# copy dist/main.js, dist/styles.css, and manifest.json into your vault's plugins folder
See CONTRIBUTING.md for the full development setup.
Cmd/Ctrl + P).+ / −, font size with Aa+ / Aa−.For 25+ keyboard commands, see Obsidian → Settings → Hotkeys → Teleprompter Plus.
| Tab | What's there |
|---|---|
| Dashboard | Live preview, quick profile picker, health status |
| Toolbar | Choose which controls appear in the teleprompter toolbar |
| Features | Collapsible cards by category — appearance, playback, navigation, voice, OBS, WebSocket |
| Profiles | 8 built-in profiles + your own saved configurations |
| Connection | Optional local WebSocket server for Stream Deck + mobile remote |
| About | Plugin info, shortcuts, credits |
55+ actions across 8 categories — Playback, Speed, Font, Navigation, Display, Utility, Countdown, Flip. Real-time bidirectional state sync: the Stream Deck button updates live when you change the teleprompter from any source.
{ "command": "toggle-play" }
{ "command": "set-speed", "value": 3 }
{ "command": "jump-to-header", "value": 1 }
Full action catalog, configuration steps, and Stream Deck plugin setup: docs/stream-deck-actions.md.
A local-only WebSocket server (default ws://127.0.0.1:8765) lets you build custom controls in any language.
const ws = new WebSocket('ws://127.0.0.1:8765')
ws.onopen = () => ws.send(JSON.stringify({ command: 'play' }))
ws.onmessage = (e) => {
const msg = JSON.parse(e.data as string)
if (msg.type === 'state') console.log('speed:', msg.data.speed)
}
Full command list, state shape, and integration examples: docs/websocket-api.md.
Privacy — the server binds to
127.0.0.1only. No LAN or internet exposure by default. The mobile remote piggy-backs on your existing Obsidian session over the same loopback bridge.
Three engines, selected automatically based on availability:
say — built-in system voices (Samantha, Daniel, etc.). No setup.Pause/resume from the toolbar or keyboard. Citations are resolved from your bibliography (Quarto/Pandoc .bib files).
Most common issues:
| Issue | Fix |
|---|---|
| WebSocket port already in use | Settings → Connection → change port (default 8765). Click Restart server. |
| Stream Deck not connecting | Settings → Connection → Restart server. Confirm the Stream Deck plugin is installed and points at the same port. |
| Plugin doesn't appear after install | Verify <vault>/.obsidian/plugins/teleprompter-plus/ contains main.js, styles.css, manifest.json. Reload Obsidian (Cmd/Ctrl + R). |
| Content not updating when switching notes | Close and reopen the teleprompter view. |
| Fullscreen looks wrong | Plugin fullscreen is in-window. For true OS fullscreen, use Obsidian's View → Toggle Fullscreen first. |
| Pin window does nothing | macOS and Windows only. Some Linux window managers override this. |
Full troubleshooting guide: docs/troubleshooting.md.
%%{init: {'theme':'base', 'themeVariables': {
'background':'#0a0a0a',
'primaryColor':'#001a26',
'primaryTextColor':'#e0fbff',
'primaryBorderColor':'#00d4ff',
'secondaryColor':'#1a0a02',
'tertiaryColor':'#001824',
'lineColor':'#00d4ff',
'fontFamily':'Inter, sans-serif'
}}}%%
flowchart LR
subgraph Clients["🎮 EXTERNAL CLIENTS"]
direction TB
StreamDeck["Stream Deck<br/>55+ actions"]
Mobile["Mobile Remote<br/>touch web UI"]
Custom["Custom Scripts<br/>TS · Node · Python"]
end
subgraph Bridge["🔌 WEBSOCKET BRIDGE"]
direction TB
WS["ws://127.0.0.1:8765<br/><i>loopback only</i>"]
Commands["Command Router"]
Broadcast["State Broadcaster"]
WS --> Commands
WS --> Broadcast
end
subgraph Obsidian["📔 OBSIDIAN PLUGIN"]
direction TB
Plugin["Plugin Entry<br/>main.ts"]
View["Teleprompter View<br/>ItemView"]
Settings["Settings Manager"]
Plugin --> View
Plugin --> Settings
subgraph Core["Core Components"]
direction LR
Svelte["Svelte 5 UI"]
Markdown["Markdown<br/>marked + hljs"]
State["State<br/>$state · $effect"]
end
View --> Core
end
subgraph Branches["⚡ SIDE BRANCHES"]
direction TB
TTS["TTS Engines<br/>Kokoro · say · Web Speech"]
Cite["Citation Resolver<br/>[@key] → (Author, Year)"]
OBS["OBS Service<br/>recording sync"]
end
StreamDeck <-->|"commands ⇄ state"| WS
Mobile <--> WS
Custom <--> WS
Bridge <-->|"local IPC"| Plugin
View --> TTS
View --> Cite
Plugin --> OBS
classDef client fill:#1a0a02,stroke:#FF6B00,stroke-width:2px,color:#FF6B00
classDef bridge fill:#001824,stroke:#00d4ff,stroke-width:3px,color:#00d4ff
classDef obs fill:#001a26,stroke:#00d4ff,stroke-width:2px,color:#00d4ff
classDef branch fill:#001824,stroke:#00d4ff,stroke-width:2px,stroke-dasharray: 5 5,color:#e0fbff
class StreamDeck,Mobile,Custom client
class WS,Commands,Broadcast bridge
class Plugin,View,Settings,Svelte,Markdown,State obs
class TTS,Cite,OBS branch
Orange = command sent from a client. Cyan = state update broadcast back. All traffic stays on
127.0.0.1— never on LAN.
A richer Excalidraw version of this diagram is in docs/architecture.excalidraw — open it in Obsidian (with the Excalidraw plugin) to view, edit, or export to PNG/SVG for slides and presentations.
Design system, component reference, and icon catalog: docs/.
Pull requests welcome. See CONTRIBUTING.md for the tech stack, project structure, build workflow, code style, and contribution guidelines.
Full version history in CHANGELOG.md. Latest release: see the Releases page.
Have an idea? Open a discussion or submit an issue.
Created by Juracy Américo (@JuracyAmerico).
Built with Obsidian, Svelte 5, TypeScript, Vite, Tailwind CSS, marked.js, highlight.js, and ws.
MIT License. Copyright © 2024–2026 Juracy Américo. See LICENSE.
If this plugin saves you time, you can support continued development: