Skip to main content

Quickstart

Get started with CodeInk in less than 60 seconds. No account required, no installation needed.
CodeInk runs entirely in your browser. Your documents are stored locally and never sent to any server.

Create your first document

1

Open the editor

Navigate to the documents page or click “Get started” from the homepage.When you open CodeInk for the first time, a new document is automatically created with example content showing all major features.
src/scripts/editor.ts
async function createNewDocument(): Promise<{ docId: string; createdAt: number }> {
  const docId = crypto.randomUUID()
  const now = Date.now()
  const doc: Document = {
    id: docId,
    title: extractTitle(DEFAULT_MARKDOWN),
    content: DEFAULT_MARKDOWN,
    createdAt: now,
    updatedAt: now,
  }
  await saveDoc(doc)
  window.history.replaceState(null, "", `/editor#${docId}`)
  return { docId, createdAt: now }
}
Each document gets a unique UUID stored in the URL hash (e.g., /editor#abc-123-def). Bookmark the URL to return to your document later.
2

Write some Markdown

Start typing in the left pane. The preview updates in real-time on the right.Try this example:
# My first document

This is **bold text** and this is *italic text*.

## Code example

Here's some TypeScript:

```typescript
function greet(name: string): string {
  return `Hello, ${name}!`
}

console.log(greet("World"))

As you type, the status bar at the bottom shows:
- Line count
- Word count
- Character count
- Save status

```typescript src/scripts/status-bar.ts
export function updateStatusBar(content: string) {
  const lines = content.split("\n").length
  const words = content.trim().split(/\s+/).filter(Boolean).length
  const chars = content.length

  document.getElementById("line-count")!.textContent = `${lines} lines`
  document.getElementById("word-count")!.textContent = `${words} words`
  document.getElementById("char-count")!.textContent = `${chars} chars`
}
3

Add syntax highlighting

CodeInk automatically highlights code blocks using Shiki, the same engine that powers VS Code.Supported languages include:
  • JavaScript, TypeScript, JSX, TSX
  • Python, Rust, Go, Java, Kotlin
  • HTML, CSS, SCSS, Tailwind
  • SQL, GraphQL, YAML, JSON, TOML
  • Bash, Docker, Terraform, HCL
  • And 16+ more
Try adding a Python code block:
```python
def factorial(n: int) -> int:
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # Output: 120
```
Always specify the language for code blocks (e.g., ```python) to enable syntax highlighting.
4

Create a diagram

Add a Mermaid diagram to visualize your ideas. CodeInk renders diagrams in real-time.Try this flowchart:
```mermaid
graph TD
    A[User opens CodeInk] --> B{First time?}
    B -->|Yes| C[Create new document]
    B -->|No| D[Load existing document]
    C --> E[Show example content]
    D --> E
    E --> F[User writes Markdown]
    F --> G[Auto-save to IndexedDB]
```
Or try a sequence diagram:
```mermaid
sequenceDiagram
    participant User
    participant Editor
    participant Preview
    participant IndexedDB

    User->>Editor: Type Markdown
    Editor->>Preview: Update content
    Preview->>Preview: Render HTML
    Editor->>IndexedDB: Auto-save after 1s
    IndexedDB-->>Editor: Confirm save
```
Mermaid supports 15+ diagram types including flowcharts, sequence diagrams, ER diagrams, Gantt charts, class diagrams, state diagrams, and more.
5

Add math equations

Use KaTeX to render LaTeX math expressions.For inline math, use single dollar signs:
The quadratic formula is $x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$.
For display math, use double dollar signs:
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$
Try adding this matrix multiplication:
$$
\begin{pmatrix}
1 & 2 \\
3 & 4
\end{pmatrix}
\times
\begin{pmatrix}
5 & 6 \\
7 & 8
\end{pmatrix}
=
\begin{pmatrix}
19 & 22 \\
43 & 50
\end{pmatrix}
$$
6

Switch view modes

Use the view mode buttons at the top of the editor to change the layout:
  • Editor: Full-width editor (great for writing)
  • Split: Side-by-side editor and preview (default)
  • Preview: Full-width preview (great for reading)
src/scripts/view-mode.ts
export type ViewMode = "split" | "editor" | "preview"

function setViewMode(mode: ViewMode) {
  editorRoot.setAttribute("data-view", mode)
  viewEditorBtn?.classList.toggle("active", mode === "editor")
  viewSplitBtn?.classList.toggle("active", mode === "split")
  viewPreviewBtn?.classList.toggle("active", mode === "preview")
}
On mobile devices (width < 640px), CodeInk automatically defaults to editor-only mode.
7

Export your document

Click the “Export” button in the toolbar to download your document as a .md file.The filename is automatically generated from your document’s title (the first # Heading).
src/scripts/export.ts
const content = getEditorContent()
const titleMatch = content.match(/^#\s+(.+)$/m)
const title = titleMatch ? titleMatch[1].trim() : "document"
const sanitized = title.replace(/[^a-z0-9\s-]/gi, "").replace(/\s+/g, "-")
const filename = `${sanitized}.md`

const blob = new Blob([content], { type: "text/markdown;charset=utf-8" })
// ... create download link
Use a clear, descriptive first heading like # Project Requirements so your exported file has a meaningful name like project-requirements.md.

Managing documents

All your documents are listed on the documents page. Here’s what you can do:

View all documents

Documents are sorted by last modified date (most recent first). Each card shows:
  • Document title (extracted from first heading)
  • Content preview (first 100 characters)
  • Last modified time (relative, e.g., “2h ago”)
src/scripts/documents.ts
function formatRelativeTime(ts: number): string {
  const diff = Date.now() - ts
  if (diff < 60000) return "Just now"
  if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`
  if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`
  if (diff < 604800000) return `${Math.floor(diff / 86400000)}d ago`
  return new Date(ts).toLocaleDateString()
}

Rename a document

Hover over a document card and click the pencil icon. Type a new title (max 20 characters) and press Enter.
src/scripts/documents.ts
function handleRename(wrapper: HTMLElement, id: string, rerender: () => void) {
  const h3 = wrapper.querySelector(".doc-title") as HTMLElement
  const currentTitle = h3.textContent || ""
  const input = document.createElement("input")
  input.type = "text"
  input.value = currentTitle
  input.maxLength = MAX_TITLE_LENGTH // 20 characters
  
  // ... handle input and save
}
Custom titles are limited to 20 characters. If you don’t set a custom title, CodeInk uses the first heading from your document.

Delete a document

Hover over a document card and click the trash icon. Confirm the deletion in the browser prompt.
src/scripts/documents.ts
async function handleDelete(id: string, rerender: () => void) {
  if (!confirm("Delete this document?")) return
  await deleteDoc(id)
  rerender()
}
Deleted documents cannot be recovered. CodeInk does not have a trash or recycle bin.

Create a new document

Click the “Create new document” button on the documents page. CodeInk generates a unique UUID and loads the editor with example content.

Using markdown linting

CodeInk includes real-time Markdown linting powered by remark-lint.

View lint diagnostics

Lint issues appear as:
  • Wavy underlines in the editor
  • A count in the status bar (e.g., “3 issues”)
Hover over an underlined section to see the specific issue.

Auto-fix issues

Click the “Fix” button in the status bar to automatically fix common issues:
  • Missing spaces after heading markers (e.g., #Heading# Heading)
  • Inconsistent list markers
  • Inconsistent emphasis markers
  • Extra blank lines
src/scripts/markdown-linter.ts
export function fixMarkdown(text: string): string {
  try {
    const file = processor.processSync(text)
    return file.toString()
  } catch (err) {
    console.error("Markdown fix failed", err)
    return text
  }
}
The auto-fix feature uses remark-stringify to reformat your Markdown with consistent style: - for bullet lists, _ for emphasis, * for strong, and - for horizontal rules.

Keyboard shortcuts

CodeInk leverages CodeMirror 6’s built-in keyboard shortcuts:
ShortcutAction
Cmd/Ctrl + BBold selection
Cmd/Ctrl + IItalic selection
Cmd/Ctrl + ZUndo
Cmd/Ctrl + Shift + ZRedo
Cmd/Ctrl + FFind
Cmd/Ctrl + HFind and replace
TabIndent line/selection
Shift + TabOutdent line/selection
CodeMirror automatically handles most common editing operations. Full keyboard shortcut documentation is available in the CodeMirror 6 docs.

Privacy and data storage

CodeInk is designed with privacy as a core principle:

100% client-side

All Markdown processing, rendering, and storage happens in your browser. No data is ever sent to a server.

IndexedDB storage

Documents are stored in your browser’s IndexedDB. They persist across sessions but are limited to one browser.

No tracking

Zero analytics, zero cookies, zero tracking scripts. CodeInk doesn’t know you exist.

No accounts

No signup, no login, no passwords. Your documents are tied to your browser, not to an account.

Storage limits

IndexedDB storage is subject to browser quota limits (typically 50% of available disk space). If you hit the limit, you’ll need to delete old documents or export them as files.

Clearing data

To delete all CodeInk data:
  1. Open browser DevTools (F12)
  2. Go to Application → Storage
  3. Find “IndexedDB” → “codeink-docs”
  4. Right-click and select “Delete database”
Alternatively, clear all site data for CodeInk in your browser settings.

Next steps

Now that you know the basics, explore more features:

Mermaid diagrams

Learn all Mermaid diagram types with examples

KaTeX math

Master LaTeX math syntax for equations and formulas

Document management

Learn how to organize and manage your documents

GitHub repository

Contribute to CodeInk or report issues

Build docs developers (and LLMs) love