onivim/oni
Oni: Modern Modal Editing - powered by Neovim
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓21+ active contributors
- ✓Distributed ownership (top contributor 30% of recent commits)
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 6y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/onivim/oni)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/onivim/oni on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: onivim/oni
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/onivim/oni shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across all four use cases
- 21+ active contributors
- Distributed ownership (top contributor 30% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 6y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live onivim/oni
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/onivim/oni.
What it runs against: a local clone of onivim/oni — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in onivim/oni | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 2255 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of onivim/oni. If you don't
# have one yet, run these first:
#
# git clone https://github.com/onivim/oni.git
# cd oni
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of onivim/oni and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "onivim/oni(\\.git)?\\b" \\
&& ok "origin remote is onivim/oni" \\
|| miss "origin remote is not onivim/oni (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "browser/src/App.ts" \\
&& ok "browser/src/App.ts" \\
|| miss "missing critical file: browser/src/App.ts"
test -f "browser/src/Editor/NeovimEditor/NeovimEditor.tsx" \\
&& ok "browser/src/Editor/NeovimEditor/NeovimEditor.tsx" \\
|| miss "missing critical file: browser/src/Editor/NeovimEditor/NeovimEditor.tsx"
test -f "browser/src/Redux/createStore.ts" \\
&& ok "browser/src/Redux/createStore.ts" \\
|| miss "missing critical file: browser/src/Redux/createStore.ts"
test -f "browser/src/Plugins/PluginManager.ts" \\
&& ok "browser/src/Plugins/PluginManager.ts" \\
|| miss "missing critical file: browser/src/Plugins/PluginManager.ts"
test -f "browser/src/Renderer/CanvasRenderer.ts" \\
&& ok "browser/src/Renderer/CanvasRenderer.ts" \\
|| miss "missing critical file: browser/src/Renderer/CanvasRenderer.ts"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 2255 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2225d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/onivim/oni"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
Oni is a Neovim-powered modal editor combining Vim's editing power with modern IDE features like code completion, inline diagnostics, embedded browser, and fuzzy finding. It wraps Neovim in a cross-platform Electron/React UI (written in 2.3MB of TypeScript) to deliver a unified experience between modal editing and contemporary IDE capabilities. Monolithic Electron app structured as browser/ (React+TypeScript rendering layer) with src/Editor/NeovimEditor/ (the core Neovim bridge and editor state). State is managed via Redux with NeovimEditorStore.ts and NeovimEditorReducer.ts at browser/src/Editor/NeovimEditor/. Plugins/config live in .oni/ directory with JavaScript config entry point at .oni/config.js.
Who it's for
Vim users and developers who want Neovim's modal editing efficiency without abandoning IDE features like LSP-based completion, hover tooltips, and syntax error overlays. Also attractive to developers who value extensibility and want a keyboard-centric alternative to VSCode but with Vim semantics.
Maturity & risk
Abandoned in active maintenance—the README explicitly states the project is unmaintained with focus shifted to Onivim 2 and libvim. CI pipelines (Travis, AppVeyor) are configured and codecov integration exists, but this is a legacy codebase no longer receiving feature development or patches.
This is a dormant project: any contributions will not be merged, bugs will not be fixed by maintainers, and it depends on Neovim versions that may have aged out. There is no active issue triage or PR review process. Using this in production would be reckless; it exists as historical reference or for personal forks only.
Active areas of work
Nothing. The README states focus has moved to Onivim 2 (Reason-based rewrite) and libvim (Neovim library extraction). This repository receives no active commits, PRs, or maintenance.
Get running
Clone: git clone https://github.com/onivim/oni.git. Install: check .nvmrc for Node version, then yarn install (uses Yarn per .yarnrc). Build/run: consult the wiki at https://github.com/onivim/oni/wiki/Development (exact commands not in provided file list, but package.json scripts would define dev/build targets).
Daily commands:
Exact commands unavailable from file list—consult .travis.yml (CI config) and wiki. Likely: yarn dev or yarn start to launch Electron dev mode. Build for distribution likely: yarn build or yarn package.
Map of the codebase
browser/src/App.ts— Application root entry point orchestrating the main editor initialization and component hierarchybrowser/src/Editor/NeovimEditor/NeovimEditor.tsx— Core Neovim editor integration component; primary interface between Oni UI and Neovim backendbrowser/src/Redux/createStore.ts— Redux store configuration managing global state for editor, buffers, and UI statebrowser/src/Plugins/PluginManager.ts— Plugin system orchestrator loading, initializing, and managing plugin lifecyclebrowser/src/Renderer/CanvasRenderer.ts— Canvas-based text rendering engine responsible for drawing editor content and performancebrowser/src/Input/KeyBindings.ts— Keyboard binding resolution mapping user input to editor commands and Neovim operationsbrowser/src/Editor/BufferManager.ts— Central buffer lifecycle manager tracking open files, modifications, and buffer metadata
How to make changes
Add a New Buffer Layer (Visual Enhancement)
- Create new layer component in browser/src/Editor/OniEditor/ extending React.Component (
browser/src/Editor/OniEditor/IndentGuideBufferLayer.tsx) - Implement BufferLayerRender interface to draw on canvas after text render (
browser/src/Editor/NeovimEditor/BufferLayerManager.ts) - Register layer in NeovimBufferLayersView by adding to layer array (
browser/src/Editor/NeovimEditor/NeovimBufferLayersView.tsx) - Export from browser/src/Editor/OniEditor/index.ts for integration (
browser/src/Editor/OniEditor/index.ts)
Add a New Plugin API Method
- Define new method signature on Oni interface in plugin API (
browser/src/Plugins/Api/Oni.ts) - Implement method handler dispatching Redux action or calling editor service (
browser/src/Editor/NeovimEditor/NeovimEditorActions.ts) - Add corresponding action creator and type to the actions file (
browser/src/Editor/NeovimEditor/NeovimEditorActions.ts) - Update reducer to handle new action type (
browser/src/Editor/NeovimEditor/NeovimEditorReducer.ts) - Document API method in plugin documentation and test with sample plugin (
browser/src/Plugins/Plugin.ts)
Add a New Editor Command
- Create command handler in NeovimEditorCommands dispatching to Neovim (
browser/src/Editor/NeovimEditor/NeovimEditorCommands.ts) - Wire command to keybinding in KeyBindings resolver (
browser/src/Input/KeyBindings.ts) - Optionally expose via plugin API if third-party accessible (
browser/src/Plugins/Api/Oni.ts) - Update state reducer if command modifies editor state (
browser/src/Editor/NeovimEditor/NeovimEditorReducer.ts)
Integrate a New Language Service (LSP)
- Create language client configuration in plugin or as built-in service (
browser/src/Plugins/Api/LanguageClient/LanguageClientHelpers.ts) - Register in Services API to expose to plugins (
browser/src/Plugins/Api/Services.ts) - Wire hover provider through HoverRenderer component (
browser/src/Editor/NeovimEditor/HoverRenderer.tsx) - Connect completion through CompletionMenu for omnifunc integration (
browser/src/Editor/NeovimEditor/CompletionMenu.ts) - Wire definition/symbol lookups through Definition and Symbols modules (
browser/src/Editor/NeovimEditor/Definition.ts)
Why these technologies
- Neovim subprocess — Provides proven
Traps & gotchas
No explicit Neovim binary requirement listed, but code assumes Neovim is installed and on PATH or configured via environment. The Electron context may have IPC security constraints not visible in TypeScript files. .nvmrc pins Node version (check file for exact version). Vim Script plugins in the repo (311KB) are compiled in; modifying them requires Vim knowledge parallel to TypeScript. Redux DevTools integration likely expected in dev but not configured in visible files. Package.json not in provided list—exact dependencies and build tooling hidden.
Architecture
Concepts to learn
- Neovim RPC (Remote Procedure Call) — Oni communicates with Neovim as a subprocess via msgpack-rpc; understanding request/response patterns and event subscriptions is critical for any editor or actions code
- Modal editing (Vim modes: Normal, Insert, Visual) — Core to Oni's identity; the entire UI (keybindings, cursor rendering, completion triggers) must adapt based on Neovim's current mode
- Redux state management — Oni's editor state (buffer content, cursor position, completions, diagnostics) flows through Redux; reducers and selectors are the contract between Neovim events and React rendering
- Grid-based text rendering (Neovim grid protocol) — Neovim outputs a character grid (like old terminal UIs); NeovimRenderer.tsx must convert this sparse grid into efficient React components
- Language Server Protocol (LSP) — Completions, hover info, and diagnostics in Oni come from LSP servers (not built-in); understanding how LSP responses map to BufferLayerManager decorations is crucial for IDE features
- Buffer layer decoration (highlight regions, error underlines) — Oni overlays syntax errors and highlights on top of Neovim's base grid; BufferLayerManager.ts is the abstraction managing non-text visual layers
- Electron IPC (Inter-Process Communication) — Oni runs as an Electron app with a main process and renderer process; any native calls or Neovim subprocess spawning likely uses Electron IPC
Related repos
onivim/oni2— Official successor to Oni, rewritten in Reason/OCaml with better performance; this is where active development movedonivim/libvim— Extracted Neovim core as a library; used by Oni2 and enables embedding Vim semantics without subprocess overheadneovim/neovim— The Neovim project itself—Oni is a UI wrapper around Neovim's core; understanding Neovim's RPC protocol is essentialvim/vim— Original Vim; Neovim is a fork, and Oni inherits all Vim semantics and scripting, making Vim docs relevantMicrosoft/vscode— Oni was inspired by VSCode's UI patterns and feature set (completion menu, status bar, integrated file explorer); shares the same Electron + TypeScript stack
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for NeovimEditor state management (NeovimEditorReducer.ts, NeovimEditorSelectors.ts)
The NeovimEditor directory contains critical Redux-style state management files (Reducer, Selectors, Store, Actions) but there's no visible test directory for these modules. Given the complexity of editor state (buffer management, window state, completion menu state), comprehensive unit tests would prevent regressions and make the codebase more maintainable for future contributors. This is especially important since the state drives the entire UI rendering pipeline.
- [ ] Create browser/src/Editor/NeovimEditor/tests/ directory
- [ ] Add tests for NeovimEditorReducer.ts covering major action handlers (buffer changes, window resizing, completion state)
- [ ] Add tests for NeovimEditorSelectors.ts covering key selectors (active buffer, cursor position, hover state)
- [ ] Set up test infrastructure (Jest config if not present) to run with existing CI pipeline
Add GitHub Actions workflow to replace Travis CI / AppVeyor deprecation path
The repo currently uses .travis.yml and appveyor.yml for CI, but Travis CI has deprecated their free tier. Since the README shows build badges and the project needs continuous integration, migrating to GitHub Actions (which is free and integrated) would modernize the CI/CD pipeline. This is a concrete, high-value task that unblocks the entire project's testing infrastructure.
- [ ] Create .github/workflows/ci.yml with Node.js/Yarn build and test jobs
- [ ] Ensure the workflow runs on push and pull_request to master/main
- [ ] Replicate any test/build commands from .travis.yml and appveyor.yml
- [ ] Update README.md to use GitHub Actions badge instead of Travis/AppVeyor badges
- [ ] Verify codecov integration works with the new workflow
Add integration tests for BufferManager.ts and BufferHighlights.ts buffer operations
The Editor module contains foundational buffer management logic (BufferManager.ts, BufferHighlights.ts) but there's no evidence of integration tests validating buffer lifecycle (create, read, update, delete), highlight layers, or synchronization with Neovim state. These are core operations that multiple UI components depend on, making test gaps high-risk for regressions.
- [ ] Create browser/src/Editor/tests/ directory for buffer integration tests
- [ ] Add tests for BufferManager.ts: buffer creation, switching, closing, and metadata updates
- [ ] Add tests for BufferHighlights.ts: highlight layer management and coordinate transformations
- [ ] Mock Neovim communication layer to test state synchronization
- [ ] Integrate tests into CI pipeline to run before merge
Good first issues
- Add missing unit tests for browser/src/Editor/NeovimEditor/BufferHighlights.ts (file exists but likely has zero test coverage); write basic tests covering highlight application to buffer ranges
- Document the Neovim RPC protocol flow in browser/src/Editor/NeovimEditor/NeovimEditorActions.ts with inline comments; currently opaque which rpc methods map to Vim commands
- Implement hover tooltip position collision detection in browser/src/Editor/NeovimEditor/HoverRenderer.tsx to prevent tooltips from rendering off-screen on small windows
Top contributors
- @akinsho — 30 commits
- @bryphe — 25 commits
- @feltech — 8 commits
- @psxpaul — 7 commits
- @CrossR — 6 commits
Recent commits
17ceaa4— Update README.md (bryphe)b5e57ce— Remove text about ongoing development (#2757) (corollari)ebe9ffd— Update BACKERS.md - thank you! (bryphe)3df2f8b— README: Clean up old links (bryphe)50d89d1— Remove bs-platform dependency (#2735) (bryphe)205e0bc— Update config.yml with new insiders (bryphe)285a9a3— Fix upath conflict (#2729) (TalAmuyal)1068d8d— Update BACKERS.md - thank you! (bryphe)adea2d1— Update BACKERS.md - thank you! :) (bryphe)88bfec7— Update BACKERS.md - thank you for your support! :) (bryphe)
Security observations
The Oni codebase presents moderate security concerns primarily stemming from its unmaintained status and potential vulnerabilities in plugin systems and external integrations. The browser-based architecture introduces XSS and CSP risks, while the plugin system could enable arbitrary code execution. The shift to Onivim 2 means security patches are unlikely. Critical recommendations include migrating to the maintained version, implementing plugin sandboxing, adding comprehensive input validation, and establishing security headers. The codebase would benefit from a formal security audit and adoption of security best practices for browser-based applications with external plugin capabilities.
- High · Unmaintained Project with Outdated Dependencies —
README.md, entire codebase. The repository is explicitly marked as unmaintained in the README, with development focus shifted to Onivim 2 and libvim. This means security patches and vulnerability fixes are unlikely to be applied. Dependencies may contain known vulnerabilities that will not be addressed. Fix: Migrate to the actively maintained Onivim 2 project (https://github.com/onivim/oni2) or implement a comprehensive dependency audit and patching strategy if continued use is necessary. - Medium · Potential XSS Risk in React Components —
browser/src/Editor/NeovimEditor/*.tsx files. Multiple React component files (.tsx/.ts) are present without visible sanitization patterns. Components like HoverRenderer.tsx, NeovimPopupMenu.tsx, and WelcomeBufferLayer.tsx could potentially render unsanitized content from language servers or plugins without proper escaping. Fix: Implement Content Security Policy (CSP) headers, use React's built-in XSS protection (avoid dangerouslySetInnerHTML), sanitize all external input using libraries like DOMPurify, and perform security code review of all component rendering logic. - Medium · Plugin System Security - Arbitrary Code Execution Risk —
browser/src/Plugins/. The presence of AnonymousPlugin.ts and a Plugins directory with API capabilities suggests plugins can execute arbitrary code. Without proper sandboxing or permissions model, malicious plugins could compromise the entire application. Fix: Implement plugin sandboxing using Web Workers or separate processes, establish a plugin permission system, validate and sign plugins, maintain a plugin allowlist, and provide clear warnings about plugin security implications to users. - Medium · Configuration File Security —
.oni/config.js. The .oni/config.js file could potentially contain sensitive configuration. JavaScript configuration files can be vulnerable to injection if they process untrusted input or if loaded from untrusted sources. Fix: Validate and sanitize all configuration input, use JSON instead of JavaScript for config files if possible, implement strict schema validation, restrict file permissions on config files, and never store secrets in configuration files. - Low · Missing Security Headers in Browser Context —
browser/src/App.ts, global configuration. No evidence of security headers (CSP, X-Frame-Options, X-Content-Type-Options, etc.) in the visible codebase structure. This could allow various browser-based attacks. Fix: Implement Content Security Policy with strict directives, set X-Frame-Options to DENY or SAMEORIGIN, implement X-Content-Type-Options: nosniff, X-XSS-Protection headers, and Referrer-Policy. - Low · Language Server Integration Security —
browser/src/Plugins/Api/LanguageClient/. Files like LanguageClient/LanguageClientLogger.ts and LanguageClientHelpers.ts indicate integration with language servers. External language servers may not be fully trusted or could be compromised. Fix: Validate language server responses, implement input validation on all language server communication, use checksums/signatures for language server binaries, run language servers in isolated processes, and implement timeout mechanisms. - Low · No Visible Dependency Lock File in File Structure —
package.json equivalent. While .yarnrc and .nvmrc are present, no package-lock.json or yarn.lock file content is provided in the analysis. This makes it difficult to assess if dependencies are pinned to specific versions. Fix: Ensure yarn.lock or package-lock.json is committed to the repository, use deterministic dependency resolution, regularly audit dependencies with 'yarn audit' or 'npm audit', and keep all dependencies updated.
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.