Skip to content

Newsletter

One decision, made from the archive: a hero with the field in it, the back issues as the actual argument, and the three worries about handing over an address answered as content.

6 routes6 pages · 22 blocks39 files · 4,790 lineslucide-reactAdded 14 Sept 2026

What's included

  • app/about/page.tsx
  • app/archive/[slug]/page.tsx
  • app/archive/page.tsx
  • app/globals.css
  • app/layout.tsx
  • app/not-found.tsx
  • and 10 more files
  • 6 pages it is built from, installed with it
  • Needs lucide-react

Works with

  • React
  • Next.js
  • Tailwind CSS
  • TypeScript

npx hoverlab init newsletter ./my-app

Or over MCP, from your editor's agent — no account needed.

License

Free to read, copy and install, for personal and non-commercial projects. Shipping it in client work or a paid product needs Pro ($79 once). The source lands in your repo and stops being ours — no attribution, nothing to upgrade.

Was this useful?

Every screen

One long email about software, every Friday

Postmortems with the numbers left in, migrations with the rollback described, and interview processes assessed against what they actually selected for. Free, and about 2,000 words.

One email a week. Unsubscribe in one click. Your address is never sold.

41,280 already waiting

Read by engineers at

  • Northwind
  • Contoso
  • Umbra
  • Vandelay
  • Aperture
  • Lumon
Issue 148

The cache we deleted, and the four weeks of arguing that preceded it

A caching layer that everyone agreed was load-bearing turned out to be hiding a query plan that went quadratic. The interesting part is not the fix — it is how long it took to be allowed to look.

Elin Sørensen9 min read

Three years in

41,280 subscribers and a 62% open rate, which is the number that matters

A large list that nobody opens is a vanity metric and a rented audience. This one is small by newsletter standards and is read, which is why the sponsor slots are booked out to June and why there is only ever one of them.

Read the archive
41,280
Subscribers
March 2026, verified addresses only
62%
Open rate
Rolling 12-issue average
148
Issues, no skipped weeks bar nine
Since March 2023
0
Times the list has been shared
And there is no mechanism to

What readers say

Unedited, and picked to include the two that describe it as long — because it is, and somebody who wants a three-minute read should know before subscribing.

“The only newsletter I read the week it arrives rather than in a batch on a Sunday. It is long, which is unusual and correct — the short ones have nothing to say.”
Tobias RennerStaff engineer, Contoso
“I have forwarded the estimates issue to three managers and it changed how one of them ran planning. That is a better hit rate than most books.”
Priya RamanathanEngineering manager
“It is one email a week and it is genuinely one email a week. No “quick note”, no webinar invitation, no course launch. I have been on it four years.”
Marcus OyelaranPrincipal engineer, Umbra
“Half the issues are about things that went wrong, with the numbers left in. I do not know anywhere else that publishes the rollback as well as the launch.”
Dev KaurPlatform lead, Aperture

The terms

What subscribing actually signs you up for

The three worries everybody has about giving an address to a newsletter, answered before you are asked to give one a second time.

  • One email, Friday morning, that is allThere is no second email, no digest, no “we noticed you have not opened”. If a week has nothing worth 2,000 words, nothing is sent — that has happened nine times in three years.
  • Unsubscribe in one click, from any issueA link in the footer that works immediately and does not ask you to confirm, log in, or explain. There is no re-engagement sequence afterwards.
  • Your address is never sold, rented or sharedNot to sponsors, not to a partner, not as part of a "network". Sponsors get a slot in the email and a click count, and never a list.
  • Every issue is public a fortnight laterThe archive is free and unpaywalled, and always will be. Subscribing buys it two weeks early and in your inbox, which is worth something to some people and nothing to others.

Live components in your current theme — switch routes, or the phone icon to check the mobile layout. Colours are this template’s Tideline palette, which ships in app/globals.css. Soft cyan and the largest radius in the catalog. Harbour is the same hue at nearly double the saturation and a quarter of the roundness — the two are a good demonstration that hue alone does not separate two palettes.

