BuildWithMatija
Back to Builds
ToolActiveDemo available

PromptSync

A browser teleprompter that keeps an old iPad, laptop, or second screen in sync with the controller.

  • Node.js
  • WebSockets
  • HTML
  • JavaScript
  • SCSS
  • Docker
  • GitHub Actions
  • nginx
Live demoGitHubVisit website
Problem
Teleprompter setups get annoying when the script lives on one device but the display is somewhere else. Older tablets can still be useful as viewer screens, but many modern web apps are too heavy or do not handle iOS fullscreen limitations well. The friction is especially visible when recording videos alone, where editing the script, controlling scroll speed, and keeping the display readable all need to happen without touching the viewer device.
Thesis
A small browser app with plain HTML, compiled CSS, Node.js, and WebSockets can cover the useful teleprompter workflow without requiring a native app. The controller should own the script and display controls, while viewer devices only need a room code and a lightweight synchronized rendering layer. Prioritizing old-browser compatibility matters more than adding a heavy editor or account system.
Validation
The repository includes a working Node.js server, controller page, viewer page, WebSocket room synchronization, Docker deployment, and a GitHub Actions deploy workflow. The README documents a production URL at https://promptsync.site and a production topology using nginx, Docker, and Cloudflare DNS-only routing. There is no verified user count, customer usage, or public launch evidence beyond the documented deployment.
Proof points
  • README describes PromptSync as a lightweight browser-based teleprompter and presentation viewer built for broad browser compatibility, including older tablets.
  • README documents controller and viewer roles, six-digit room codes, WebSocket content sync, scroll synchronization, controller-driven autoplay, display controls, and fullscreen support.
  • README documents a production URL at https://promptsync.site.
  • Dockerfile and docker-compose.yml exist for containerized deployment.
  • GitHub Actions workflow builds CSS and deploys the app over SSH on pushes to main.
  • No public user count, customer count, or revenue proof is documented.
Audience
  • Creators recording videos who want a controllable teleprompter without buying dedicated hardware
  • People using an old iPad or tablet as a viewer screen
  • Developers who want a small self-hosted teleprompter instead of a native app

Executive summary

PromptSync is a small browser-based teleprompter and presentation viewer.

The core workflow is simple: open the controller on a laptop or modern browser, open the viewer on another device, enter the same six-digit room code, and the viewer stays synchronized with the controller. The controller pushes script content, scroll position, autoplay state, and display settings over WebSockets.

The project is built with plain browser technologies, Node.js, SCSS, and the ws WebSocket package. The README explicitly calls out broad browser compatibility, including older tablets, as a design goal.

The problem

A teleprompter sounds simple until the display and the controls are on different devices.

If the script is on the viewer device, editing text or changing scroll speed means touching the same screen you are trying to read from. If the screen is an old iPad or tablet, many modern web apps are too heavy, too framework-dependent, or awkward around fullscreen behavior. On iOS Safari, fullscreen also has limitations, so the viewer flow needs to account for Home Screen installation.

PromptSync solves the small but real friction of using a second device as a clean reading screen while keeping control on the main device.

The thesis

The bet is that this does not need to be a native app.

A controller/viewer split, six-digit room codes, and a lightweight WebSocket state layer are enough for the main teleprompter workflow. The controller owns the script, scroll, autoplay, and display controls. The viewer only needs to join a room and render the latest synchronized state.

The implementation intentionally keeps the frontend simple: static HTML pages, one browser script, SCSS compiled to CSS, and a Node.js server that serves files and manages WebSocket rooms.

What I built

Controller and viewer roles

PromptSync has two separate browser entry points:

  • controller.html
  • viewer.html

The controller can generate or join a six-digit room, write the script, push updates, control scroll, start or pause autoplay, adjust autoplay speed, open a viewer window, and preview the rendered output.

The viewer joins the same room code and displays the synchronized content.

Real-time room synchronization

The server keeps in-memory room state for each six-digit code.

Each room stores:

  • current script content
  • scroll percentage
  • autoplay state and speed
  • display settings
  • controller connection
  • viewer connections

When the controller changes content, scroll, autoplay, or settings, the server broadcasts the updated state to connected viewers.

There is no documented persistent database. Room state is in memory, and empty rooms are deleted when the controller and viewers disconnect.

Teleprompter controls

The controller supports:

  • live script editing
  • manual push update
  • scroll synchronization
  • scroll up and scroll down buttons
  • autoplay start and pause
  • autoplay speed control
  • font size control
  • line height control
  • content width control
  • top and bottom frame insets
  • horizontal offset
  • dark and light theme
  • horizontal mirroring
  • vertical mirroring
  • presentation mode
  • fullscreen preview

