@prose-motions/core
is a lightweight extension that brings Vim's Normal / Insert modes and an ever-growing collection of native keybindings to any Tiptap (v2) or ProseMirror editor.
Esc
/i
to toggle modes- Cursor motions:
h
j
k
l
- Word-back with
b
- Delete current line with
dd
- Blocks text input in Normal mode to match Vim behaviour
Designed to be drop-in: no external CSS, no runtime deps beyond Tiptap itself.
bun add @prose-motions/core # or npm/yarn/pnpm
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { VimMode } from '@prose-motions/core'
function MyEditor () {
const editor = useEditor({
extensions: [StarterKit, VimMode],
content: '<p>hello world</p>'
})
return <EditorContent editor={editor} />
}
import { useState } from 'react'
import {
ProseMirror,
ProseMirrorDoc,
reactKeys,
} from '@handlewithcare/react-prosemirror'
import { EditorState } from 'prosemirror-state'
import { schema } from 'prosemirror-schema-basic'
import { VimMode } from '@prose-motions/core'
export default function MyProseMirror () {
return (
<ProseMirror
defaultState={EditorState.create({
schema,
plugins: [
// The reactKeys plugin is required for the ProseMirror component to work!
reactKeys(),
...VimMode.addProseMirrorPlugins()
],
})}
>
<ProseMirrorDoc />
</ProseMirror>
);
}
This snippet uses the modern "React × ProseMirror" bridge maintained by Handle with Care (handlewithcarecollective/react-prosemirror). It automatically handles state-tearing issues by updating the
EditorView
inside a layout effect
Intentionally minimal and built with modern tooling, Prose Motions adds powerful Vim keybindings to your editor without the bloat - perfect for developers who value efficiency:
- TypeScript-first – the whole codebase is written in strict TS so extending the keybinding set feels like ordinary app code, no fiddling with build steps.
- ProseMirror plugin architecture – every keybinding (motions, operators, text-objects…) is ultimately a pure command that manipulates the editor state through transactions; no DOM tricks involved. See the ProseMirror reference for details (docs).
- Tiptap v2 wrapper – the extension registers itself as a standard
Extension
so it works out-of-the-box in Tiptap powered editors and any wrapper that exposes the underlying ProseMirror view. (tiptap.dev) - Optimized Bundle – Built with Bun for ESM modules with tree-shaking optimization. Tiny footprint in your application bundle.
- Zero runtime deps – no CSS frameworks, no helper libs. The only peer deps are the editor engines themselves (
@tiptap/core
,prosemirror-state
).
Thanks to ProseMirror's declarative state → transaction → new-state we can express complex Vim behaviour in plain TypeScript (see the ProseMirror State guide). Want to add
w
,yy
, or repeat counts? Just compose new commands – no native code compilation, no browser-specific hacks.
If you're new to Vim motions or were pointed here by colleagues, we recommend reading "Why Vim Is More than Just an Editor – Vim Language, Motions, and Modes Explained". It's an excellent introduction to the concepts that make Vim-style editing so powerful.
- fix: cmd - v mod override persists in insert mode
- Repeat counts (
5j
), more operators (dw
,yy
,p
) - Proper line height calculation to avoid layout thrash
- Performance micro-optimisations
- windows / linux mode change support
- editor sandbox
- @prose-motions/styles package / caret transform support in normal vs insert mode
- config layer / i.e, change caret size or color, choose if editor defaults to normal or insert mode (currently defaults to insert mode)
- CI / automated publishing flow
- Complete Vim key-binding coverage — implement the full command set documented in
:help index
We're on a mission to keep this package lean and mean. Check out our size stats:
Initial Size (January 2025) | Latest Size | Change |
---|---|---|
4.52 kB | 4.52 kB | +0.0 kB |
Let's see if we can add awesome features while keeping our package fit. Every byte counts, but fun counts more!
Product | Description |
---|---|
Grit AI | The AI Note Editor |
Contributions & ideas are welcome – open an issue or PR.