Comprehensive starter kit extension for Tiptap editor with essential extensions bundled together
npx @tessl/cli install tessl/npm-tiptap--starter-kit@3.4.0The Tiptap Starter Kit provides a comprehensive collection of essential editor extensions bundled together for quick setup of rich-text editing functionality. It's built on top of the headless Tiptap editor framework and includes 20+ commonly needed extensions like text formatting, document structure, lists, links, and editor utilities.
npm install @tiptap/starter-kitimport { StarterKit } from "@tiptap/starter-kit";
import type { StarterKitOptions } from "@tiptap/starter-kit";Default import:
import StarterKit from "@tiptap/starter-kit";CommonJS:
const { StarterKit } = require("@tiptap/starter-kit");import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
// Use with default configuration (all extensions enabled)
const editor = new Editor({
element: document.querySelector("#editor"),
extensions: [StarterKit],
content: "<p>Hello World!</p>",
});
// Use with selective configuration
const customEditor = new Editor({
element: document.querySelector("#editor"),
extensions: [
StarterKit.configure({
// Disable some extensions
bold: false,
italic: false,
// Configure others
heading: {
levels: [1, 2, 3],
},
link: {
openOnClick: false,
HTMLAttributes: {
class: "custom-link",
},
},
}),
],
content: "<h1>Custom Editor</h1><p>With selective extensions.</p>",
});Creates a bundled extension containing 20+ essential Tiptap extensions for rich-text editing. Each bundled extension can be individually configured or disabled.
const StarterKit: Extension<StarterKitOptions>;Usage Examples:
// Use with default configuration (all extensions enabled)
const editor = new Editor({
extensions: [StarterKit],
});
// Configure specific extensions
const editor = new Editor({
extensions: [
StarterKit.configure({
bold: false, // Disable bold
heading: { levels: [1, 2, 3] }, // Configure heading levels
link: { openOnClick: true }, // Configure link behavior
}),
],
});
// Extend with additional functionality
const customExtension = StarterKit.extend({
name: 'customStarterKit',
addCommands() {
return {
customCommand: () => ({ commands }) => {
// Custom command implementation
return true;
},
};
},
});Configuration interface for enabling/disabling and customizing bundled extensions.
interface StarterKitOptions {
// Text formatting extensions
bold: Partial<BoldOptions> | false;
italic: Partial<ItalicOptions> | false;
underline: Partial<UnderlineOptions> | false;
strike: Partial<StrikeOptions> | false;
code: Partial<CodeOptions> | false;
// Document structure extensions
document: false;
paragraph: Partial<ParagraphOptions> | false;
heading: Partial<HeadingOptions> | false;
blockquote: Partial<BlockquoteOptions> | false;
horizontalRule: Partial<HorizontalRuleOptions> | false;
hardBreak: Partial<HardBreakOptions> | false;
text: false;
// List extensions
bulletList: Partial<BulletListOptions> | false;
orderedList: Partial<OrderedListOptions> | false;
listItem: Partial<ListItemOptions> | false;
listKeymap: Partial<ListKeymapOptions> | false;
// Code extensions
codeBlock: Partial<CodeBlockOptions> | false;
// Link extensions
link: Partial<LinkOptions> | false;
// Editor utilities
undoRedo: Partial<UndoRedoOptions> | false;
dropcursor: Partial<DropcursorOptions> | false;
gapcursor: false;
trailingNode: Partial<TrailingNodeOptions> | false;
}Configuration Examples:
// Disable specific extensions
const minimalConfig: Partial<StarterKitOptions> = {
bold: false,
italic: false,
underline: false,
strike: false,
};
// Configure extension options
const customConfig: Partial<StarterKitOptions> = {
heading: {
levels: [1, 2, 3, 4], // Only allow h1-h4
},
link: {
openOnClick: false,
HTMLAttributes: {
class: "editor-link",
rel: "nofollow",
},
},
codeBlock: {
HTMLAttributes: {
class: "code-block",
},
},
};
// Mix of disabled and configured extensions
const hybridConfig: Partial<StarterKitOptions> = {
// Disable some extensions
underline: false,
horizontalRule: false,
dropcursor: false,
// Configure others
blockquote: {
HTMLAttributes: {
class: "custom-blockquote",
},
},
bulletList: {
HTMLAttributes: {
class: "bullet-list",
},
},
};The StarterKit includes the following extensions:
**text** or Ctrl+B)*text* or Ctrl+I)~~text~~)`code`)# syntax support> syntax)--- syntax)- or * syntax)1. syntax)// Core extension from @tiptap/core
interface Extension<Options = any, Storage = any> {
configure(options?: Partial<Options>): Extension<Options, Storage>;
extend<ExtendedOptions = Options, ExtendedStorage = Storage>(
extendedConfig?: Partial<ExtensionConfig<ExtendedOptions, ExtendedStorage>>
): Extension<ExtendedOptions, ExtendedStorage>;
}
// Base extension types (imported from respective extension packages)
interface BoldOptions {
/**
* HTML attributes to add to the bold element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface ItalicOptions {
/**
* HTML attributes to add to the italic element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface HeadingOptions {
/**
* The available heading levels.
* @default [1, 2, 3, 4, 5, 6]
*/
levels: number[];
/**
* The HTML attributes for a heading node.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface LinkOptions {
/**
* If enabled, the extension will automatically add links as you type.
* @default true
*/
autolink: boolean;
/**
* An array of custom protocols to be registered with linkifyjs.
* @default []
*/
protocols: Array<LinkProtocolOptions | string>;
/**
* Default protocol to use when no protocol is specified.
* @default 'http'
*/
defaultProtocol: string;
/**
* If enabled, links will be opened on click.
* @default true
*/
openOnClick: boolean;
/**
* If enabled, the link will be selected when clicked.
* @default false
*/
enableClickSelection: boolean;
/**
* Adds a link to the current selection if the pasted content only contains an url.
* @default true
*/
linkOnPaste: boolean;
/**
* HTML attributes to add to the link element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
/**
* @deprecated Use the `shouldAutoLink` option instead.
* A validation function that modifies link verification for the auto linker.
*/
validate: (url: string) => boolean;
/**
* A validation function which is used for configuring link verification for preventing XSS attacks.
* Only modify this if you know what you're doing.
*/
isAllowedUri: (
url: string,
ctx: {
defaultValidate: (url: string) => boolean;
protocols: Array<LinkProtocolOptions | string>;
defaultProtocol: string;
}
) => boolean;
/**
* Determines whether a valid link should be automatically linked in the content.
*/
shouldAutoLink: (url: string) => boolean;
}
interface CodeBlockOptions {
/**
* Adds a prefix to language classes that are applied to code tags.
* @default 'language-'
*/
languageClassPrefix: string;
/**
* Define whether the node should be exited on triple enter.
* @default true
*/
exitOnTripleEnter: boolean;
/**
* Define whether the node should be exited on arrow down if there is no node after it.
* @default true
*/
exitOnArrowDown: boolean;
/**
* The default language.
* @default null
*/
defaultLanguage: string | null | undefined;
/**
* Enable tab key for indentation in code blocks.
* @default false
*/
enableTabIndentation: boolean;
/**
* The number of spaces to use for tab indentation.
* @default 4
*/
tabSize: number;
/**
* Custom HTML attributes that should be added to the rendered HTML tag.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface BulletListOptions {
/**
* The node name for the list items
* @default 'listItem'
*/
itemTypeName: string;
/**
* HTML attributes to add to the bullet list element
* @default {}
*/
HTMLAttributes: Record<string, any>;
/**
* Keep the marks when splitting the list
* @default false
*/
keepMarks: boolean;
/**
* Keep the attributes when splitting the list
* @default false
*/
keepAttributes: boolean;
}
interface OrderedListOptions {
/**
* The node name for the list items
* @default 'listItem'
*/
itemTypeName: string;
/**
* HTML attributes to add to the ordered list element
* @default {}
*/
HTMLAttributes: Record<string, any>;
/**
* Keep the marks when splitting the list
* @default false
*/
keepMarks: boolean;
/**
* Keep the attributes when splitting the list
* @default false
*/
keepAttributes: boolean;
}
interface ListItemOptions {
/**
* The HTML attributes for a list item node.
* @default {}
*/
HTMLAttributes: Record<string, any>;
/**
* The node type for bulletList nodes
* @default 'bulletList'
*/
bulletListTypeName: string;
/**
* The node type for orderedList nodes
* @default 'orderedList'
*/
orderedListTypeName: string;
}
interface ListKeymapOptions {
/**
* The node type for bulletList nodes
* @default 'bulletList'
*/
bulletListTypeName: string;
/**
* The node type for orderedList nodes
* @default 'orderedList'
*/
orderedListTypeName: string;
/**
* The node type for listItem nodes
* @default 'listItem'
*/
listItemTypeName: string;
}
interface HardBreakOptions {
/**
* Controls if marks should be kept after being split by a hard break.
* @default true
*/
keepMarks: boolean;
/**
* HTML attributes to add to the hard break element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface DropcursorOptions {
/**
* The color of the drop cursor. Use `false` to apply no color and rely only on class.
* @default 'currentColor'
*/
color?: string | false;
/**
* The width of the drop cursor
* @default 1
*/
width: number | undefined;
/**
* The class of the drop cursor
* @default undefined
*/
class: string | undefined;
}
interface TrailingNodeOptions {
/**
* The node type that should be inserted at the end of the document.
* @note the node will always be added to the `notAfter` lists to
* prevent an infinite loop.
* @default 'paragraph'
*/
node: string;
/**
* The node types after which the trailing node should not be inserted.
* @default ['paragraph']
*/
notAfter?: string | string[];
}
interface UndoRedoOptions {
/**
* The amount of history events that are collected before the oldest events are discarded.
* @default 100
*/
depth: number;
/**
* The delay (in milliseconds) between changes after which a new group should be started.
* @default 500
*/
newGroupDelay: number;
}
interface UnderlineOptions {
/**
* HTML attributes to add to the underline element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface StrikeOptions {
/**
* HTML attributes to add to the strike element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface CodeOptions {
/**
* The HTML attributes applied to the code element.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface BlockquoteOptions {
/**
* HTML attributes to add to the blockquote element
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface ParagraphOptions {
/**
* The HTML attributes for a paragraph node.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface HorizontalRuleOptions {
/**
* The HTML attributes for a horizontal rule node.
* @default {}
*/
HTMLAttributes: Record<string, any>;
}
interface LinkProtocolOptions {
scheme: string;
optionalSlashes?: boolean;
}import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
const editor = new Editor({
extensions: [
StarterKit.configure({
// Configure heading levels and attributes
heading: {
levels: [1, 2, 3],
HTMLAttributes: {
class: "editor-heading",
},
},
// Configure link behavior
link: {
openOnClick: false,
autolink: true,
protocols: ["http", "https", "mailto"],
HTMLAttributes: {
class: "editor-link",
target: "_blank",
rel: "noopener noreferrer",
},
},
// Configure code blocks
codeBlock: {
languageClassPrefix: "language-",
exitOnTripleEnter: true,
HTMLAttributes: {
class: "code-block",
},
},
}),
],
});// Only enable text formatting and basic structure
const basicEditor = new Editor({
extensions: [
StarterKit.configure({
// Disable lists
bulletList: false,
orderedList: false,
listItem: false,
listKeymap: false,
// Disable advanced features
link: false,
codeBlock: false,
blockquote: false,
// Keep basic formatting
bold: {},
italic: {},
paragraph: {},
heading: { levels: [1, 2] },
}),
],
});import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import { Image } from "@tiptap/extension-image";
import { Table } from "@tiptap/extension-table";
const fullEditor = new Editor({
extensions: [
// Use StarterKit as foundation
StarterKit.configure({
// Configure as needed
heading: { levels: [1, 2, 3] },
}),
// Add additional extensions
Image.configure({
HTMLAttributes: {
class: "editor-image",
},
}),
Table.configure({
resizable: true,
}),
],
});