Getting Started
For LLMs, see /llms.txt.
Inkwell is a Markdown editor and renderer for React that treats Markdown as the canonical content.
You write and edit content in a visual WYSIWYG interface, but the underlying content is always the Markdown source; the Markdown source is the text.
It ships with WYSIWYG basics such as bold, italic, strike, code,
and an extensible plugin system with batteries included for
everything else.
Installation
Section titled “Installation”npm install @railway/inkwellpnpm add @railway/inkwellyarn add @railway/inkwellbun add @railway/inkwellRequires React 19 or later as a peer dependency.
Editor
Section titled “Editor”Render InkwellEditor with a content string and an onChange handler.
import { InkwellEditor } from "@railway/inkwell";import { useState } from "react";import "@railway/inkwell/styles.css";
function App() { const [content, setContent] = useState("# Hello **world**");
return <InkwellEditor content={content} onChange={setContent} />;}This gives you a fully featured Markdown editor out of the box:
- Block formatting — headings, blockquotes, and fenced code blocks, all triggered by typing their Markdown syntax
- Inline formatting — bold, italic, strikethrough, and inline code, rendered visually as you type
- Floating toolbar — select text to reveal bold, italic, and strikethrough buttons
- Syntax highlighting — fenced code blocks are highlighted automatically
- Keyboard shortcuts —
⌘Bbold,⌘Iitalic,⌘Dstrikethrough
The floating toolbar is powered by the Bubble Menu plugin.
Rendering Markdown
Section titled “Rendering Markdown”InkwellRenderer turns a Markdown string into formatted HTML. No browser
dependencies — works anywhere React runs, including server-side rendering.
import { InkwellRenderer } from "@railway/inkwell";import "@railway/inkwell/styles.css";
function Preview({ content }: { content: string }) { return <InkwellRenderer content={content} />;}Pair them together for a live preview:
import { InkwellRenderer, InkwellEditor } from "@railway/inkwell";import "@railway/inkwell/styles.css";import { useState } from "react";
function EditorWithPreview() { const [content, setContent] = useState("# Hello **world**");
return ( <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}> <InkwellEditor content={content} onChange={setContent} /> <InkwellRenderer content={content} /> </div> );}Styling
Section titled “Styling”Inkwell ships default editor, plugin, and renderer styles. Import them once in your app entry point:
import "@railway/inkwell/styles.css";You can override any class to match your product. See the Styling guide for the full list of CSS classes.