General-purpose Lume theme based on Tufte CSS.
- Styling with Tufte CSS: Uses a modified version of Tufte CSS, a popular CSS micro-framework created in 2014 by David Liepmann based on the work of Edward Tufte. Its wide margins and beautiful serif typography create a clean, sophisticated aesthetic.
- Expressive Syntax: Includes several plugins that extend standard Markdown
syntax for things like sidenotes, complex math blocks,
<figcaption>tags, and more, all without writing a single line of HTML. See the Syntax section for more information. - LumeCMS Integration: Features a comprehensive
_cms.tsfile that allows for no-code content management of the entire site using LumeCMS. - Perfect Lighthouse Scores: Earns perfect 100s in performance, accessibility, best practices, and SEO on Lighthouse.
Tip
This quickstart is for creating your own Lume site using the Tufte theme. If you just want to check out the theme, visit the live demo.
Prerequisite: make sure to install Deno if you haven't already. I'm using Deno 2.8.1, but it'll probably work on other versions.
deno run -A https://lume.land/init.ts --theme=tufte
deno task serveUnder the hood, the Tufte theme is a Lume plugin that automatically loads a bunch of plugins, layouts, components, and stylesheets.
When you install the Tufte theme, you won't see any of its internal files in
your site. This is because the theme internals are loaded as
remote files via Lume's
site.remote() API. This keeps your site's repo clean while still making the
necessary theme files available to Lume.
Tip
Because local files take precedence over remote files, you can override the theme internal files by creating an identically-named file in the same location, if you were so inclined.
Tufte uses 12 Lume plugins and 6 markdown-it plugins to add syntax, optimize performance, and handle internal theme logic.
Syntax plugins
These plugins add syntax that you can use when writing page content. See the Syntax section for a guide.
- katex: renders math blocks.
- nueglow: highlights code blocks.
- markdown: already installed by default, but we need to explicitly add it in order to add our own markdown-it plugins.
- markdown-it-anchor:
adds
idattributes to headings so that you can use URI fragments. - markdown-it-collapsible: adds syntax for collapsibles.
- markdown-it-toc-done-right: adds syntax for tables of content.
- markdown-it-smart-media: adds syntax for videos, audio, and figcaptions.
- markdown-it-tufte-sections: custom plugin that
automatically wraps page content in
<section>tags based on headings, as Tufte CSS requires. - markdown-it-tufte-notes: custom plugin that adds syntax for Tufte-style sidenotes and margin notes.
Optimization/SEO plugins
These plugins are used to make pages load faster, improve SEO, or other invisible-but-important things. 100s in every category on Lighthouse doesn't just happen, you know.
- imageSize: adds
widthandheightattributes to images to prevent layout shifts on page load. - sitemap: generates the sitemap.
- feed: generates the RSS feed.
- favicon: optimizes the favicon and converts it to different formats.
- Though it's not a plugin, the
fontPreloads.vtocomponent definitely fits in this category. It selectively preloads only the font files that each page uses. This prevents FOUT without adding unused global preloads.
Internal plugins
These plugins are used to make other parts of the theme work.
- sass: transpiles the SCSS stylesheets into browser-consumable CSS files.
- basePath: prefixes relative URLs (e.g.
/about) with a subpath, which allows the site to be deployed on services like GitHub Pages. - metas: adds
<meta>tags to the<head>of each page for things like titles, descriptions, and the favicon. - readingInfo: counts the words of each page, which is used in the blogList component's post info.
- search: allows layouts to query and filter pages, which is used in the blogList component to list the posts.
A more in-depth guide to the Tufte theme's syntax is available here.
Sidenotes are like GFM footnotes, but they're inline and the numbering is automatic. Just put the sidenote text inside a pair of square brackets with a caret immediately following the left bracket.
Example:
This is my[^"my", in this case, referring to me.] paragraph text.Result:
Margin notes are like sidenotes but without numbers. The syntax is the same but with an asterisk after the caret.
Example:
I am the very model of a modern major general.[^*No idea why I picked this as the example.]Result:
Subtitles are text that is italic and has a large font size. You can turn any
paragraph text into a subtitle by adding {.subtitle} to the end of the line.
Example:
Written by A Bunch of Bees {.subtitle}Result:
Math is rendered using KaTeX, which uses the same syntax as TeX. A list of KaTeX
syntax is available here. You can start a
math block by using the math language in a code block.
Example:
```math
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
```Result:
<figcaption> tags are added using
image title syntax.
Just add quotes after the source URI.
Example:
Result:
On wide screens, the main content only occupies 55% of the screen width. To make
an element take up more space, add {.fullwidth} to the end of the line.
Example:
 {.fullwidth}Result:
To use
Tufte CSS epigraphs, add
{.epigraph} to the end of a blockquote and add {.quotecite} to the next
paragraph text.
Example:
> On two occasions I have been asked by members of Parliament, 'Pray, Mr.
> Babbage, if you put into the machine wrong figures, will the right answers
> come out?' I am not able rightly to apprehend the kind of confusion of ideas
> that could provoke such a question. {.epigraph}
— Charles Babbage (inventor of the automatic calculator), 1864 {.quotecite}Result:
You can use Nueglow's special syntax for highlighting specific sequences and lines.
To highlight a section, surround it with single bullet markers (e.g. •important•). To underline a section, surround it with double bullet markers (e.g. ••mistake••). To highlight an entire line, begin it with a greater than sign (>). To render a diff, use plus signs (+) and minus signs (-) to start inserted and deleted lines, respectively.
Example:
```ts
interface User {
id: number;
name: string;
}
function greet(•user: User•): string {
> return `Hello, ${user.name}!`;
}
-const me: User = { id: 1, name: "Not Ethan" };
+const me: User = { id: 1, name: "Ethan" };
console.log(••greet{me}••);
```Result:
To add <details> tags, use the
markdown-it-collapsible
syntax. It’s very similar to the code block syntax, except you use plus signs
instead of backticks.
Example:
+++This is the summary
This is the collapsible content. You can put anything you want in here.
+++Result (shown in collapsed form and in expanded form):
To add a table of contents, use the syntax from
markdown-it-toc-done-right:
place any of ${toc}, [[toc]], [toc], or [[_toc_]] anywhere on a page and
the plugin will automatically replace it with a table of contents based on your
headings.
Example:
[toc]Result:
Here are all the sites that I'm aware of that use the Tufte theme. If your site uses the Tufte theme and you'd like it to be featured here, feel absolutely free to open a PR!
- Lume Tufte Theme Demo (obviously)
- Lume Nueglow Plugin Demo
- Thanks to David Liepmann and Edward Tufte for making tufte.css.
- Thanks to Óscar Otero for making the incredible SSG Lume and for making 11 of the 16 external plugins that the Tufte theme uses.
- Thanks to the respective authors of markdown-it-anchor, markdown-it-collapsible, and markdown-it-toc-done-right.
Everything else, including two of the external plugins (lume_nueglow and markdown-it-smart-media) and both of the internal mdit plugins (tufte-notes and tufte-sections), was made by me.
This project is under an MIT License. See LICENSE for more information.