Get it

39 files · .zip · nothing to configure

then

cd newsletter
npm install
npm run dev

The archive contains the whole project — routes, blocks, theme tokens, Tailwind and PostCSS config, tsconfig and a .gitignore. One runtime dependency, and no Hoverlab dependency at all: it is your code from the moment it unzips.

For AI

The component, its props, the design tokens it expects and the command that installs it — as one prompt. Paste it into Claude, Cursor, v0 or ChatGPT and what they build around it will match the rest of the catalog instead of inventing its own system.

See the prompt

Routes

PathPageFile
/Newsletter Landingapp/page.tsx
/archiveBlog Indexapp/archive/page.tsx
/archive/[slug]Article Pageapp/archive/[slug]/page.tsx
/aboutAbout Pageapp/about/page.tsx
/sponsorSingle Offerapp/sponsor/page.tsx
404404 Pageapp/not-found.tsx

What you get

project root(8 files)

  • GETTING-STARTED.md
  • gitignore
  • next.config.ts
  • package.json
  • postcss.config.mjs
  • README.md
  • tailwind.config.ts
  • tsconfig.json

app/(8 files)

  • about/page.tsx
  • archive/[slug]/page.tsx
  • archive/page.tsx
  • globals.css
  • layout.tsx
  • not-found.tsx
  • page.tsx
  • sponsor/page.tsx

components/(23 files)

  • article-header.tsx
  • blog-post-grid.tsx
  • booking-scheduler.tsx
  • cookie-consent.tsx
  • cta-split-panel.tsx
  • footer-mega.tsx
  • footer-minimal.tsx
  • footer-newsletter.tsx
  • hero-price-anchor.tsx
  • hero-waitlist.tsx
  • logo-cloud.tsx
  • logo-strip.tsx
  • navbar-simple.tsx
  • newsletter-signup.tsx
  • not-found-404.tsx
  • pricing-value-split.tsx
  • product-spec-split.tsx
  • review-distribution-band.tsx
  • stats-narrative.tsx
  • stats-timeline.tsx
  • team-grid.tsx
  • testimonial-grid.tsx
  • theme-provider.tsx

Every file is listed. The 22 files in components/ are the blocks the pages import — each one has its own page if you want to read it on its own.

Project files

Everything except the blocks. Opens on app/globals.css — the file that makes the rest look right, since every block styles itself with bg-card and text-muted-foreground rather than literal colours.

app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

/**
 * Design tokens — the Tideline palette.
 *
 * Soft cyan and the largest radius in the catalog. Harbour is the same hue at nearly double the saturation and a quarter of the roundness — the two are a good demonstration that hue alone does not separate two palettes.
 *
 * This file is the reason a pasted block looks right. Every block and page
 * styles itself with semantic classes — `bg-card`, `text-muted-foreground`,
 * `border-border` — rather than literal colours, so they inherit whatever
 * you define here instead of fighting it. Change a value below and every
 * section in the project moves with it. Change the hue on `--primary` and
 * `--ring` together and you have rebranded the site.
 *
 * Values are bare HSL channels, not `hsl(...)` calls. That is what lets
 * Tailwind compose them with an alpha suffix: `bg-primary/10` expands to
 * `hsl(var(--primary) / 0.1)`, which is impossible if the variable already
 * carries its own function wrapper.
 *
 * Every foreground/background pair below clears WCAG AA (4.5:1) in both
 * themes. If you retune one, check the pair rather than trusting the eye —
 * mid-lightness accents are the ones that fail.
 */

