Skip to main content

A native code editor for React Native.

Its own engine on each platform, Kotlin on Android and Swift on iOS, with tree-sitter highlighting and a Nitro binding. No WebView.

npm install react-native-codepad react-native-nitro-modules

Keystrokes stay inside the frame.

The time to handle a key and draw the result, next to one frame at 60 Hz.

codepad3 ms
one frame16.7 ms

3 ms of work per keystroke on a 10,000 line file, median over 60 keystrokes at 150 ms per key, on iOS, debug build.

7 ms
to reparse a 2,000 line Markdown file with 2,239 injectionson Android, debug build
131 ms
to the first paint of a 100,000 line fileon Android, debug build

Simulator and emulator numbers, kept to catch regressions. Numbers from a real device are welcome in an issue.

Tree-sitter highlighting, one package per language.

Install a language package and pass its id. Your app carries only the languages it uses.

import { CodeEditor } from 'react-native-codepad';
import { typescript } from 'react-native-codepad-lang-typescript';

const source = `export function greet(name: string) {
return "hi " + name;
}
`;

export function HighlightedEditor() {
return (
<CodeEditor
language={typescript}
initialValue={source}
lineNumbers
style={{ flex: 1 }}
/>
);
}

Everything the keyboard does, from JavaScript.

The soft keyboard, hardware keys and the ref all drive the same engine paths.

  • Selection with handles, the loupe and the edit menu
  • Undo and redo with keystrokes grouped into one undo step
  • Auto indent and auto closing brackets and quotes
  • Tab and Shift+Tab to indent and outdent, plus bracket matching and an active line
  • Search literal or regex, replace one or all, every match painted
  • Hardware keys with the full key table
  • A toolbar API that drives the same paths from JavaScript
  • Three themes keyed by nvim-treesitter capture names

Follows the keyboard, frame by frame.

The editor insets itself by the keyboard's overlap and follows the keyboard animation frame by frame.

import { CodeEditor } from 'react-native-codepad';

export function KeyboardAwareEditor() {
return (
<CodeEditor
avoidKeyboard
autoFocus
suggestions="off"
contentInsets={{ bottom: 56 }}
style={{ flex: 1 }}
/>
);
}

And it works with what you use.

  • React Native 0.81+
  • New Architecture
  • Expo development builds
  • react-native-nitro-modules
  • react-native-keyboard-controller
  • react-native-safe-area-context

Start with the installation.