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-modulesKeystrokes stay inside the frame.
The time to handle a key and draw the result, next to one frame at 60 Hz.
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