LTheme is a VitePress theme. This page shows how this site itself is wired up, so you can copy the same setup into your own VitePress project.
Not on npm yet — publishing it is deliberately deferred for now. To use it today, copy src/theme from the repo into your project and self-reference it the same way this site does (see its package.json's exports field). Once it does get published, the install will just be:
npm install lthemeWire up the theme
In .vitepress/config.mts:
import { defineConfigWithTheme } from "vitepress";
import type { ThemeConfig } from "ltheme/theme/types";
import { tufteSidenotePlugin, writingContainerPlugin } from "ltheme/theme/support/markdown-plugins";
export default defineConfigWithTheme<ThemeConfig>({
themeConfig: {
avatar: "/images/avatar.jpg",
nav: [
{ text: "Home", link: "/" },
{ text: "Posts", link: "/posts" },
],
socialLinks: [
{ icon: "github", link: "https://github.com/you", ariaLabel: "GitHub" },
],
footer: {
since: 2025,
imprint: { text: "Imprint", link: "/imprint", show: true },
},
},
markdown: {
config(md) {
md.use(tufteSidenotePlugin);
md.use(writingContainerPlugin);
},
},
});And in .vitepress/theme/index.ts:
import Theme from "ltheme/theme";
export default Theme;Write sidenotes
tufteSidenotePlugin adds a ^[...] inline syntax. Anywhere in a paragraph:
Regular text^[This becomes a margin note on desktop, and a tap-to-expand note on mobile.] continues here.Pull a passage out of the flow
writingContainerPlugin adds a :::writing container for quoting or highlighting a block:
::: writing Optional Title
This renders at the same width as body text, set apart from the surrounding prose.
:::Post metadata
Posts read author, date, categories, and tags from frontmatter, and are listed on the paginated home feed automatically:
---
title: My Post
date: 2026-01-01
categories: [Architecture]
tags: [notes]
---