@layer base {
  :root {
    --background: 196 22% 99%;
    --foreground: 196 45% 9%;
    --card: 0 0% 100%;
    --card-foreground: 196 45% 9%;
    --popover: 0 0% 100%;
    --popover-foreground: 196 45% 9%;
    --primary: 196 45% 34%;
    --primary-foreground: 0 0% 100%;
    --secondary: 196 22% 96%;
    --secondary-foreground: 196 40% 20%;
    --muted: 196 15% 96%;
    --muted-foreground: 196 12% 42%;
    --accent: 178 45% 95%;
    --accent-foreground: 178 45% 22%;
    --destructive: 0 72% 45%;
    --destructive-foreground: 0 0% 100%;
    --border: 196 15% 90%;
    --input: 196 15% 90%;
    --ring: 196 45% 34%;

    --radius: 1.5rem;
  }

  .dark {
    --background: 196 40% 5%;
    --foreground: 196 15% 97%;
    --card: 196 32% 8%;
    --card-foreground: 196 15% 97%;
    --popover: 196 32% 8%;
    --popover-foreground: 196 15% 97%;
    --primary: 196 55% 72%;
    --primary-foreground: 196 45% 8%;
    --secondary: 196 25% 15%;
    --secondary-foreground: 196 15% 97%;
    --muted: 196 25% 15%;
    --muted-foreground: 196 12% 68%;
    --accent: 178 30% 18%;
    --accent-foreground: 178 40% 92%;
    --destructive: 0 62% 52%;
    --destructive-foreground: 0 0% 100%;
    --border: 196 22% 19%;
    --input: 196 22% 19%;
    --ring: 196 55% 72%;
  }
}

@layer base {
  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground antialiased;
  }

  /**
   * Global motion opt-out.
   *
   * Blocks guard their own animations with Tailwind's `motion-safe:`, but
   * third-party CSS and anything you add later will not. This is the
   * backstop: it neutralises every animation and transition on the page
   * for users who have asked the OS for reduced motion, rather than
   * relying on each author to remember.
   */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

More Landing Pages

Open the full page for this template

Startup Waitlist

The waitlist hero with the count on it

A pre-launch site in violet: one email field, a blog to keep the list warm, and no pricing to be held to. The smallest honest thing to put in front of a product that does not exist yet.

4 routes4 pages13 blocksUltraviolet
Pro
Open the full page for this template

Developer Tool

The terminal hero, typing the install

Near-black buttons, square corners and a terminal-green accent. Install command above the fold, real code before any prose, docs and changelog behind it.

5 routes5 pages17 blocksGraphite
Pro
Open the full page for this template

Mobile App

The store-badge download hero

Emerald and 16px corners, built around one conversion: the store install. Badges and the App Store rating above the fold, a single price, and an account area for the subscription.

5 routes5 pages18 blocksSignal
Pro
Open the full page for this template

Agency Studio

Case studies that name the constraint

Terracotta on warm paper, with no blue in it anywhere. Full-bleed hero, client list, the actual team, a journal and a careers page — and no pricing, on purpose.

5 routes5 pages15 blocksSandstone
Pro
Open the full page for this template

Local Service

Hours, address and phone above the fold

Deep teal, for a business people let into their house. A booking widget above the fold, every price published, and a compliance footer with the registrations a regulated trade has to show.

4 routes4 pages14 blocksHarbour
Pro
Open the full page for this template

Marketplace

Both sides of the market on one page

Dark olive on warm off-white, built for two audiences at once: search and real listings for buyers, the seller economics below the fold, and a browse route behind it.

5 routes5 pages19 blocksMoss
Pro
Open the full page for this template

Enterprise

The security posture band

Burgundy and square corners — the register of things bought in a boardroom. Numbers in the hero, a comparison table that concedes rows, and published prices instead of a sales wall.

5 routes5 pages18 blocksClaret
Pro
Open the full page for this template

Integration Platform

The integration grid, sorted by depth

High-chroma blue. The connector names in the hero, a catalogue with honest live/beta/planned status, four SDK languages and a dated roadmap for everyone who is not on the list.

4 routes4 pages14 blocksCobalt
Pro
Open the full page for this template

Creator Course

The curriculum, module by module

Magenta-plum with the softest corners in the set, for one person selling one thing. A student testimonial as the hero, a long instructor section, one price and the refund policy on the page.

5 routes5 pages15 blocksPlum