Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Marpit
https://github.com/marp-team/marpit
Admin
Marpit is a lightweight framework for converting Markdown and CSS themes into slide decks composed
...
Tokens:
19,904
Snippets:
169
Trust Score:
7.4
Update:
1 month ago
Context
Skills
Chat
Benchmark
89.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Marpit Marpit is a lightweight framework for creating slide decks from Markdown. It transforms Markdown content and CSS themes into static HTML and CSS that can be used as a logicless slide deck or converted to PDF by printing in a browser. The framework is designed to output minimal assets while providing powerful features like directives for slide configuration, image syntax extensions for backgrounds, and a clean CSS theming system. Marpit serves as the foundational converter in the Marp ecosystem and is built on markdown-it for parsing. It extends standard Markdown with directives (YAML-based configuration), slide backgrounds via image syntax, header/footer support, pagination, and inline SVG rendering for pixel-perfect scaling. The theming system allows pure CSS styling without predefined classes or mixins, making it straightforward for developers to create custom presentation themes. ## Marpit Class Constructor The main entry point for creating slide decks. Instantiate with options to configure Markdown parsing behavior, container elements, inline SVG mode, heading dividers, and more. ```javascript import { Marpit, Element } from '@marp-team/marpit' // Basic instance with default settings const marpit = new Marpit() // Full configuration with all options const customMarpit = new Marpit({ // Enable HTML tags and line breaks in Markdown markdown: { html: true, breaks: true, }, // Custom container elements for HTML output container: [ new Element('article', { id: 'presentation' }), new Element('div', { class: 'slides' }), ], // Wrap each slide in custom element slideContainer: new Element('div', { class: 'slide' }), // Enable experimental inline SVG mode for pixel-perfect scaling inlineSVG: true, // Auto-divide slides at heading level 2 or higher headingDivider: 2, // Enable CSS container query support cssContainerQuery: true, // Enable CSS nesting support cssNesting: true, // Make output printable to PDF printable: true, // Set default language attribute for slides lang: 'en', // Enable loose YAML parsing for directives looseYAML: false, // Custom anchor callback for slide IDs anchor: (index) => `slide-${index + 1}`, }) ``` ## Marpit.render() Method Renders Markdown content into HTML and CSS. Returns an object containing the rendered HTML string, CSS styles, and collected HTML comments (useful for presenter notes). ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() // Add a theme first marpit.themeSet.default = marpit.themeSet.add(` /* @theme presentation */ section { width: 1280px; height: 720px; font-size: 32px; padding: 40px; background: #1a1a2e; color: #eee; } h1 { color: #00d4ff; } `) const markdown = ` --- paginate: true header: 'My Presentation' --- # Welcome to Marpit This is the first slide with pagination enabled. <!-- This comment becomes a presenter note --> --- ## Second Slide - Bullet point 1 - Bullet point 2 <!-- Another presenter note for this slide --> --- ## Third Slide Final slide content here. ` // Render to HTML and CSS const { html, css, comments } = marpit.render(markdown) // html: '<div class="marpit"><section id="1">...</section>...</div>' // css: 'div.marpit { ... } section { ... }' // comments: [['This comment becomes a presenter note'], ['Another presenter note...'], []] // Create complete HTML document const document = ` <!DOCTYPE html> <html> <head> <style>${css}</style> </head> <body> ${html} </body> </html> ` ``` ## Render HTML as Array Output HTML as an array of strings, one per slide page. Useful for custom slide navigation or individual slide manipulation in applications. ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() const markdown = ` # Page 1 First slide content --- # Page 2 Second slide content --- # Page 3 Third slide content ` // Pass htmlAsArray option to get array output const { html, css, comments } = marpit.render(markdown, { htmlAsArray: true }) // html is now an array: // [ // '<section id="1">\n<h1>Page 1</h1>\n<p>First slide content</p>\n</section>\n', // '<section id="2">\n<h1>Page 2</h1>\n<p>Second slide content</p>\n</section>\n', // '<section id="3">\n<h1>Page 3</h1>\n<p>Third slide content</p>\n</section>\n' // ] // Use slides individually (still need container for CSS scoping) html.forEach((slideHtml, index) => { console.log(`Slide ${index + 1}:`, slideHtml) }) ``` ## ThemeSet.add() Method Adds a theme CSS string to the theme set. The CSS must include a `@theme` meta comment to specify the theme name. Returns a Theme instance. ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() // Add a complete theme with all styling const theme = marpit.themeSet.add(` /* @theme corporate */ section { width: 1280px; height: 720px; font-size: 28px; padding: 40px; background-color: #ffffff; color: #333333; } /* Style headings */ h1 { font-size: 48px; color: #0066cc; border-bottom: 2px solid #0066cc; } h2 { font-size: 36px; color: #004499; } /* Pagination styling */ section::after { content: 'Page ' attr(data-marpit-pagination) ' / ' attr(data-marpit-pagination-total); position: absolute; right: 40px; bottom: 30px; font-size: 16px; color: #666; } /* Header and footer positioning */ header, footer { position: absolute; left: 40px; right: 40px; height: 30px; font-size: 14px; color: #888; } header { top: 20px; } footer { bottom: 20px; } /* Lead slide class for title pages */ section.lead { display: flex; flex-direction: column; justify-content: center; text-align: center; background: linear-gradient(135deg, #0066cc, #004499); color: white; } section.lead h1 { color: white; border: none; } `) // Set as default theme marpit.themeSet.default = theme // Now use the theme const { html, css } = marpit.render(` <!-- _class: lead --> # Corporate Presentation --- ## Agenda - Topic 1 - Topic 2 `) ``` ## Theme Importing with @import Create customized themes based on existing themes using CSS @import or @import-theme rules. ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() // Add base theme first marpit.themeSet.add(` /* @theme base */ section { width: 1280px; height: 720px; font-size: 30px; padding: 40px; background: #fff; color: #333; } h1 { color: #333; font-size: 48px; } h2 { color: #555; font-size: 36px; } code { background: #f4f4f4; padding: 2px 8px; } `) // Create dark theme that imports base marpit.themeSet.add(` /* @theme dark */ @import 'base'; section { background: #1a1a2e; color: #eee; } h1 { color: #00d4ff; } h2 { color: #7dd3fc; } code { background: #2d2d44; color: #f8f8f2; } `) // Create colorful theme variant marpit.themeSet.add(` /* @theme colorful */ @import 'base'; section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; } h1, h2 { color: white; } `) // Use themes via directive const { css } = marpit.render(` <!-- theme: dark --> # Dark Theme Slide `) ``` ## ThemeSet Management Methods Methods for managing themes in the theme set: get, has, delete, clear, and iterate through themes. ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() // Add multiple themes marpit.themeSet.add('/* @theme light */ section { background: #fff; }') marpit.themeSet.add('/* @theme dark */ section { background: #222; }') marpit.themeSet.add('/* @theme blue */ section { background: #1e40af; }') // Check number of themes console.log(marpit.themeSet.size) // 3 // Check if theme exists console.log(marpit.themeSet.has('dark')) // true console.log(marpit.themeSet.has('unknown')) // false // Get theme instance const darkTheme = marpit.themeSet.get('dark') console.log(darkTheme.name) // 'dark' console.log(darkTheme.css) // '/* @theme dark */ section { background: #222; }' // Get theme with fallback to default/scaffold const theme = marpit.themeSet.get('nonexistent', true) // Returns default or scaffold // Get theme metadata const meta = marpit.themeSet.getThemeMeta('dark', 'theme') // 'dark' // Get theme property (e.g., width, height) const width = marpit.themeSet.getThemeProp('light', 'width') // Iterate through all themes for (const theme of marpit.themeSet.themes()) { console.log(`Theme: ${theme.name}`) } // Delete a specific theme marpit.themeSet.delete('blue') console.log(marpit.themeSet.size) // 2 // Clear all themes marpit.themeSet.clear() console.log(marpit.themeSet.size) // 0 ``` ## Custom Directives Define custom global and local directives to extend Marpit's functionality. Global directives apply to the entire deck, local directives apply per-slide. ```javascript import { Marpit } from '@marp-team/marpit' const marpit = new Marpit() // Custom global directive for presentation metadata marpit.customDirectives.global.author = (value, marpit) => { return { author: value } } marpit.customDirectives.global.date = (value, marpit) => { return { date: value } } // Custom local directive for color presets marpit.customDirectives.local.colorPreset = (value, marpit) => { const presets = { ocean: { backgroundColor: '#0077b6', color: '#caf0f8' }, sunset: { backgroundColor: '#e63946', color: '#f1faee' }, forest: { backgroundColor: '#2d6a4f', color: '#d8f3dc' }, midnight: { backgroundColor: '#1d3557', color: '#a8dadc' }, } return presets[value] || {} } // Custom local directive for text alignment marpit.customDirectives.local.align = (value, marpit) => { // Returns class to be applied to section const alignments = { center: 'text-center', right: 'text-right', left: 'text-left', } return alignments[value] ? { class: alignments[value] } : {} } // Add theme with preset support marpit.themeSet.default = marpit.themeSet.add(` /* @theme custom */ section { width: 1280px; height: 720px; padding: 40px; } section.text-center { text-align: center; } section.text-right { text-align: right; } `) // Use custom directives in Markdown const { html, css } = marpit.render(` --- author: John Doe date: 2024-01-15 --- <!-- colorPreset: ocean --> <!-- _align: center --> # Ocean Theme Slide Centered text with ocean colors --- <!-- _colorPreset: sunset --> # Sunset Slide This slide uses sunset colors (spot directive with underscore) --- # Back to Ocean Previous colorPreset continues `) ``` ## Marpit.use() Method Extend Marpit with markdown-it plugins, PostCSS plugins, or Marpit-specific plugins. Returns the Marpit instance for chaining. ```javascript import { Marpit } from '@marp-team/marpit' import markdownItEmoji from 'markdown-it-emoji' import markdownItContainer from 'markdown-it-container' const marpit = new Marpit() // Chain multiple plugins marpit // Add emoji support .use(markdownItEmoji) // Add custom containers for multi-column layouts .use(markdownItContainer, 'columns', { render: (tokens, idx) => { if (tokens[idx].nesting === 1) { return '<div class="columns">\n' } return '</div>\n' }, }) .use(markdownItContainer, 'column', { render: (tokens, idx) => { if (tokens[idx].nesting === 1) { return '<div class="column">\n' } return '</div>\n' }, }) // Add theme with column support marpit.themeSet.default = marpit.themeSet.add(` /* @theme with-columns */ section { width: 1280px; height: 720px; padding: 40px; } .columns { display: flex; gap: 20px; } .column { flex: 1; } `) // Use plugins in Markdown const { html, css } = marpit.render(` # Emojis Work! :rocket: :tada: --- # Multi-Column Layout ::: columns ::: column ## Left Column - Point 1 - Point 2 ::: ::: column ## Right Column - Point A - Point B ::: ::: `) ``` ## Marpit Plugin Factory Create Marpit-specific plugins that have access to the Marpit instance via `md.marpit`. Use the plugin factory from `@marp-team/marpit/plugin`. ```javascript import { Marpit } from '@marp-team/marpit' import { marpitPlugin } from '@marp-team/marpit/plugin' // Create a Marpit plugin with access to Marpit instance const slideCounterPlugin = marpitPlugin((md) => { const { marpit } = md // Add custom directive marpit.customDirectives.global.showSlideCount = (value) => { return { showSlideCount: value === 'true' || value === true } } // Extend renderer const originalRender = md.renderer.render.bind(md.renderer) md.renderer.render = (tokens, options, env) => { const result = originalRender(tokens, options, env) // Custom processing with access to marpit return result } }) // Plugin that adds a built-in theme const builtInThemePlugin = marpitPlugin((md) => { const { marpit } = md marpit.themeSet.add(` /* @theme plugin-theme */ section { width: 1280px; height: 720px; background: #2d3436; color: #dfe6e9; font-family: system-ui, sans-serif; } h1 { color: #74b9ff; } `) }) // Use plugins const marpit = new Marpit() .use(slideCounterPlugin) .use(builtInThemePlugin) const { html, css } = marpit.render(` <!-- theme: plugin-theme --> <!-- showSlideCount: true --> # Plugin-Provided Theme `) ``` ## Element Class for Container Customization Create custom HTML container elements for wrapping the slide deck or individual slides with specific attributes. ```javascript import { Marpit, Element } from '@marp-team/marpit' // Create instance with custom containers const marpit = new Marpit({ // Outer containers wrapping entire deck container: [ new Element('main', { id: 'app', role: 'main' }), new Element('div', { class: 'presentation-wrapper' }), ], // Container for each individual slide slideContainer: new Element('article', { class: 'slide-page' }), }) marpit.themeSet.default = marpit.themeSet.add(` /* @theme custom-container */ section { width: 1280px; height: 720px; padding: 40px; } `) const { html, css } = marpit.render(` # Slide 1 --- # Slide 2 `) // Output structure: // <main id="app" role="main"> // <div class="presentation-wrapper"> // <article class="slide-page"> // <section id="1"><h1>Slide 1</h1></section> // </article> // <article class="slide-page"> // <section id="2"><h1>Slide 2</h1></section> // </article> // </div> // </main> // Disable containers entirely const noContainerMarpit = new Marpit({ container: false, }) ``` ## Directives in Markdown Use YAML-based directives in HTML comments or front-matter to configure slides. Global directives affect all slides, local directives affect current and following slides, spot directives (underscore prefix) affect only current slide. ```markdown --- theme: default paginate: true header: 'Company Name' footer: '© 2024' headingDivider: 2 --- <!-- Global style directive --> <!-- style: | section { font-family: 'Arial', sans-serif; } section.title { background: navy; color: white; } --> <!-- _class: title --> # Main Presentation Title Subtitle goes here --- ## First Section <!-- backgroundColor: #f5f5f5 --> Regular content with light background --- ## Still Light Background Local directives persist across slides --- <!-- _backgroundColor: #1a1a2e --> <!-- _color: white --> ## Dark Slide (Spot Directive) Only this slide is dark (underscore prefix) --- ## Back to Light The spot directive only affected the previous slide --- <!-- paginate: hold --> ## Appendix This slide shows page number but doesn't increment counter --- <!-- paginate: skip --> ## Hidden from Count This slide is hidden from pagination entirely ``` ## Image Syntax Extensions Extended Markdown image syntax for backgrounds, resizing, and filters. Use keywords in the alt text to control image behavior. ```markdown # Inline Image Resizing    --- # Image Filters     --- # Slide Background  Content appears over the background --- # Background Size Options  Use 'cover' (default), 'contain', 'fit', 'auto', or percentage --- # Background with Color  Solid color background using hex --- <!-- Inline SVG mode required for advanced backgrounds --> # Multiple Backgrounds    Images arrange horizontally --- # Vertical Multiple Backgrounds    --- # Split Background Left  Content on the right side --- # Split Background Right with Size  Content takes 60% on the left ``` ## Complete Application Example A full example showing Marpit used to build a presentation generator with themes, plugins, and custom features. ```javascript import { Marpit, Element } from '@marp-team/marpit' import { marpitPlugin } from '@marp-team/marpit/plugin' import fs from 'fs' // Custom plugin for auto-generated table of contents const tocPlugin = marpitPlugin((md) => { md.marpit.customDirectives.global.toc = (value) => { return { generateToc: value === 'true' } } }) // Initialize Marpit with full configuration const marpit = new Marpit({ markdown: { html: true, breaks: true }, inlineSVG: true, // Enable advanced backgrounds headingDivider: false, cssContainerQuery: true, }) .use(tocPlugin) // Add comprehensive theme marpit.themeSet.default = marpit.themeSet.add(` /* @theme professional */ :root { --primary: #2563eb; --secondary: #1e40af; --background: #ffffff; --text: #1f2937; --muted: #6b7280; } section { width: 1280px; height: 720px; padding: 60px; background: var(--background); color: var(--text); font-family: 'Inter', system-ui, sans-serif; font-size: 28px; line-height: 1.6; } h1 { font-size: 56px; color: var(--primary); margin-bottom: 20px; } h2 { font-size: 42px; color: var(--secondary); } code { background: #f3f4f6; padding: 4px 8px; border-radius: 4px; font-size: 0.9em; } pre { background: #1f2937; color: #f9fafb; padding: 20px; border-radius: 8px; overflow-x: auto; } pre code { background: none; padding: 0; } section::after { content: attr(data-marpit-pagination) ' / ' attr(data-marpit-pagination-total); position: absolute; right: 60px; bottom: 40px; font-size: 16px; color: var(--muted); } header { position: absolute; top: 30px; left: 60px; right: 60px; font-size: 14px; color: var(--muted); } footer { position: absolute; bottom: 30px; left: 60px; font-size: 14px; color: var(--muted); } /* Title slide variant */ section.title { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; } section.title h1 { color: white; font-size: 64px; } section.title p { font-size: 24px; opacity: 0.9; } /* Two column layout */ section.columns { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; } `) // Sample presentation content const presentation = ` --- paginate: true header: 'Technical Workshop' footer: 'Confidential' --- <!-- _class: title --> <!-- _paginate: skip --> # Building Modern Applications A comprehensive guide to software architecture *Workshop 2024* --- ## Agenda 1. Introduction to Architecture Patterns 2. Hands-on Implementation 3. Best Practices & Code Review 4. Q&A Session --- ## Key Concepts <!-- _class: columns --> ### Design Patterns - Singleton - Factory - Observer - Strategy ### Architecture Styles - Microservices - Event-Driven - Serverless - Monolithic --- ## Code Example \`\`\`javascript class UserService { constructor(repository) { this.repository = repository; } async createUser(data) { const user = new User(data); return this.repository.save(user); } } \`\`\` ---  ## Visual Architecture The diagram shows our system components: - **API Gateway**: Entry point - **Services**: Business logic - **Database**: Data persistence --- <!-- _backgroundColor: #1f2937 --> <!-- _color: #f9fafb --> ## Questions? Contact: team@example.com <!-- This is a presenter note: Remember to ask for questions --> ` // Render presentation const { html, css, comments } = marpit.render(presentation) // Generate complete HTML file const htmlDocument = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Technical Workshop</title> <style>${css}</style> </head> <body> ${html} </body> </html>` // Write to file fs.writeFileSync('presentation.html', htmlDocument) // Export presenter notes const notes = comments .map((slideNotes, i) => `Slide ${i + 1}:\n${slideNotes.join('\n')}`) .filter((n) => n.includes('\n')) .join('\n\n') fs.writeFileSync('presenter-notes.txt', notes) console.log('Presentation generated successfully!') ``` ## Summary Marpit is ideal for developers building presentation tools, documentation systems, or any application requiring Markdown-to-slides conversion. The framework excels in scenarios where minimal output size matters, such as embedding presentations in web applications, generating printable PDFs, or creating slide-based content management systems. Its markdown-it foundation ensures compatibility with the broader Markdown ecosystem while the PostCSS-based theming allows sophisticated CSS processing. Integration patterns typically involve creating a Marpit instance, registering custom themes via `themeSet.add()`, optionally extending functionality with plugins via `use()`, and rendering Markdown with `render()`. For applications requiring fine-grained control, custom directives provide a powerful extension mechanism, while the `htmlAsArray` option enables per-slide manipulation. The framework's pure HTML/CSS output makes it framework-agnostic, working seamlessly with React, Vue, vanilla JavaScript, or server-side rendering environments.