The viewer supports room joining and fullscreen-style viewing.

Lightweight markdown-style rendering

PromptSync does not use a full markdown engine.

The browser script includes a small renderer for the formatting needed by a teleprompter:

  • # Heading 1
  • ## Heading 2
  • ### Heading 3
  • paragraphs
  • **bold**
  • *italic*
  • bullet lists
  • --- separators
  • [pause] blocks

That keeps the renderer small and predictable for older browser support.

Older iPad support

The README specifically documents a recommended setup for iPad 4 / iOS 10.

The viewer is intended to be added to the iPad Home Screen and launched from that icon, because iOS Safari needs that flow for fullscreen-like behavior. If the viewer is opened inside normal Safari on iOS, the app shows instructions to use Share → Add to Home Screen.

The browser script also includes iOS Safari detection, viewport handling, orientation handling, and an immersive viewer mode fallback.

Deployment

The repository includes Docker production support.

The Dockerfile uses Node 22 Alpine, builds SCSS into plain CSS, copies the static public files and server into a runtime image, exposes port 3000, and defines a healthcheck against /health.

The Docker Compose file runs the app as a container named promptsync, with BASE_PATH support and a healthcheck.

The README documents a production topology with:

  • app path: /root/promptsync
  • public URL: https://promptsync.site
  • nginx ingress
  • internal Docker networking
  • Cloudflare DNS-only routing
  • direct health checks

The GitHub Actions workflow builds CSS, verifies public/styles.css, then deploys over SSH by pulling main on the server and recreating the Docker Compose service.

Architecture

text
Controller browser
  → controller.html
  → app.js
  → WebSocket

Node.js server
  → static file serving
  → in-memory room state
  → WebSocket broadcast

Viewer browser
  → viewer.html
  → app.js
  → synchronized script, scroll, autoplay, and display settings

Current status

Active with public demo. Production deployment runs at promptsync.site via Docker, nginx, and GitHub Actions deploy on push to main. Controller and viewer flows, WebSocket room sync, and older iPad Home Screen setup are documented and working.

No installer package, public user count, or revenue model. Room state is in-memory only — rooms disappear when all clients disconnect.

Related services

  • Internal tools

Working through something similar?

If your company has a workflow, content system, or internal process that needs to become real software, this is the kind of work I can help with.

Get in touch

Related builds

You might also find these useful

ToolActiveOpen source

DropImg

A self-hosted, Docker-first image hosting tool — drag, drop, or paste to get instant public URLs, with built-in multi-user support, S3-compatible storage, and optional background removal.

  • React 19
  • Vite
  • Hono
  • Node.js
  • TypeScript
  • Tailwind CSS 4
  • SQLite
  • Drizzle ORM
  • Garage S3
  • Docker
  • Better Auth
  • Cloudflare
View buildGitHub
ToolActiveClosed source

Home Cloud

Home Cloud is a self-hosted personal cloud for storing, browsing, uploading, and streaming photos and videos from a local drive. It splits the system into a Payload CMS control plane, a React/Vite frontend, and a Go fileserver for chunked uploads and media delivery.

  • Payload CMS 3
  • Next.js 16
  • React 19
  • Vite 8
  • TypeScript
  • Go 1.22
  • PostgreSQL
  • Docker Compose
  • pnpm
  • Tailwind CSS
  • HTTP Range Requests
  • Short-lived signed URLs
View build
ToolActiveOpen source

incognito.pics

incognito.pics is a client-side image privacy tool for stripping C2PA, EXIF, and XMP metadata from images. It also includes an EXIF editor for viewing and changing common camera and author fields without uploading the image to a server.

  • React 19
  • Vite
  • Tailwind CSS 4
  • shadcn/ui
  • HTML5 Canvas API
  • piexifjs
  • Vitest
  • c2patool
  • sharp
View buildLive demo
Build with Matija logo

Build with Matija

Modern websites, content systems, and AI workflows built for long-term growth.

Services

  • Headless CMS Websites
  • Next.js & Headless CMS Advisory
  • AI Systems & Automation
  • Website & Content Audit

Resources

  • Case Studies
  • How I Work
  • Blog
  • Topics
  • CMS Hub
  • E-commerce Hub
  • B2B Website Strategy
  • Dashboard

Headless CMS

  • Payload CMS Developer
  • CMS Migration
  • Multi-Tenant CMS
  • Payload vs Sanity
  • Payload vs WordPress
  • Payload vs Contentful

Get in Touch

Ready to modernize your stack? Let's talk about what you're building.

Book a discovery callContact me →
© 2026Build with Matija•All rights reserved•Privacy Policy•Terms of Service
BuildWithMatija
Get In Touch