FormidableLabs/spectacle
A React-based library for creating sleek presentations using JSX syntax that gives you the ability to live demo your code.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓25+ active contributors
- ✓Distributed ownership (top contributor 22% of recent commits)
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/formidablelabs/spectacle)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/formidablelabs/spectacle on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: FormidableLabs/spectacle
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/FormidableLabs/spectacle shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across the board
- Last commit 3w ago
- 25+ active contributors
- Distributed ownership (top contributor 22% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live FormidableLabs/spectacle
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/FormidableLabs/spectacle.
What it runs against: a local clone of FormidableLabs/spectacle — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in FormidableLabs/spectacle | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 54 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of FormidableLabs/spectacle. If you don't
# have one yet, run these first:
#
# git clone https://github.com/FormidableLabs/spectacle.git
# cd spectacle
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of FormidableLabs/spectacle and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "FormidableLabs/spectacle(\\.git)?\\b" \\
&& ok "origin remote is FormidableLabs/spectacle" \\
|| miss "origin remote is not FormidableLabs/spectacle (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "packages/spectacle/package.json" \\
&& ok "packages/spectacle/package.json" \\
|| miss "missing critical file: packages/spectacle/package.json"
test -f "packages/spectacle/src" \\
&& ok "packages/spectacle/src" \\
|| miss "missing critical file: packages/spectacle/src"
test -f "packages/create-spectacle/src/cli.ts" \\
&& ok "packages/create-spectacle/src/cli.ts" \\
|| miss "missing critical file: packages/create-spectacle/src/cli.ts"
test -f "packages/spectacle-mdx-loader/src/index.js" \\
&& ok "packages/spectacle-mdx-loader/src/index.js" \\
|| miss "missing critical file: packages/spectacle-mdx-loader/src/index.js"
test -f "package.json" \\
&& ok "package.json" \\
|| miss "missing critical file: package.json"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 54 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~24d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/FormidableLabs/spectacle"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
Spectacle is a React-based presentation library that lets developers write slides in JSX (or Markdown/MDX) and deliver live code demos within presentations. It compiles to a self-contained web app, enabling seamless live coding demos alongside traditional presentation content. Monorepo structure: packages/spectacle/ contains the core React presentation engine, examples/ has three runnable demo patterns (js/, md/, mdx/) showing JSX, Markdown, and MDX input modes. Build system uses Babel for transpilation (.babelrc.js, .babelrc.build.js) and Webpack for bundling. Styling via SCSS (35KB) for theming.
Who it's for
Frontend developers and technical presenters who want to build interactive, code-heavy presentations without leaving the React ecosystem. Users value JSX syntax, live demo capability, and the ability to version-control slides as code.
Maturity & risk
Production-ready and actively maintained by Formidable Labs. The monorepo structure, comprehensive CI/CD pipelines (.github/workflows/), and TypeScript-first codebase (258KB) indicate maturity. Active maintenance status badge and recent tooling (wireit, pnpm) suggest ongoing development without stagnation.
Standard open source risks apply.
Active areas of work
Active development with changesets-based versioning (.changeset/config.json) and automated release workflows (release.yml). CI runs on every push (ci.yml). The three examples directories indicate ongoing focus on supporting multiple authoring formats (JSX/Markdown/MDX). No specific data on open PRs, but the create-spectacle.yml workflow suggests tooling expansion.
Get running
git clone https://github.com/FormidableLabs/spectacle.git
cd spectacle
pnpm install
cd examples/js
pnpm run start
This starts the webpack-dev-server on port 3000 with hot reload. See examples/js/webpack.config.js for bundler config.
Daily commands:
For the JS example: cd examples/js && pnpm run start (webpack-dev-server on :3000, hot reload enabled). For building: pnpm run build triggers wireit, which runs nps webpack and depends on packages/spectacle:build:lib. For linting: pnpm run lint (ESLint-based via nps).
Map of the codebase
packages/spectacle/package.json— Core library package definition and dependency tree for the React presentation engine.packages/spectacle/src— Source directory containing all core Spectacle component implementations, hooks, and utilities that power the presentation library.packages/create-spectacle/src/cli.ts— CLI entry point for the create-spectacle scaffolding tool; defines how new presentations are generated.packages/spectacle-mdx-loader/src/index.js— Webpack loader that transforms MDX slide definitions into Spectacle-compatible React components.package.json— Monorepo root configuration managing all three packages and shared build/lint workflows via wireit..github/workflows/ci.yml— CI/CD pipeline orchestrating test, lint, and build steps across the entire monorepo on every commit.docs/index.mdx— Primary documentation entry point covering Spectacle's architecture, API, and usage patterns.
How to make changes
Create a New Custom Slide Component
- Create a new React component file in packages/spectacle/src with proper TypeScript types and styled-components styling. (
packages/spectacle/src/[ComponentName].tsx) - Export the component from the main index file to make it available to users. (
packages/spectacle/src/index.ts) - Add unit tests for the new component using Jest. (
packages/spectacle/src/[ComponentName].test.tsx) - Document the component API and usage example in the docs. (
docs/api-reference.md)
Generate a New Example Project
- Create a new example directory under examples/ with your desired flavor (js, mdx, typescript, etc). (
examples/[example-name]/package.json) - Set up webpack configuration for local development and building. (
examples/[example-name]/webpack.config.js) - Add .babelrc for JSX/React transpilation. (
examples/[example-name]/.babelrc) - Create index.html entry point and index.js/jsx/tsx main file with your presentation. (
examples/[example-name]/index.html) - Add start and build scripts to package.json; add to root package.json if needed for CI. (
package.json)
Add Support for a New Content Format (Custom Loader)
- Create a new loader package under packages/spectacle-[format]-loader following the pattern of spectacle-mdx-loader. (
packages/spectacle-[format]-loader/src/index.js) - Implement the loader to parse your format and return Spectacle slide components. (
packages/spectacle-[format]-loader/src/helpers.js) - Add package.json with proper entry point and peer dependencies on spectacle. (
packages/spectacle-[format]-loader/package.json) - Create an example project demonstrating the new format loader. (
examples/[format]/webpack.config.js)
Add a New Theme
- Create a new theme object following Spectacle's theme interface (colors, fonts, sizes) in packages/spectacle/src/theme. (
packages/spectacle/src/theme/[ThemeName].ts) - Export the theme from the theme index for easy importing. (
packages/spectacle/src/theme/index.ts) - Create an example presentation using your new theme. (
examples/themes/[theme-name].jsx) - Document the theme in the themes guide with screenshots and customization options. (
docs/themes.md)
Why these technologies
- React 18 — Core UI framework enabling component-based slide authoring with hooks, context, and modern React features.
- styled-components — CSS-in-JS library providing scoped, dynamic styling with theme context propagation across slide components.
- framer-motion — Animation library for smooth slide transitions, entrance animations, and interactive presentation controls.
- Webpack & Babel — Build toolchain for transpiling JSX/TypeScript and bundling presentations for both development and production.
- TypeScript — Provides type safety and IDE autocompletion for core library and scaffold-generated projects.
- MDX — Enables mixing Markdown content with React components, lowering barrier to entry for non-React developers.
- Changesets + GitHub Actions — Automated versioning and npm publishing workflow for the monorepo's three independent packages.
Trade-offs already made
-
Monorepo structure with three separate npm packages
- Why: Allows independent versioning of core library, CLI scaffolding tool, and MDX loader while sharing infrastructure.
- Consequence: Requires careful dependency management and coordinated releases; adds complexity to local development setup.
-
styled-components over CSS Modules or plain CSS
- Why: Enables dynamic theme switching at runtime and automatic theme prop injection to all components.
- Consequence: Larger JavaScript bundle; styled-components must be present in user applications; CSS-in-JS debugging less familiar to some.
-
MDX as primary content authoring format
- Why: Lower friction for non-React developers while still allowing React components and interactivity.
- Consequence: Requires webpack loader setup; adds build-time complexity; less suitable for static pre-compiled presentations.
-
Webpack-based scaffolding with optional TypeScript
- Why: Familiar to React ecosystem; supports both JSX and MDX out of the box.
- Consequence: Does not support Vite or other bundlers in generated projects without manual reconfiguration.
Non-goals (don't propose these)
- Does not support offline/static HTML export (presentations require React runtime).
- Does not handle real-time collaborative editing or presenter-audience synchronization.
Traps & gotchas
Monorepo uses pnpm (not npm/yarn)—ensure pnpm is installed (check .npmrc for specifics). Wireit orchestration means dependencies between packages are explicit in wireit configs; running examples/js requires packages/spectacle:build:lib to complete first. Two separate Babel configs (.babelrc.js for dev, .babelrc.build.js for distribution) can cause confusion if modifying transpilation. Hot reload in examples works via webpack-dev-server, not a custom dev server—teardown may require killing the port if interrupted.
Architecture
Concepts to learn
- JSX as presentation markup — Spectacle's core innovation—treating slide definitions as React components rather than JSON or HTML, enabling live code evaluation and dynamic content generation
- Monorepo orchestration with Wireit — Understanding wireit (used in package.json) is critical to running tasks across packages/spectacle and examples/ without manual dependency management
- Markdown + JSX interop (MDX) — Spectacle supports three authoring modes (JS, Markdown, MDX); MDX is the bridge allowing prose and React components in a single file
- Babel transpilation for JSX and modern JS — Two separate Babel configs (.babelrc.js vs .babelrc.build.js) handle dev-time and distribution-time transpilation differently; understanding this prevents build breakage
- Webpack hot module replacement — Examples use webpack-dev-server with HMR to enable live presentation editing without page reload—critical for the 'live demo' experience
- Changeset-based versioning (semantic release) — Release automation in this repo relies on .changeset/ files to track breaking changes and auto-increment version numbers; contributors must understand this workflow
- Theme composition via CSS/SCSS variables — Spectacle's theming model (35KB of SCSS) uses CSS custom properties for slide styling; understanding this enables custom theme creation without forking
Related repos
hakimel/reveal.js— Popular HTML/CSS-based presentation framework; Spectacle's main competitor but React-free and less code-focusedmaadhav/web-present— Similar React presentation library; alternative if you prefer a lighter-weight solution without JSX emphasismdx-js/mdx— Underlying MDX syntax and transpilation engine that Spectacle wraps for Markdown + React slide authoringFormidableLabs/prism-react-renderer— Companion library by same org for syntax highlighting in live code demos—commonly used within Spectacle presentationsvercel/swr— Formidable Labs often uses this for data fetching in interactive demos; common pairing with Spectacle for live-coding examples
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for create-spectacle CLI package
The create-spectacle package (packages/create-spectacle/) lacks visible test coverage. Given it's a critical tool for scaffolding new projects, unit tests for CLI argument parsing, template generation, and file creation would prevent regressions and improve maintainability.
- [ ] Examine packages/create-spectacle/ structure to identify core modules needing tests
- [ ] Create test suite covering CLI entry point, template copying logic, and configuration generation
- [ ] Ensure tests validate all example templates (js, md, mdx, typescript) are correctly scaffolded
- [ ] Add test coverage reporting to CI pipeline (ci.yml already exists, extend it)
Document and add examples for Spectacle theming API gaps
docs/themes.md exists but based on the example packages using different setups, there appear to be undocumented theming patterns. Creating a comprehensive theming guide with TypeScript examples would reduce contributor confusion and improve adoption.
- [ ] Review examples/typescript, examples/mdx, and examples/js for actual theming implementations
- [ ] Document the complete theme object shape and all overridable properties in docs/themes.md
- [ ] Create a TypeScript-based theming example in examples/typescript/ showcasing custom theme creation
- [ ] Add inline JSDoc comments to the main theme-related exports in packages/spectacle/
Add pre-commit linting and format validation workflow
The repo has eslint, prettier, and wireit configurations, but no pre-commit hook or GitHub Action validating format on push. This prevents contributors from merging code that fails linting, reducing maintainer review burden.
- [ ] Create .husky/pre-commit configuration to run pnpm run lint:fix && pnpm run prettier:fix
- [ ] Add husky setup documentation to CONTRIBUTING.md with install instructions
- [ ] Verify existing .github/workflows/ci.yml includes full lint/prettier checks before merge
- [ ] Test the pre-commit setup locally across monorepo packages
Good first issues
- Add TypeScript types to the mocks/use-resize-observer.js file—currently a plain JS mock, could benefit from .d.ts declarations for IDE support in tests
- Expand docs/api-reference.md with live code examples for each component (JSX snippets)—similar to the existing markdown layouts docs but for React API
- Create a 'custom theme' example in examples/ showing how to override SCSS variables and extend the default theme—currently no dedicated example for theming
Top contributors
- @github-actions[bot] — 22 commits
- @carloskelly13 — 22 commits
- @gksander — 9 commits
- @ryan-roemer — 8 commits
- @fritz-c — 7 commits
Recent commits
7cdefd5— Remove link to compromised styled-system.com domain (#1364) (Copilot)d79da7a— Version Packages (#1360) (github-actions[bot])9c2f940— Fix: Restore Heading component secondary color styling (regression in v10.2.2) (#1358) (Copilot)43a0d14— Version Packages (#1354) (github-actions[bot])5d95275— Bug(CI): Fix missing quotes in install (#1356) (ryan-roemer)0452103— Update OIDC and node versions (#1355) (ryan-roemer)ac05838— fix: resolve React 19 compatibility by replacing defaultProps with attrs (#1351) (umxr)c5d9242— Version Packages (#1353) (github-actions[bot])1e09087— Update animated-progress.tsx (#1352) (madaxen86)2c4627f— Fix one-page build + html and other misc. (#1349) (ryan-roemer)
Security observations
The Spectacle presentation library codebase demonstrates good security practices overall, with proper package management through pnpm and wireit build orchestration. However, there are moderate concerns around permissive dependency versioning in examples, development server exposure in the start script, and missing security documentation. The project would benefit from explicit security policies, stricter dependency pinning, and security headers configuration. No critical vulnerabilities like hardcoded secrets, SQL injection, or obvious credential exposure were identified in the provided file structure. The monorepo structure and CI/CD workflows appear well-organized with standard security practices.
- Medium · Permissive Dependency Version in Example Package —
examples/js/package.json. The example package uses 'spectacle': '' which allows any version including potentially unstable or vulnerable future releases. This could introduce security vulnerabilities without explicit version pinning. Fix: Replace '' with a specific version range like '^X.Y.Z' or use exact version pinning. Example: 'spectacle': '^7.0.0' - Medium · Webpack Dev Server with Hot Reload in Development —
examples/js/package.json (start script). The webpack-dev-server is configured with --hot flag on port 3000 without explicit security headers or HTTPS configuration. This could expose the development environment to unauthorized access or man-in-the-middle attacks. Fix: Ensure webpack-dev-server is only used in isolated development environments. For production-like environments, use proper HTTPS, authentication, and restrict network access. Consider using --https flag and firewall rules. - Low · Missing Package Lock Integrity Verification —
.github/workflows and package.json wireit config. The wireit configuration references 'pnpm-lock.yaml' for dependency tracking, but there's no evidence of lock file verification or signature validation in the CI/CD pipeline visibility provided. Fix: Ensure pnpm-lock.yaml is committed and verified in CI/CD pipelines. Add pnpm install --frozen-lockfile to CI scripts to prevent lock file tampering. - Low · No Explicit Security Policy Documentation —
Repository root. While a CONTRIBUTING.md exists, there is no visible SECURITY.md file for reporting security vulnerabilities responsibly, which is a best practice for open-source projects. Fix: Create a SECURITY.md file with responsible disclosure guidelines, security contact information, and vulnerability reporting process. See https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository - Low · No Content Security Policy Configuration Visible —
examples/js/index.html and other example entry points. As a React-based presentation library that executes JSX/code, there's no visible CSP headers or security configuration to mitigate XSS attacks if user-provided content is rendered. Fix: Add Content-Security-Policy headers to HTML files. If rendering user content, implement strict CSP rules and sanitization. Consider using libraries like DOMPurify for untrusted content.
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.