ReactJS based Presentation Library.

Getting Started

The new best way to get started is by running create-react-app my-presentation --scripts-version spectacle-scripts. This will use create-react-app to create almost everything you need. This however, doesn't include publish scripts, and ejecting is required for fancy stuff.

The second best way to get started is by using the Spectacle Boilerplate.

Alternatively, you can npm install spectacle and write your own build configurations. We also provide full UMD builds (with a Spectacle global variable) of the library at dist/spectacle.js and dist/spectacle.min.js for more general use cases. You could, for example, include the library via a script tag with: https://unpkg.com/[email protected]/dist/spectacle.min.js.

Note that we have webpack externals for react, react-dom, and prop-types, so you will need to provide them in your upstream build or something like linking in via script tags in your HTML page for all three libraries. This comports with our project dependencies which place these three libraries in peerDependencies.

But really, it is SO much easier to just use the boilerplate. Trust me.

One Page

To aid with speedy development / kicking the tires on spectacle, we support using a simple boilerplate HTML page with a bespoke script tag that contains your entire presentation. The rest of the setup will take care of transpiling your React/ESnext code, providing Spectacle, React, and ReactDOM libraries, and being raring to go with a minimum of effort.

We can start with this project's sample at one-page.html. It's essentially, the same presentation as the fully-built-from-source version, with a few notable exceptions:

  1. There are no imports or requires. Everything must come from the global namespace. This includes Spectacle, React, ReactDOM and all the Spectacle exports from ./src/index.js -- Deck, Slide, themes, etc.

  2. The presentation must include exactly one script tag with the type text/spectacle that is a function. Presently, that function is directly inserted inline into a wrapper code boilerplate as a React Component render function. The wrapper is transpiled. There should not be any extraneous content around it like outer variables or comments.

    Good examples:

    <script type="text/spectacle">
      () => (
        <Deck>{/* SLIDES */}</Deck>
    <script type="text/spectacle">
      () => {
        // Code-y code stuff in JS...
        return (
          <Deck>{/* SLIDES */}</Deck>

    Bad examples of what not to do:

    <script type="text/spectacle">
      // Outer comment (BAD)
      const outerVariable = "BAD";
      () => (
        <Deck>{/* SLIDES */}</Deck>

... with those guidelines in mind, here's the boilerplate that you can literally copy-and-paste into an HTML file and start a Spectacle presentation that works from the get go!

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width initial-scale=1 user-scalable=no" />
    <link href="https://fonts.googleapis.com/css?family=Lobster+Two:400,700" rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,700" rel="stylesheet" type="text/css">
    <link href="https://unpkg.com/[email protected]/normalize.css" rel="stylesheet" type="text/css">
    <div id="root"></div>
    <script src="https://unpkg.com/[email protected]/prop-types.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.js"></script>
    <script src="https://unpkg.com/[email protected]^4/dist/spectacle.js"></script>
    <script src="https://unpkg.com/[email protected]^4/lib/one-page.js"></script>
    <script type="text/spectacle">
      () => {
        // Your JS Code goes here

        return (
          {/* Throw in some slides here! */}


After downloading the boilerplate, your first order of business is to open terminal and run npm install

Next run rm -R .git to remove the existing version control.

Then, to start up the local server, run npm start

Open a browser and hit http://localhost:3000, and we are ready to roll

Build & Deployment

Building the dist version of the slides is as easy as running npm run build:dist

If you want to deploy the slideshow to surge, run npm run deploy

⚠️ If you are deploying the dist version to GitHub Pages, note that the built bundle uses an absolute path to the /dist/ directory while GitHub Pages requires the relative ./dist/ to find any embedded assets and/or images. A very hacky way to fix this is to edit one place in the produced bundle, as shown in this GitHub issue.


Spectacle comes with a built in presenter mode. It shows you a slide lookahead, current time and your current slide:


Otherwise, it can also show you a stopwatch to count the elapsed time:


To present:

Note: Any windows/tabs in the same browser that are running Spectacle will sync to one another, even if you don't want to use presentation mode

Check it out:


You can toggle the presenter or overview mode by pressing respectively alt+p and alt+o.


Key Combination Function
Right Arrow Next Slide
Left Arrow Previous Slide
Space Next Slide
Shift+Space Previous Slide
Alt/Option + O Toggle Overview Mode
Alt/Option + P Toggle Presenter Mode
Alt/Option + T Toggle Timer in Presenter Mode
Alt/Option + A Start autoplay (if enabled)


Fullscreen can be toggled via browser options, or by hovering over the bottom right corner of your window until the fullscreen icon appears and clicking it.

PDF Export

Exporting a totally sweet looking PDF from your totally sweet looking Spectacle presentation is absurdly easy. You can either do this via the browser, or from the command line:


  • Run npm install spectacle-renderer -g
  • Run npm start on your project and wait for it to build and be available
  • Run spectacle-renderer
  • A totally cool PDF is created in your project directory

For more options and configuration of this tool, check out:



  • Run npm start
  • Open http://localhost:3000/
  • Add export& after the ? on the URL of page you are redirected to, e.g.: http://localhost:3000/#/?export&_k=wbyhif
  • Bring up the print dialog (ctrl or cmd + p)
  • Check "Background Graphics" to on if you are about that life
  • Change destination to "Save as PDF", as shown below:


If you want to print your slides, and want a printer friendly version, simply repeat the above process but instead print from http://localhost:3000/?export&print

Basic Concepts

Main file

Your presentation files & assets will live in the presentation folder.

The main .js file you write your deck in is /presentation/index.js

Check it out here in the boilerplate.

// index.js

import React, { Component } from 'react';
import {
  Appear, BlockQuote, Cite, CodePane, Code, Deck, Fill, Fit,
  Heading, Image, Layout, ListItem, List, Quote, Slide, Text
} from 'spectacle';

export default class extends Component {
  render() {
    return (

Here is where you can use the library's tags to compose your presentation. While you can use any JSX syntax here, building your presentation with the supplied tags allows for theming to work properly.

The bare minimum you need to start is a Deck element and a Slide element. Each Slide element represents a slide inside of your slideshow.


In Spectacle, themes are functions that return style objects for screen & print.

You can import the default theme from:

import createTheme from "spectacle/lib/themes/default";

Or create your own based upon the source.

index.js is what you would edit in order to create a custom theme of your own, using object based styles.

You will want to edit index.html to include any web fonts or additional CSS that your theme requires.

createTheme(colors, fonts)

Spectacle's functional theme system allows you to pass in color and font variables that you can use on your elements. The fonts configuration object can take a string for a system font or an object that specifies it‘s a Google Font. If you use a Google Font you can provide a styles array for loading different weights and variations. Google Font tags will be automatically created. See the example below:

const theme = createTheme({
  primary: "red",
  secondary: "blue"
}, {
  primary: "Helvetica",
  secondary: { name: "Droid Serif", googleFont: true, styles: [ "400", "700i" ] }

The returned theme object can then be passed to the Deck tag via the theme prop, and will override the default styles.