Use me

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:

sh
npm install ltheme

Wire up the theme

In .vitepress/config.mts:

ts
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:

ts
import Theme from "ltheme/theme";

export default Theme;

Write sidenotes

tufteSidenotePlugin adds a ^[...] inline syntax. Anywhere in a paragraph:

md
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:

md
::: 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:

md
---
title: My Post
date: 2026-01-01
categories: [Architecture]
tags: [notes]
---