Nib
Nib is a free template for writers: essayists, newsletter writers, columnists, poets, authors with a book. Essays are set like the pages of a well-made book (Bodoni Moda for titles, Newsreader for text, a drop cap, a reading measure) and every essay has a pen-and-ink drawing that draws itself on screen: the outlines first, as a pen would, then the ink. Paper by day; night ink in the dark theme, where the drawings turn white. The demo is a fictional writer, Ada Wren, and her journal, Notes from the Margin.
Nib comes in two variants, chosen when you create the site: files/Sanity (static pages, any host) and
EmDash (--cms emdash, rendered on request on Cloudflare). The pages are the same in
both.
Pages and their content
Section titled “Pages and their content”| Page | Edit it in |
|---|---|
| Home (the title page) | Pages → Home page (a list of sections) |
| Essays (every essay, a filter by topic) | Pages → Essays page |
| An essay (the drawing, a drop cap, a margin note, the letter, the next essay) | Content → Essays |
| Books (each book, a signed copy, questions) | Pages → Books page and Content → Books |
| About (you, a portrait, the contact form, readings, questions) | Pages → About page |
| Name, journal, navigation, profiles, colophon | Pages → Site settings |
| Buttons, labels, chat, emails and the game’s texts | Content → Interface texts |
| Privacy, terms | Pages → Legal |
In titles, words wrapped in *stars* are set in italic, as in “Small things, *written down* before
they go”.
The drawings
Section titled “The drawings”Every drawing is an SVG of black shapes on white, set inline in the text colour, so it follows the theme
and the site can draw it. draw decides when (see src/components/Drawing.astro): the title page’s
drawing, an essay’s and the about page’s portrait draw themselves when the page opens; the writer on the
home page and later books as they scroll into view; lists show their drawings as plain pictures, so the
page stays light. With reduced motion every drawing is simply there.
To add your own, draw with black ink on white paper, scan or photograph it, and trace it:
npm run ink -- scan.jpg --out heron # → src/assets/drawings/heron.svgnpm run ink -- scan.jpg --width 1300 --threshold 115 --speckles 10--width is the detail it is traced at, --threshold (0–255) how dark a line must be to count, and
--speckles drops specks smaller than that many pixels. Aim for under about 60 kB gzipped per drawing.
The shapes are grouped from left to right, so the pen moves the way a hand would. Pick the file in the
editor (an essay’s Drawing field); with Sanity, upload the SVG. EmDash doesn’t accept SVG uploads by
default (an SVG can carry a script, so its admin only takes pictures); the demo’s drawings are imported
when the site is set up, and for new ones upload a JPEG or PNG of the drawing, which then fades in instead
of drawing itself. Any picture works the same way elsewhere too. Drawings are checked before they are set
in the page: an SVG with a script, an event handler or an outside reference is not shown.
Essays
Section titled “Essays”Each essay has a title, a standfirst, a topic (the essays page filters by topic without any JavaScript),
the date, its reading time in minutes, a drawing with its description and caption, and a margin note (a
line from the essay, set beside its opening on wide screens). The body is the essay; its first letter is
a drop cap. Essays are listed newest first. Search engines get each one as a schema.org BlogPosting.
Each book is a spread: its drawing, what it is, a line, a few sentences, the details (pages, binding, publisher…), the price and where to buy it. The signed copy is a one-time payment with Stripe (a Price id) or Lemon Squeezy (a variant id) in Pages → Books page → A signed copy. Without keys the button explains how to switch it on.
Letters and readings
Section titled “Letters and readings”The about page’s contact form asks for a name, email, what it is about (a short list you set in Pages → About page → Contact form) and the letter. The choice is written above the letter in the email you receive (Resend, to the email in Site settings). Readings and talks book through Cal.com; until it’s connected the page shows a preview of the calendar with your times.
Integrations
Section titled “Integrations”Everything works without keys; each feature switches on with its variables in .env.example.
| Feature | Where | Service |
|---|---|---|
| Book a call about a reading | About page, loads on click; a preview of the calendar until connected | Cal.com |
| A signed copy | Books page (one-time payment) | Stripe or Lemon Squeezy |
| The letter (newsletter) | Home page and under every essay, with a welcome email | Supabase or Mailchimp |
| Letters | About page; to the email in Site settings | Resend |
| AI chat | Every page; answers about the essays, books and readings | Claude or OpenAI |
| Search | ⌘K or the search button: the essays, books and about page | built in, or Algolia |
| Analytics | Every page; Google Analytics only after consent | Plausible, Umami, Google Analytics, PostHog |
Sections
Section titled “Sections”The home page is built from these sections, in any order: Title page (the title and a drawing that inks itself in), Latest essays (a contents list with roman numerals), A line from the notebook (a large quotation that comes up word by word), The writer (a portrait that draws itself, a few lines and facts) and The letter (the newsletter, with an airmail edge).
Colors and brand
Section titled “Colors and brand”src/content/singletons/brand.json (Pages → Brand in Keystatic) holds three colors: the accent
(rubric red: buttons, drop caps, asterisms and marks), the second (sepia: small capitals and captions)
and the third (ink: the dark theme). Buttons are darkened until their text reads; every color is
adjusted for each theme, and one that can’t get there stops the build with a message. Brand also sets the
fonts (text and titles) and the corners (square by default, or soft). The site opens on paper; the toggle
switches to night ink and the browser remembers it.
Languages
Section titled “Languages”Nib is ready for more languages: see Languages.
The 404 page
Section titled “The 404 page”A small game, Set the paragraph: a paragraph comes back from the printer set ragged; tap a word to start a new line before it, or the first word of a line to join it to the one above, until every line fits the measure as evenly as you can. Each line’s badness is the square of the room left at its end (the last line is free); the best possible setting is found for every paragraph, and you score 100 × (best + 10) ÷ (yours
- 10). Three paragraphs, yours to write (Interface texts → 404 game). The best score is kept in the visitor’s browser.
AI assistants and search engines
Section titled “AI assistants and search engines”AGENTS.mddescribes the project for coding assistants (Claude Code reads it throughCLAUDE.md, Cursor through.cursor/rules/)./llms.txtlists your pages, essays and books for AI assistants, in every language.- Pages carry JSON-LD: you as a
Person, essays asBlogPostings, books asBooks and questions as aFAQPage.
Commands
Section titled “Commands”pnpm dev # local site, editor at /keystaticpnpm build # production buildpnpm ink -- scan.jpg # trace a drawingpnpm cms sanity schema|seed # move content to Sanity (see Content → Sanity)In the EmDash variant: npm run dev, npm run deploy (Cloudflare) and npm run emdash:schema
(after changing the content model).
