Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Hacker's Tiny Slide Deck (HTSD)

npm version CI

Turn a Markdown document into a slide deck, in two steps:

  1. Add a <script> tag referring the HTSD JavaScript bundle to the end of the Markdown document. For example, accessing the bundle from jsDelivr service:

    <script type="text/javascript" src=""></script>

    (Replace VERSION with the version of this npm package.)

  2. Convert the Markdown document into html. For example, using marked:

    marked -i > example.html

This might be the preferable option for preparing a quick presentation.

Use an editor plugin to make step 2 easier, preferably via a keyboard shortcut. For example, markdown-mode for Emacs has the markdown-export-and-preview (C-c C-c v) command, which converts the .md file in the current buffer to a .html file and opens the html in the default browser.

To demonstrate the features quickly, see the sources of and the converted html.


  • Responsive CSS, with automatically scaling text size.
  • You can still adjust text size with the browser's zoom function.
  • Keyboard shortcuts to change slides:
    • ⬅️ (left arrow) to show the previous slide
    • ➡️ (right arrow) to show the next slide
    • Home to show the first slide
    • End to show the last slide
  • Keyboard shortcut to toggle fullscreen, Shift+F.
  • Swipe left and right gestures to change slides on mobile browsers.
  • Built for modern browsers (no support for old browsers).
  • Support browser history, remember current slide shown on reload.
  • Easy slide specific CSS styles with id attributes generated from headers.
  • Intentionally kept simple to allow easy hacking and customization. If you don't like something, download the source code and change it.
  • Tiny, currently 12 KiB in size (bundled, minified, not compressed).
  • Printing the html document is unaffected; CSS styles are for screen media only.
  • Might be one of the fastest ways to prepare a slide deck!


Prepare a Markdown document, with a <script> tag referring htsd.min.js:

# Title

I'm the first slide.


## Topic 1

I'm the second slide.


# End

Thank you!

<script type="text/javascript" src=""></script>

Where VERSION in the <script>'s src attribute refers to a version of this npm package.)

Convert the .md file prepared above to .html. Here, using marked:

marked -i > example.html

Conventions to turn Markdown into slides

This section lists the special conventions to turn the content of html generated from a Markdown document into slides.

Horizontal separators (<hr>) separate slides

## Slide 1


## Slide 2

The contents of each slide get wrapped in a <div> tag, with style class htsd-slide. Every slide will have that as the base class. In addition, slides may have additional modifier classes and id attributes; read below for more.

You can utilize the base class (htsd-slide) for styling global to all slides.

Modifier class for the highest level header in a slide

# Title

## Topic 1

I'm centered.


## Topic 2

I'm not centered.

Here, the slide with <h1>Title</h1> will have the htsd-slide--h1 modifier class in addition to the htsd-slide base class. HTSD includes CSS styles to center the content having the htsd-slide--h1 class.

The slide with <h2>Topic 2</h2> gets htsd-slide--h2 as the modifier class. HTSD has no special CSS styles for header levels below level 2, but you can add them yourself.

Id attribute for the highest level header in a slide

The text contents of the highest level header in each slide is used to generate the id attributes for them. You can use this in the CSS selectors to customize styles (see


Customize styles

Use a <style media="screen"> tag to customize styles. There are custom CSS properties to help your tuning needs:

@import url(,400i,700);

/* override css custom properties */
:root {
  --htsd-sans-font-family: 'Roboto', sans-serif;
  --htsd-slide-bg-color: #f6f6f6;
  --htsd-header-color: #262626;
  --htsd-text-color: #1a1a1a;

/* override rules with selectors */
.htsd-slide em {
  font-weight: bold;

See the end of for more examples.

Syntax highlighting inside <code> tags

You can enable syntax highlighting inside <code> tags with an external JavaScript library, such as Prism.js.

See the end of to see how to highlight code with Prism.js.

Install HTSD manually

By default, loading htsd.min.js with the <script> tag automatically installs all features. If you want to install features manually, use the data-manual attribute in the <script> tag. For example:

<script type="text/javascript" src="" data-manual></script>

HTSD provides the following object in window:

window.htsd = {
  // calls, in order:
  // 1. installStyles
  // 2. installSlides
  // 3. installNavigation
  // 4. markInstalled
  installAll: () => undefined,

  // apply CSS styles by injecting a <style> tag into <head>;
  // this will make <body> invisible (the document goes blank)
  installStyles: () => undefined,

  // wrap content into <div class="htsd-slide"> tags, to be used as slides
  installSlides: () => undefined,

  // 1. enable handling the hash part of browser location
  // 2. show the selected slide (requires <body> to be visible, see `markInstalled`)
  // 3. make keyboard shortcuts and swipe gestures available
  installNavigation: () => undefined,

  // add `htsd--installed` class to the <body> tag, make <body> visible
  markInstalled: () => undefined

  // contains HTSD version number
  version: string

Now, you can call installAll manually:

<script type="text/javascript">htsd.installAll()</script>

Calling the install* or markInstalled functions more than once leads to undefined behavior. The implementation is simpler without attempting to handle the complexities in different call combinations.