Skip to content
Open
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
7 changes: 6 additions & 1 deletion .claude/skills/create-example/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Contains all of the example's configuration. Here's an annotated example (from `
"Slash Menu",
"Appearance & Styling"
],
<!-- NPM dependencies the source files rely on. -->
<!-- NPM dependencies the source files rely on. Only list packages the example actually imports — the generated `package.json` already includes `@blocknote/core`, `@blocknote/react`, the UI library (see `uiLib`), `react`, and `react-dom`. -->
"dependencies": {
"@mui/icons-material": "^5.16.1",
"@mui/material": "^5.16.1"
Expand All @@ -54,6 +54,11 @@ Contains all of the example's configuration. Here's an annotated example (from `
"pro": true
```

Two constraints on dependencies:

- `"uiLib"` (optional; `"mantine"` | `"ariakit"` | `"shadcn"`, default `"mantine"`) selects which single BlockNote UI package the generated `package.json` depends on. The mantine variant also carries `@mantine/core`/`@mantine/hooks` (peer dependencies of `@blocknote/mantine`). Do not add UI packages to `"dependencies"` manually; set `uiLib` instead.
- Examples with `"docs": true` are all compiled into the docs site's single dependency context, so `vp run gen` fails if two docs-embedded examples declare incompatible version ranges of the same package (e.g. `lib0` for yjs 13 vs 14). Reconcile the ranges or set `"docs": false` on one of them.

`README.md`

A Markdown description of the example. Made of four parts:
Expand Down
43 changes: 43 additions & 0 deletions .claude/skills/knip-skill/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: knip-skill
description: How Knip is configured in this repo and how to act on its findings. Should be used automatically whenever Knip is run, mentioned, configured, or reports unused files/dependencies/exports — including when deciding whether a flagged item is safe to delete.
---

Knip checks for unused files, dependencies, and exports. Config lives in `knip.json` at the repo root. Several parts of this repo look "unused" to static analysis but are load-bearing, so **verify every finding before deleting** — the config encodes a lot of hard-won exceptions.

# Running Knip

1. **Always regenerate first**: `vp run --filter @blocknote/dev-scripts gen`. Example `package.json`s, `playground/src/examples.gen.tsx`, and part of `docs/package.json`'s dependencies are generated from `.bnexample.json` manifests. Running Knip against stale generated files produces phantom findings.
2. Run via the root script: `pnpm knip` (this is `knip --no-config-hints`). Don't run bare `knip` from a subdirectory.
3. Knip respects `.gitignore` for entry/project file discovery — gitignored files (e.g. `docs/components/example/generated/`) are never picked up as project files, so they don't appear in reports. That is expected, not a coverage bug.
4. Knip is **not wired into CI**. CI only checks that `gen` output is committed and current (`build.yml` "Check generated files are up to date"). Keeping `pnpm knip` at zero findings is a manual discipline — run it before finishing any branch that touches dependencies or exports.

# Triaging findings — check these before deleting anything

A flagged item is a **false positive** (fix the config, not the code) when it is:

- **Referenced by a string path**, not an import — e.g. `docs/components/typstCompilerWasmUrl.ts` via turbopack aliases in `docs/next.config.ts`. Add it as an `entry` if it's real source that should stay analyzed; use the root `ignore` list only when suppressing all issue types for it is acceptable (`ignore` silences everything about a file, not just "unused file" — `ignoreFiles` is the narrower option that only suppresses the unused-file report).
- **A binary invoked from `node_modules/.bin` in a script** — e.g. `wasm-pack` in `packages/xl-typst-compiler/scripts/ensure-wasm.mjs`. Add to that workspace's `ignoreDependencies`.
- **A subpath entry of a package's exports map** — packages with entries beyond `"."` need them listed in the workspace `entry` config (see `packages/math-block`, `packages/diagram-block` with `src/*-exporter/index.{ts,tsx}`, and `packages/xl-pdf-exporter` with `src/react-pdf/index.ts`). Check the package.json `exports` field before deleting an "unused file" that is an `index.ts`.
- **A workspace dep that exists for build ordering, not imports** — e.g. `@blocknote/shared` and `@blocknote/xl-typst-compiler` in root `ignoreDependencies`, and all of playground's `@blocknote/*` deps (see below). Removing them breaks topological build order (locally and on Vercel) even though no source file imports them.
- **Consumed via a namespace import** (`import * as x` then `x.fn(...)` passed around) — Knip can miss this. Keep the export and mark it with a `@public` JSDoc tag, which exempts it (see `getLLMText` in `docs/lib/source/examples.ts`).

Only after ruling those out is a finding a **true positive**: delete the file, remove the dep, or un-export the symbol.

**Be very careful with `knip --fix`.** It once un-exported `getLLMText`, which broke the docs production build because only `next build` (not `types:check`) runs the full route typecheck. Prefer manual fixes; if you use `--fix`, review every hunk.

# Non-standard workspace configs (the "why" behind knip.json)

- **`docs`**: `ignoreDependencies: [".+"]` — dependency checking is disabled **by design**. `gen` syncs deps from docs-embedded example manifests into `docs/package.json`, and docs consumes things through paths Knip can't follow. Do not "improve" this by narrowing the pattern; do not hand-prune docs deps that gen will re-add.
- **`playground`**: `@blocknote/.+` deps drive Vercel's `--filter '@blocknote/example-editor...'` build ordering — never remove them. `katex` and `tex2typst` are resolved from the playground's own `node_modules` by build-mode vite aliases in `playground/vite.config.ts` (a Vercel filtered-install workaround) — keep the ignore list in sync with those aliases: if an alias is added/removed there, mirror it in the dep list and `knip.json`. Everything else was deliberately pruned; playground examples resolve their own deps via per-example `node_modules` (relative imports).
- **`examples/*/*`**: `.bnexample.json` lists only what the example's source imports; the generator auto-injects `@blocknote/core`, `@blocknote/react`, the `uiLib` package (+ `@mantine/core`/`@mantine/hooks` for mantine), `react`, `react-dom` — hence the shared `ignoreDependencies`. A few examples have per-example configs extending it. **Never edit a generated example `package.json` to satisfy Knip** — fix `.bnexample.json` and rerun `gen`.
- Example `"@blocknote/*": "latest"` version specs are deliberate (the StackBlitz open-a-directory repro contract, guarded by `fresh-install-tests.yml`); pnpm's workspace settings resolve them to workspace packages locally. Knip flagging or you pinning these is wrong.
- **`tests`**: has `paths` for `@examples/*`/`@shared/*`; the ambient `declare module` for `@examples` is deliberate (avoids TS6059) — don't convert it to tsconfig paths. `@blocknote/ariakit`/`@blocknote/shadcn` are used by e2e fixtures in ways Knip misses.
- **`packages/dev-scripts`**: templates (`examples/template-react/*.template.tsx`) are entries; `vite-env.d.ts.template.tsx` is ignored (it's emitted verbatim, never imported).

# When adding new packages or deps

- New package with subpath exports → add an `entry` config for it in `knip.json`.
- New workspace dep added only for build ordering → add it to root `ignoreDependencies` with the others, don't leave Knip red.
- New string-referenced source file → prefer an `entry` for its workspace; fall back to the root `ignore` list (accepting the blind spot: `ignore` suppresses all issue types for that file). Generated files should be gitignored, which keeps them out of analysis entirely.
- After any of the above, `pnpm knip` must exit 0 before the branch is done.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Committed output of `pnpm run gen` — collapsed in GitHub diffs and excluded
# from language stats. CI (build.yml) verifies it stays in sync with examples/.
playground/src/examples.gen.tsx linguist-generated=true
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ jobs:
- name: Install Dependencies
run: vp install

- name: Check generated files are up to date
run: |
vp run --filter @blocknote/dev-scripts gen
git diff --exit-code || (echo "Generated files are out of date. Run 'pnpm run gen' and commit the result." && exit 1)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
test -z "$(git ls-files --others --exclude-standard)" || (echo "Generated files are missing from the commit. Run 'pnpm run gen' and commit the result." && git ls-files --others --exclude-standard && exit 1)

# `vp run -r build` includes @blocknote/xl-typst-compiler, whose build
# task compiles its Rust wasm when missing or stale (rustup is
# preinstalled on the runners; the pinned toolchain + wasm32 target
Expand Down
51 changes: 0 additions & 51 deletions docs/app/(home)/_components/FAQ.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions docs/app/(home)/_components/FrameworkPill.tsx

This file was deleted.

111 changes: 0 additions & 111 deletions docs/app/(home)/_components/Letter.tsx

This file was deleted.

41 changes: 0 additions & 41 deletions docs/app/(home)/_components/Marquee.tsx

This file was deleted.

15 changes: 0 additions & 15 deletions docs/app/(home)/_components/Shared.tsx

This file was deleted.

Loading
Loading