Palimpsest — an engine for text with layers. Markdown in, dossier out.
The engine short name is PalST (ENGINE_SHORT_NAME / PalST export). Use PalST in product UI and migration notes; the npm package remains @krwg/palimpsest.
A lightweight engine for publishing long-form text as an interactive reading experience — footnotes, offline reading, dossier aesthetics.
Palimpsest turns markdown into a reading site with real depth: inline tooltip footnotes, chapter-based navigation, offline reading via service worker, and a minimalist dossier aesthetic out of the box. Built for serial fiction, investigative writing, and documentary projects — anything where the text has layers worth surfacing, not burying in a PDF.
Extracted from Piligrim — the novel reader is the first consumer, not the source of hardcoded constants.
npm install @krwg/palimpsestnpm create palimpsest@latest my-book
# or from this repo before the create package is published:
npm create github:krwg/palimpsest/create-palimpsest my-bookThis repository is also a GitHub template. Neutral demo (paper theme): demo/ — published to GitHub Pages from main.
import {
createReader,
dossierTheme,
parseChapter,
renderBody,
createServiceWorkerSource,
ENGINE_SHORT_NAME,
} from '@krwg/palimpsest';
import '@krwg/palimpsest/styles.css';
await createReader({
root: document.getElementById('app')!,
theme: [dossierTheme],
manifestUrl: './chapters/manifest.json',
storageKeys: {
settings: 'my-book-settings',
progress: 'my-book-progress',
},
});markdown dialect → parseChapter() → { meta, glossary, body }
→ renderBody() → HTML
→ bindFootnotes() → interactive layers
theme tokens → applyTheme() → CSS custom properties (--ps-*)
plugin slots → FootnoteRenderer | DocumentExhibit | TableOfContents | ChapterTransition
import { applyTheme, paperTheme, sepiaTheme, nightTheme } from '@krwg/palimpsest';
applyTheme(paperTheme); // or sepia / night / dossierAll colors, fonts, widths, and motion land on --ps-* variables so themes switch without a rebuild. Default typography dogfoods the Piligrim stack: Cormorant Garamond + IBM Plex Sans + Special Elite (exhibits).
Override any default when calling createReader:
| Slot | Default |
|---|---|
FootnoteRenderer |
Tooltip (desktop) / bottom sheet (mobile) |
DocumentExhibit |
Archival sheet with optional bilingual toggle |
TableOfContents |
Chapter list + per-chapter progress bars |
ChapterTransition |
Instant HTML swap |
import { writeFileSync } from 'node:fs';
import { createServiceWorkerSource } from '@krwg/palimpsest';
writeFileSync(
'sw.js',
createServiceWorkerSource({
cacheName: 'my-reader-v1',
assets: ['index.html', 'chapters/manifest.json', 'chapters/ch01.txt'],
}),
);::chapter::
title: Chapter title
when: Place, year
::/chapter::
Prose with a glossary term[[1]].
:::document
::label:: EXHIBIT
Body of the document.
:::
[[1]]: term — footnote body shown in a tooltip.See test/fixtures/sample-chapter.txt and Piligrim’s chapters/_TEMPLATE.md for the full surface (::figure::, ::translate::, hand layers, …).
Optional reader behaviors are off by default (except the progress bar). Pass English defaults or override with a string bag (Piligrim can supply Russian):
await createReader({
root,
chrome: true,
lightbox: true,
progressBar: true,
search: true, // Ctrl/⌘ K overlay + reader.search()
navigation: { gestures: true, continuePrompt: true },
strings: {
continueYes: 'Продолжить',
continueNo: 'С начала',
translate: 'Перевести',
original: 'Оригинал',
searchPlaceholder: 'Поиск по главам…',
},
});Helpers: resolveReaderFeatures, resolveReaderStrings, defaultReaderStrings.
Canonical theme id is data-ps-theme (e.g. dossier). For hosts that still style with Piligrim classes (theme-paper, theme-white, …), applyTheme also sets theme-${legacyThemeClass(name)} via the permanent map PILIGRIM_THEME_CLASS (dossier→paper, paper→white, …). This is intentional host compatibility, not a temporary shim.
npm install
npm test
npm run buildMilestone 0.1.0 — extract engine, document API.
Milestone 0.2.0 — reader chrome, lightbox, continue/gestures, PalST short name, pre-migration harden, engine parity for Piligrim (published/soon, chapter-nav, prefetch, page meta, SW update).
Milestone 0.3.0 — migrate Piligrim onto PalST; full-text search (Ctrl/⌘ K).
MIT. Piligrim may stay GPL-3.0 — an MIT engine dependency is compatible with a GPL app.