# Choosing modules

> Every block, mark and piece of UI is opt-in; here is what each one adds and weighs.

The core ships one block type, the paragraph. Everything else is a module — a plain object you pass to the editor. Importing a module registers nothing by itself, and each one imports its own CSS, so an editor weighs exactly the modules you list.

```js editor.js
import { Editor } from 'verbal-editor';
import heading from 'verbal-editor/blocks/heading';
import code from 'verbal-editor/blocks/code';
import bold from 'verbal-editor/marks/bold';
import toolbar from 'verbal-editor/ui/toolbar';

const editor = new Editor({ blocks: [heading, code], marks: [bold], ui: [toolbar] });
```

## Or take all of them

`verbal-editor/preset` lists every block, mark and UI module, and re-exports the AI review helpers. Spread it into the options and add or remove from its arrays:

```js full.js
import { Editor } from 'verbal-editor';
import preset from 'verbal-editor/preset';

const editor = new Editor({ ...preset, ui: preset.ui.filter((m) => m.name !== 'emoji') });
```

## What each one weighs

Measured from the built package with gzip, the way the size gate in CI measures it. The budget column is the limit that gate enforces.

| Entry | JS gzip | CSS gzip | Budget |
| --- | --- | --- | --- |
| Core: editor + React binding + paragraph | 12.19 KB |  | 12.5KB |
| Full preset: every module | 30.57 KB | 5.00 KB | 31.5KB |
| [blocks/chart](#/docs/modules/blocks/chart) | 1.91 KB | 0.65 KB |  |
| [blocks/code](#/docs/modules/blocks/code) | 2.23 KB | 0.51 KB |  |
| [blocks/columns](#/docs/modules/blocks/columns) | 0.63 KB | 0.25 KB |  |
| [blocks/divider](#/docs/modules/blocks/divider) | 0.29 KB | 0.12 KB |  |
| [blocks/embed](#/docs/modules/blocks/embed) | 1.27 KB | 0.51 KB |  |
| [blocks/heading](#/docs/modules/blocks/heading) | 0.56 KB | 0.16 KB |  |
| [blocks/image](#/docs/modules/blocks/image) | 0.93 KB | 0.17 KB |  |
| [blocks/list](#/docs/modules/blocks/list) | 0.52 KB | 0.29 KB |  |
| [blocks/math](#/docs/modules/blocks/math) | 4.83 KB | 0.62 KB |  |
| [blocks/quote](#/docs/modules/blocks/quote) | 0.33 KB | 0.14 KB |  |
| [blocks/table](#/docs/modules/blocks/table) | 2.47 KB | 0.69 KB |  |
| [blocks/todo](#/docs/modules/blocks/todo) | 0.79 KB | 0.55 KB |  |
| [marks/bold](#/docs/modules/marks/bold) | 0.24 KB | 0.00 KB |  |
| [marks/code](#/docs/modules/marks/code) | 0.17 KB | 0.00 KB |  |
| [marks/italic](#/docs/modules/marks/italic) | 0.22 KB | 0.00 KB |  |
| [marks/link](#/docs/modules/marks/link) | 0.67 KB | 0.00 KB |  |
| [marks/strike](#/docs/modules/marks/strike) | 0.25 KB | 0.00 KB |  |
| [ui/dnd](#/docs/modules/ui/dnd) | 1.84 KB | 0.47 KB |  |
| [ui/emoji](#/docs/modules/ui/emoji) | 0.31 KB | 0.00 KB |  |
| [ui/slash](#/docs/modules/ui/slash) | 1.36 KB | 0.49 KB |  |
| [ui/toolbar](#/docs/modules/ui/toolbar) | 1.29 KB | 0.71 KB |  |
| [ai/diff](#/docs/modules/ai/diff) | 0.65 KB | 0.00 KB |  |
| [ai/pending](#/docs/modules/ai/pending) | 1.57 KB | 0.64 KB |  |

Code languages are not in these numbers: each one loads the first time a block shows it. The emoji index is fetched on the first `:` you type.

## Kinds of module

| Kind | Import from | Examples | Registers |
| --- | --- | --- | --- |
| Blocks | `verbal-editor/blocks/<name>` | heading, table, code | a block type, its slash entries, keys and Markdown rules |
| Marks | `verbal-editor/marks/<name>` | bold, link | a mark, its shortcut and typing rule |
| UI | `verbal-editor/ui/<name>` | slash, toolbar, dnd | menus and interactions, no document content |
| AI | `verbal-editor/ai/<name>` | pending, diff | functions you call; nothing to register |

Every module has a reference page generated from its own source under [Modules](#/docs/modules).

> [!TIP]
> `npx verbal init` asks which modules you want and prints the imports for exactly those — see [CLI](#/docs/cli).
