Reading Progress Chapters

Essay

How a team of six ships every single week

Notes from two years of small releases, written for teams who want a calmer cadence.

By Joni Mitchell, 12 minute read

01Why weekly

We used to ship when a feature felt finished. In practice that meant a big release every two months, a week of bug reports and a team that dreaded launch days. Weekly releases started as an experiment to make each launch boring.

A short cycle forces small slices. When the deadline is Friday, nobody proposes a rewrite of the billing page; they propose the one field that customers keep asking about. Small slices are easier to review, easier to test and easier to roll back.

The surprising part was morale. People like finishing things. A weekly rhythm gives every person on the team something they can point at by the end of the week, and that feeling compounds.

02Planning on Monday

Monday starts with a thirty minute meeting and a single shared document. Each person writes the one thing they will ship by Friday and the one thing that could stop them. That is the whole plan.

We keep a short list of larger bets in the same document, each split into week sized pieces. When a bet is too large to split, we treat that as a design problem rather than a planning problem and spend a day on it before committing.

Nobody estimates in hours. The question is only whether the slice fits in the week, and if two people disagree, the slice gets smaller until they agree.

03Building in the open

Every change lands behind a flag on the day it is written. Main is always deployable, and the flag decides who sees the change. This removes the pressure of a release branch and keeps conflicts small.

We review in pairs, never in queues. The author picks a reviewer when the work starts, not when it ends, so the reviewer already knows the context by the time the pull request opens.

Customers in our early access group see most flags by Wednesday. Their notes arrive while the work is still fresh, which is the cheapest moment to change direction.

04Friday releases

Friday at noon we turn the flags on for everyone and post a short changelog. The post is written by the person who built the change, in plain words, with one screenshot.

Releasing on Friday sounds risky, but the changes are small and the flags can be switched off in seconds. In two years we have rolled back eleven times and never needed a weekend.

The afternoon is for cleanup: removing old flags, answering customer replies and writing down what surprised us. That last habit has shaped more of our roadmap than any planning session.

05What we would change

We would have started the changelog earlier. It is the single best source of truth about what the product does, and new teammates read it before anything else.

We would also protect one week in six for maintenance. Without it, small debts pile up until a weekly slice is no longer small, and the rhythm starts to slip.

Most of all, we would worry less about the cadence itself. Weekly is not magic. It is a way to keep work small, feedback early and launch days quiet, and any rhythm that does that is a good one.

About this block

Reading Progress ChaptersPRO

A reading bar for long articles: brand, a Chapters dropdown of numbered section links that marks the chapter in view, and a share button, with a hairline progress line under the bar that fills as the page scrolls. On a phone the dropdown becomes a compact chapter Select in the bar. The chapter list stays in the markup and is toggled with CSS, and the block renders a demo article to scroll through.

A sticky reading bar for long articles. The Chapters item drops a numbered list of section links that marks the chapter currently in view, a share button sits on the right, and a hairline line under the bar fills as the page scrolls; on a phone the list becomes a compact chapter picker inside the bar. The block renders its own demo article so the progress line has something to measure.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://beste.dev/r/navbar98?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://beste.dev/r-base/navbar98?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/navbar98.tsx plus the shadcn button and select primitives it uses.

Quick start

The installed file exports navbar98Demo alongside the block: the exact props behind the preview above. Spread it to get a working navbar in one line.

tsx
import { Navbar98, navbar98Demo } from "@/components/beste/block/navbar98";

export default function Page() {
  return <Navbar98 {...navbar98Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Navbar98 } from "@/components/beste/block/navbar98";

export default function Page() {
  return (
    <Navbar98
      brand="Fieldnote"
      article={{
        eyebrow: "Essay",
        heading: "How a team of six ships every week",
        byline: "By Joni Mitchell, 12 minute read",
      }}
      chapters={[
        { title: "Why weekly", paragraphs: ["We used to ship when a feature felt finished.", "A short cycle forces small slices."] },
        { title: "Planning on Monday", paragraphs: ["Monday starts with a thirty minute meeting."] },
        { title: "Friday releases", paragraphs: ["Friday at noon we turn the flags on for everyone."] },
      ]}
      labels={{ chapters: "Chapters", share: "Share", copied: "Link copied", chapterPicker: "Jump to chapter" }}
    />
  );
}

Props

PropTypeDefaultDescription
brandstring–Wordmark on the left
articleArticle–Heading block at the top of the demo article
chaptersChapter[][]Article sections; each one becomes a numbered dropdown link and a picker option
labels{ chapters?: string; share?: string; copied?: string; chapterPicker?: string }{}Trigger text, share button text, copy confirmation and the picker's accessible name
classNamestring–Extra classes for the outer wrapper
ts
type Article = {
  eyebrow?: string;
  heading: string;
  description?: string;
  byline?: string;
};

type Chapter = {
  title: string;
  paragraphs: string[];
};

Behavior notes

  • The chapter list is always rendered and toggled with CSS classes, so every chapter link is in the server-rendered HTML; while closed it carries aria-hidden and inert.
  • The Chapters trigger opens on hover and on click with aria-expanded and aria-controls; the list closes when the pointer leaves the header, on Escape and on a pointer down outside the trigger.
  • A passive scroll listener sets the progress line with scaleX from scrollY over the scrollable height, and marks the last chapter whose top has passed 140px from the viewport top as current.
  • Chapter links and picker options scroll to their section with scrollIntoView; sections carry scroll-mt-24 so headings clear the sticky bar. Section ids are derived from useId.
  • Share uses the Web Share API when the browser has it and otherwise copies the page URL, showing the copied label for two seconds.
  • On a phone the shadcn Select in the bar replaces the dropdown and always shows the chapter in view.

More Navigation blocks

View all Navigation
PRO

navbar108

Numbered Index Menu

PRO

navbar115

Photo Backdrop Mega

PRO

navbar105

Expanding Search Bar

Get Pro