Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/search-visibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'penciled': patch
---

The npm keywords now include `text-annotation`, `web-highlighter`, `react-highlight`, `nextjs` and `custom-highlight-api`, so the package is easier to find. The README mentions Medium-style highlights, and its FAQ answers what happens to extension highlights when a URL changes, and whether they sync, work with PDFs or export to Markdown.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

**penciled** (penciled.org, also called penciled.js) is a 15 kB open-source JavaScript library for persistent text highlights and notes on any web page, with a [browser extension](https://www.penciled.org/extension/) built on it. Highlights are painted with the CSS Custom Highlight API, so your DOM is never touched. Think **Sonner, for text annotations**.

Use it to add Medium-style highlights and notes to a blog, docs site or web app, with no backend required.

Not to be confused with Penciled, the healthcare company at penciled.com.

**Browser support:** Chrome/Edge 105+, Safari 17.2+, Firefox 140+; no fallback on older browsers, `annotate()` only warns. [Details](https://www.penciled.org/guides/browser-support/)
Expand Down Expand Up @@ -118,6 +120,22 @@ web-highlighter wraps each highlight in `<span>` elements and leaves the UI and

Yes. penciled for the browser lets readers highlight text and take notes on any website, in Chrome, Edge and other Chromium browsers 123+ and Firefox 140+. It's free, open source and built on this library. Highlights stay in the browser, with no account, and nothing is sent anywhere. See [https://www.penciled.org/extension/](https://www.penciled.org/extension/)

### Do my extension highlights survive when a page's URL changes?

Not automatically. The extension saves highlights per page address, ignoring the `#fragment`, a leading `www.`, a trailing slash and common tracking parameters such as `utm_source`. If a page moves to a new address, or the same article is reachable at two different addresses, highlights made at one address don't show at the other. In the JavaScript library, annotations are stored under the page's path by default; set `documentId` to keep them when URLs change.

### Does the extension sync highlights between devices?

No. Highlights stay in the browser you made them in, with no account and no cloud. Only your settings sync, through your browser account. To move highlights to another browser, export a backup from the notes page and import it there.

### Can penciled highlight PDFs?

No. The extension and the library highlight text on web pages, not PDFs. For PDFs, a tool like Hypothesis is a better fit; see [https://www.penciled.org/alternatives/](https://www.penciled.org/alternatives/)

### Can I export my highlights to Markdown for Obsidian or Logseq?

Yes, as a file. **Export as Markdown** on the extension's notes page downloads a `.md` file with each highlight quoted with its note, which you can open in Obsidian, Logseq or any notes app. There's no integration or sync with them: each export is a one-off copy.

### Is this penciled.com, the healthcare company?

No. penciled.org is an open-source JavaScript highlights & notes library and browser extension, at [www.penciled.org](https://www.penciled.org). It is not related to Penciled, the healthcare company at penciled.com.
Expand Down
7 changes: 6 additions & 1 deletion apps/docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ export default defineConfig({
],
}),
],
components: { Head: './src/components/Head.astro' },
components: {
Head: './src/components/Head.astro',
Footer: './src/components/Footer.astro',
},
head: [
{ tag: 'link', attrs: { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' } },
{ tag: 'meta', attrs: { property: 'og:image', content: ogImage } },
Expand Down Expand Up @@ -146,6 +149,7 @@ export default defineConfig({
items: [
{ label: 'Theming and customization', slug: 'guides/theming' },
{ label: 'Anchoring and limitations', slug: 'guides/anchoring' },
{ label: 'Highlight text without spans', slug: 'guides/highlight-without-spans' },
{ label: 'Browser support', slug: 'guides/browser-support' },
],
},
Expand All @@ -164,6 +168,7 @@ export default defineConfig({
items: [
{ label: 'Overview', slug: 'extension' },
{ label: 'Privacy', slug: 'extension/privacy' },
{ label: 'Alternatives', slug: 'alternatives' },
],
},
{
Expand Down
45 changes: 45 additions & 0 deletions apps/docs/src/alternatives.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// The questions on /alternatives/ and its FAQPage structured data. Prices and plan limits of other
// tools may only appear when they were read on the vendor's own page; the page cites each one with
// the date it was checked. Update that date whenever a figure is re-checked.
import type { Faq } from './faq.ts';

export const checked = '31 October 2026';

export const alternativesFaq: Faq[] = [
{
question: 'What is a free Weava alternative without a storage limit?',
answer:
"penciled for the browser, the penciled.org highlighter extension, is free with no paid plan and no storage cap of its own: it asks the browser for unlimited extension storage. Weava's free plan includes unlimited highlights and 100 MB of storage, according to Weava's pricing page. Weava, unlike penciled, syncs between devices, so pick it if you read on several computers.",
},
{
question: 'Is there a Glasp alternative that keeps highlights private for free?',
answer:
"Yes: the penciled.org highlighter extension is private by design and free. There's no account, highlights stay in your browser, and nothing is sent anywhere. Glasp is a social highlighter: its pricing page says highlights are public by default, and its free plan lists unlimited public highlights. Glasp is the better choice if you want to share highlights and follow what other readers save.",
},
{
question: 'Is there a Liner alternative that just highlights?',
answer:
"Yes: the penciled.org highlighter extension only highlights text and keeps notes, with no AI features, ads or account. Liner's pricing page now presents it as an AI search product, with Free, Pro and Max plans built around AI models. If you want AI answers and summaries, Liner does that and penciled doesn't.",
},
{
question:
"Diigo stopped loading my highlights: is there a highlighter that doesn't depend on a server?",
answer:
"Yes: the penciled.org highlighter extension has no server at all. Highlights are stored in your browser's extension storage and the extension makes no network requests, so they load even offline and don't depend on any service staying up. The trade-off is that they live only in that browser: there's no sharing and no sync, so keep a backup by exporting from the notes page now and then.",
},
{
question: 'What can replace Memex for web highlights?',
answer:
"For highlighting and annotating web pages in one browser, the penciled.org highlighter extension: select text, pick a color, add a note, and the highlights come back when you return to the page. Your highlights are listed and searchable on its notes page, with tags. It doesn't replace the rest of what Memex offers, and it doesn't sync between devices.",
},
{
question: 'How does penciled compare with Web Highlights?',
answer:
"Both are free browser extensions that keep highlights locally. Web Highlights' pricing page says the free plan includes unlimited highlights, bookmarks, notes and tags, with cloud sync and its web app in the paid Premium and Ultimate plans, and it also highlights PDFs. The penciled.org highlighter extension is open source (MIT), makes no network requests, doesn't change the page's markup to draw highlights, and doesn't do PDFs or sync.",
},
{
question: 'penciled vs Hypothesis: which is better for personal highlights?',
answer:
"For private, personal highlights, the penciled.org highlighter extension is simpler: no account, and highlights stay in your browser. Hypothesis is a social annotation service: you need an account to annotate, annotations are stored on its servers, and it's built for public annotation, groups, replies and PDFs. Choose Hypothesis to discuss a text with others or annotate PDFs.",
},
];
29 changes: 29 additions & 0 deletions apps/docs/src/components/FaqList.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
// Renders questions as h2 headings with their answers, turning the site's own URLs into links. The
// same data feeds the page's FAQPage structured data in Head.astro, so the two always match.
import type { Faq } from '../faq.ts';

interface Props {
items: Faq[];
}

const { items } = Astro.props;
const slug = (question: string) =>
question
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
---

{
items.map(({ question, answer }) => (
<>
<h2 id={slug(question)}>{question}</h2>
<p>
{answer
.split(/(https:\/\/\S+\/)/)
.map((part) => (part.startsWith('https://') ? <a href={part}>{part}</a> : part))}
</p>
</>
))
}
31 changes: 31 additions & 0 deletions apps/docs/src/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
// Starlight's footer, followed by a quiet line of site links on every docs page.
import Default from '@astrojs/starlight/components/Footer.astro';
---

<Default />
<footer class="site-links">
<a href="/compare/">Compare libraries</a>
<a href="/alternatives/">Highlighter extension alternatives</a>
<a href="/faq/">FAQ</a>
<span>Not affiliated with penciled.com.</span>
</footer>

<style>
.site-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.5rem 1.25rem;
margin-top: 2rem;
font-size: var(--sl-text-xs);
color: var(--sl-color-gray-3);
}
.site-links a {
color: inherit;
text-decoration: none;
}
.site-links a:hover {
color: var(--sl-color-white);
}
</style>
11 changes: 8 additions & 3 deletions apps/docs/src/components/Head.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
// Starlight's head with descriptive titles and structured data, plus PostHog analytics.
import Default from '@astrojs/starlight/components/Head.astro';
import { disambiguation, faq } from '../faq.ts';
import { alternativesFaq } from '../alternatives.ts';
import { disambiguation, type Faq, faq } from '../faq.ts';

const route = Astro.locals.starlightRoute;
const { data } = route.entry;
Expand Down Expand Up @@ -29,6 +30,10 @@ if (notFound) {
}
}

// Pages whose questions are also published as FAQPage structured data.
const faqPages: Record<string, Faq[]> = { faq, alternatives: alternativesFaq };
const faqs = faqPages[route.id];

const url = !notFound && site && new URL(Astro.url.pathname, site).href;
const home = site?.href;
const project = {
Expand Down Expand Up @@ -60,14 +65,14 @@ const structuredData = url &&
{ '@type': 'ListItem', position: 2, name: data.title, item: url },
],
},
...(route.id === 'faq'
...(faqs
? [
{
'@context': 'https://schema.org',
'@type': 'FAQPage',
url,
about: project,
mainEntity: faq.map(({ question, answer }) => ({
mainEntity: faqs.map(({ question, answer }) => ({
'@type': 'Question',
name: question,
acceptedAnswer: { '@type': 'Answer', text: answer },
Expand Down
57 changes: 57 additions & 0 deletions apps/docs/src/content/docs/alternatives.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Alternatives to Weava, Glasp, Liner, Diigo, Memex, Hypothesis and Web Highlights
metaTitle: 'Highlighter extension alternatives: Weava, Glasp, Liner, Diigo, Memex, Hypothesis, Web Highlights'
description: How the free, open-source penciled.org highlighter extension compares with Weava, Glasp, Liner, Diigo, Memex, Hypothesis and Web Highlights, and when another tool is the better choice.
lastUpdated: 2026-10-31
tableOfContents: false
---

import FaqList from '../../components/FaqList.astro';
import { alternativesFaq, checked } from '../../alternatives.ts';

**penciled for the browser**, the penciled.org highlighter extension, is a free, open-source (MIT) extension for Chrome, Edge and Firefox that saves highlights and notes on any web page, locally, with no account. This page compares it with other web highlighter extensions: Weava, Glasp, Liner, Diigo, Memex, Hypothesis and Web Highlights. They make different trade-offs, and for many readers one of them is the better choice. To compare JavaScript libraries for your own site instead, see [Compare with other libraries](/compare/).

## How do the highlighter extensions compare?

Prices and plan limits are quoted only from each vendor's own page, checked on {checked}. Where a figure couldn't be read on the vendor's page, the cell says **see vendor**. Plans change, so check the vendor's page before deciding.

<div class="compare-table">

| Tool | Free plan and price (from the vendor's page) | Where highlights are kept | Source |
|---|---|---|---|
| **penciled.org extension** | Free, no paid plan. No limit on highlights or storage. | Only in your browser; no account, no sync | [Privacy statement](/extension/privacy/) |
| **Weava** | Free: unlimited highlights and notes, 100 MB storage, sync with unlimited devices. Premium: see vendor (the page lists both $3.99/month and $7.99/month). | Synced to your Weava account | [weavatools.com/premium](https://www.weavatools.com/premium/), checked on {checked} |
| **Glasp** | Free: unlimited public highlights; highlights are public by default. Pro: $12.50/month billed yearly ($150/year). | Your Glasp account | [glasp.co/pricing](https://glasp.co/pricing), checked on {checked} |
| **Liner** | Free: $0 (AI search features). Pro: $14.99/month billed yearly, or $17.99 monthly. Highlighter limits: see vendor. | See vendor | [liner.com/pricing](https://liner.com/pricing), checked on {checked} |
| **Diigo** | See vendor | See vendor | [diigo.com/premium](https://www.diigo.com/premium) |
| **Memex** | See vendor | See vendor | [memex.garden](https://memex.garden/) |
| **Hypothesis** | Free plan with core annotation; the pricing page lists paid plans for schools, per student. | Hypothesis's servers, or a self-hosted server | [web.hypothes.is/pricing-page](https://web.hypothes.is/pricing-page/), checked on {checked} |
| **Web Highlights** | Free: unlimited highlights, bookmarks, notes and tags. Cloud sync and the web app: Premium or Ultimate, prices see vendor. | In the extension; in the cloud with a paid plan | [web-highlights.com/pricing](https://web-highlights.com/pricing), checked on {checked} |

</div>

<FaqList items={alternativesFaq} />

## When is another tool the better choice?

penciled for the browser does one thing: private highlights and notes on web pages, in one browser. Pick something else when you need:

- **PDFs.** penciled doesn't highlight PDFs. Hypothesis, Glasp and Web Highlights work with PDFs.
- **Cross-device sync.** penciled's highlights stay in the browser you made them in; you can move them with a backup file, but they don't sync. Weava syncs on its free plan, and Web Highlights with a paid plan.
- **Research projects and collaboration.** If you organize sources in shared folders, a research tool fits better: Weava's plans list folders, sub-folders and collaboration.
- **Social reading.** To share highlights, follow other readers or discuss a text in public or in groups, use Glasp or Hypothesis.
- **AI answers and summaries.** penciled has no AI features; Liner and Glasp do.

penciled is not a read-later app or a Pocket replacement: it doesn't save copies of pages, only your highlights and notes on them.

## Where does the penciled.org extension win?

- **Nothing leaves your browser.** No account, no servers, no analytics, and the extension makes no network requests. See the [privacy statement](/extension/privacy/).
- **Free and open source.** MIT licensed, with no paid plan and no limit on highlights. Anyone can [read the source](https://github.com/marcellosso/penciled/tree/main/apps/extension).
- **Pages stay as they are.** Highlights are painted by the browser with the CSS Custom Highlight API instead of wrapping text in elements, so the page's own markup and scripts aren't affected.
- **It doesn't guess.** When a page changed so much that a highlight can't be placed with confidence, it's listed as not found instead of being put on the wrong words.
- **Markdown export.** The notes page exports a `.md` file you can open in Obsidian, Logseq or any notes app. It's a file, not an integration or sync.

[Get the penciled.org highlighter extension](/extension/) for Chrome, Edge or Firefox.

Spotted something out of date or wrong? [Open an issue](https://github.com/marcellosso/penciled/issues) and it'll be fixed.
4 changes: 2 additions & 2 deletions apps/docs/src/content/docs/compare.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ lastUpdated: 2026-10-28
description: How penciled.org, the open-source JavaScript highlights & notes library, compares with Hypothesis, mark.js, rangy, web-highlighter, Recogito and Annotator.js.
---

**penciled.org** is an open-source JavaScript library and browser extension for persistent text highlights and notes. The library, published on npm as `penciled` and also called penciled.js, is 15 kB with its UI. It's a CSS Custom Highlight API library: it paints highlights without wrapping text in elements, and it comes with a toolbar, a note editor and saving to `localStorage` or your own backend. This page compares it with [Hypothesis](https://web.hypothes.is/) and five JavaScript libraries that highlight or annotate text: [mark.js](https://markjs.io/), [rangy](https://github.com/timdown/rangy), [web-highlighter](https://github.com/alienzhou/web-highlighter), [@recogito/text-annotator](https://github.com/recogito/text-annotator-js) and [Annotator.js](https://github.com/openannotation/annotator). They solve different problems, and for some jobs one of them is the better choice.
**penciled.org** is an open-source JavaScript library and browser extension for persistent text highlights and notes. The library, published on npm as `penciled` and also called penciled.js, is 15 kB with its UI. It's a CSS Custom Highlight API library: it paints highlights without wrapping text in elements, and it comes with a toolbar, a note editor and saving to `localStorage` or your own backend. This page compares it with [Hypothesis](https://web.hypothes.is/) and five JavaScript libraries that highlight or annotate text: [mark.js](https://markjs.io/), [rangy](https://github.com/timdown/rangy), [web-highlighter](https://github.com/alienzhou/web-highlighter), [@recogito/text-annotator](https://github.com/recogito/text-annotator-js) and [Annotator.js](https://github.com/openannotation/annotator). They solve different problems, and for some jobs one of them is the better choice. Looking for a highlighter extension rather than a library? See [alternatives to Weava, Glasp, Liner and other highlighter extensions](/alternatives/).

## What is the best open source text highlighting JavaScript library?

Expand Down Expand Up @@ -85,7 +85,7 @@ penciled is also new: it's below 1.0, so its API may still change between minor
- To build **your own highlighter** that must work in **old browsers**: web-highlighter, or rangy for lower-level control.
- For **collaborative or research annotation** on the W3C model: @recogito/text-annotator.
- For **public or group annotation** of web pages and PDFs, as a service: Hypothesis.
- For **private highlights on any website**, as a reader: the [penciled.org browser extension](/extension/).
- For **private highlights on any website**, as a reader: the [penciled.org browser extension](/extension/). It's compared with Weava, Glasp, Liner, Diigo, Memex, Hypothesis and Web Highlights on [Alternatives](/alternatives/).
- For an **existing Annotator.js** deployment: keep it, or plan a migration; it isn't maintained.

## How were these numbers measured?
Expand Down
Loading
Loading