RepoPilotOpen in app →

micro-editor/micro

A modern and intuitive terminal-based text editor

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 24+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

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.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/micro-editor/micro)](https://repopilot.app/r/micro-editor/micro)

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/micro-editor/micro on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: micro-editor/micro

Generated by RepoPilot · 2026-05-09 · 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:

  1. 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.
  2. 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.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/micro-editor/micro 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 the board

  • Last commit today
  • 24+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<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 micro-editor/micro repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/micro-editor/micro.

What it runs against: a local clone of micro-editor/micro — 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 micro-editor/micro | 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 ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>micro-editor/micro</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of micro-editor/micro. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/micro-editor/micro.git
#   cd micro
#
# 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 micro-editor/micro and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "micro-editor/micro(\\.git)?\\b" \\
  && ok "origin remote is micro-editor/micro" \\
  || miss "origin remote is not micro-editor/micro (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 "cmd/micro/micro.go" \\
  && ok "cmd/micro/micro.go" \\
  || miss "missing critical file: cmd/micro/micro.go"
test -f "internal/action/actions.go" \\
  && ok "internal/action/actions.go" \\
  || miss "missing critical file: internal/action/actions.go"
test -f "internal/buffer/buffer.go" \\
  && ok "internal/buffer/buffer.go" \\
  || miss "missing critical file: internal/buffer/buffer.go"
test -f "internal/display/bufwindow.go" \\
  && ok "internal/display/bufwindow.go" \\
  || miss "missing critical file: internal/display/bufwindow.go"
test -f "internal/config/config.go" \\
  && ok "internal/config/config.go" \\
  || miss "missing critical file: internal/config/config.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
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/micro-editor/micro"
  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).

</details>

TL;DR

Micro is a terminal-based text editor written in Go that provides a modern, intuitive alternative to nano/vi by combining ease-of-use with powerful features like multiple cursors, splits, tabs, and plugins. It ships as a single static binary with zero external dependencies and includes 130+ language syntax definitions, a Lua-based plugin system, persistent undo, linting integration, and system clipboard support—all in ~614KB of Go code. Single-binary monolith: cmd/micro/ contains the CLI entrypoint; internal/action/ is the core editor logic (buffer panes, keybindings, command processing, terminal I/O); data/ holds runtime config (syntax definitions, metadata, keymaps); Lua plugin system lives in the codebase via github.com/yuin/gopher-lua bindings.

👥Who it's for

Terminal-focused developers and sysadmins who edit files over SSH or prefer CLI workflows but want nano-like simplicity with vim-like power; users migrating from nano who need mouse support, split panes, and modern defaults without heavy configuration.

🌱Maturity & risk

Production-ready and actively maintained. The repo shows CI/CD pipelines (test.yaml, release.yaml, nightly.yaml), comprehensive GitHub issue templates, semantic versioning with releases badge, and MIT licensing. Go module is at v2, indicating stable API. Activity appears recent based on the terminal dependency update (2025-03-24) and established feature set across 614K LOC.

Low risk for stable use; moderate risk for customization. Dependencies are lean (~15 direct, mostly maintained projects like tcell, gopher-lua, yuin/gopher-lua) but micro-editor forks several upstreams (json5, tcell, terminal, go-shellquote), creating maintenance burden. No visible monorepo structure risks or breaking change indicators in recent commits, but single primary maintainer (zyedidia) is evident from GitHub paths.

Active areas of work

Active development: recent terminal dependency version bump (2025-03-24) suggests ongoing compatibility fixes. CI workflows are live (test.yaml, release.yaml). The codebase includes nightly builds and staged releases, indicating steady maintenance cadence. Focus appears to be terminal compatibility and stability rather than major feature additions.

🚀Get running

git clone https://github.com/micro-editor/micro.git && cd micro && make build (or go build -o micro ./cmd/micro directly—Makefile available but Go 1.19+ and make both work)

Daily commands: make build (outputs ./micro binary) or go build -o micro ./cmd/micro && ./micro. Launch with ./micro <file> or ./micro to open empty buffer. Development: go test ./... runs tests; see test.yaml for CI matrix (Linux/macOS/Windows).

🗺️Map of the codebase

  • cmd/micro/micro.go — Entry point for the application; initializes the editor and main event loop
  • internal/action/actions.go — Core action dispatcher and keybinding handler; every user interaction flows through here
  • internal/buffer/buffer.go — Central buffer abstraction managing file contents, edits, and undo/redo; all text editing logic depends on this
  • internal/display/bufwindow.go — Viewport rendering engine; translates buffer state to terminal screen coordinates
  • internal/config/config.go — Configuration loader and schema; defines all user-configurable settings and defaults
  • internal/screen/screen.go — Terminal abstraction and drawing backend; bridges tcell and all UI rendering
  • internal/lua/lua.go — Lua scripting runtime integration; enables plugin system and extensibility

🛠️How to make changes

Add a new action (editor command)

  1. Define the action function in the appropriate file (internal/action/actions.go or internal/action/actions_other.go)
  2. Register the action in the global action map (usually in actions.go with proto.Register) (internal/action/actions.go)
  3. Add default keybinding in the defaults file (internal/action/defaults.go)
  4. Test the action with a key combo via the editor (cmd/micro/micro_test.go)

Add a new setting or configuration option

  1. Add the setting definition with type and default value (internal/config/settings.go)
  2. Update the config schema in the global config loader (internal/config/config.go)
  3. Read or apply the setting in the relevant component (buffer, display, etc.) (internal/buffer/settings.go or internal/action/globals.go)
  4. Update user documentation and micro.json example (data/micro.json)

Add a Lua plugin hook or API

  1. Define the hook name and register it in the Lua runtime (internal/lua/lua.go)
  2. Expose the hook call at the appropriate point in the action or buffer code (internal/action/events.go or internal/buffer/eventhandler.go)
  3. Test by writing a simple Lua plugin that uses the hook (internal/config/plugin_manager.go)

Add syntax highlighting for a new file type

  1. Create or update a syntax definition file (typically YAML or JSON) (data/ (runtime files directory))
  2. Define lexer rules and color groups for the language (internal/config/colorscheme.go)
  3. Register the syntax with file extension mappings (internal/buffer/buffer.go (DetectLanguage method))
  4. Test by opening a file with the new extension (cmd/micro/micro_test.go)

🔧Why these technologies

  • tcell (github.com/micro-editor/tcell/v2) — Cross-platform terminal abstraction; handles color, cursor, and raw terminal I/O without platform-specific code
  • Lua (github.com/yuin/gopher-lua) — Lightweight embedding for plugin system; allows users to extend without recompiling; already popular in editor communities
  • Go standard library + minimal dependencies — Static binary with no runtime dependencies; ensures portability and fast startup; aligns with 'micro' philosophy
  • Trie-based keybinding tree (keytree.go) — Efficient prefix matching for multi-key chords; supports both Vim-like sequences and traditional editor bindings

⚖️Trade-offs already made

  • Single-threaded main event loop with blocking I/O

    • Why: Simplicity and predictability; editor responsiveness is tied to terminal polling frequency, not parallelism
    • Consequence: Long-running commands (shell execution) may block UI; mitigated by terminal pane and job abstraction
  • Line-array buffer representation (no tree/rope)

    • Why: Simple, understandable implementation; sufficient for typical editing patterns and file sizes
    • Consequence: Very large files (>100MB) or frequent bulk edits may degrade; acceptable trade-off for 95% of use cases
  • Full re-render on every change (no incremental drawing)

    • Why: Correctness and simplicity; avoids complex dirty-region tracking and state synchronization bugs
    • Consequence: Terminal bandwidth and latency on slow links; tcell/terminal library handles optimization internally
  • Lua scripts run synchronously in main thread

    • Why: Avoids race conditions and complex async event handling; plugins are trusted user code
    • Consequence: Plugins block editor; users must keep scripts fast; no parallel I/O in plugins

🚫Non-goals (don't propose these)

  • Real-time collaborative editing (no CRDT or server sync)
  • Full IDE features (no integrated debugger, language server, refactoring tools)
  • Mouse support on all terminals (depends on terminal capabilities)
  • Graphical UI (terminal-only by design)
  • Windows native build without MinGW (uses POSIX abstractions)

🪤Traps & gotchas

Lua plugin system requires gopher-lua and layeh.com/gopher-luar (forked); plugins expect specific hook naming (onSave, onCursorMove, etc.) not validated at load time—bad plugin signatures fail silently. Terminal pane (termpane.go) uses creack/pty (indirect dep) which may not work on all Windows configs despite cross-platform claims. Config file location is hardcoded to ~/.config/micro/ (or %APPDATA% on Windows)—no env var override visible. Syntax definitions are baked into binary (data/micro.json)—runtime syntax additions not supported without rebuild.

🏗️Architecture

💡Concepts to learn

  • Terminal capability negotiation (terminfo/tcell) — Micro uses github.com/micro-editor/tcell/v2 to abstract terminal capabilities (colors, mouse, key codes) across different terminal emulators; understanding how tcell detects and adapts to xterm-256color vs true-color is essential when debugging rendering or keybinding issues
  • Pseudo-terminal (PTY) and shell integration — Micro's termpane.go uses creack/pty to spawn and manage shell subprocesses within editor splits; knowledge of PTY I/O, signal handling, and ANSI escape codes is required to understand or extend terminal pane functionality
  • Multiple cursor / multi-selection editing — Core feature of micro; bufpane.go maintains multiple cursor positions and selection ranges simultaneously, requiring custom undo/redo and conflict resolution logic that differs from single-cursor editors
  • Lua embedding and script isolation — Micro plugins run in a Lua VM (gopher-lua) with limited access to editor internals via layeh.com/gopher-luar; understanding Lua function signatures, metatables, and the sandbox model is critical for plugin development and security
  • Rope or gap buffer text representation — Micro's buffer implementation (in bufpane.go) needs efficient insert/delete at arbitrary positions and persistent undo; the choice between naive string concatenation, gap buffers, or ropes affects performance on large files and memory usage
  • Syntax highlighting via tokenization — Micro's 130+ syntax definitions (data/micro.json) are parsed and applied incrementally to render colored text; understanding regex-based or state-machine tokenization helps when adding new language support or debugging highlight bugs
  • Diff gutter (line-based change tracking) — Micro includes a built-in diff gutter (visible in GitHub feature list) that marks added/modified/deleted lines; this requires tracking original file state and computing efficient diffs (via sergi/go-diff) without blocking the UI
  • vim/vim — Inspirational predecessor; micro aims to provide vim-like power (multiple cursors, splits, plugins) with nano-like ease-of-use
  • BurntSushi/ripgrep — Complementary tool often paired with micro in terminal workflows for fast file searching; ripgrep is frequently integrated into editor plugin systems
  • alacritty/alacritty — Cross-platform terminal emulator that micro depends on rendering libraries from (tcell); shared terminal capability stack
  • helix-editor/helix — Modern terminal editor alternative written in Rust; similar goals (easy + powerful) but different language and plugin architecture (built-in LSP vs Lua)
  • neovim/neovim — Modern vim fork with Lua scripting; shares plugin system approach (Lua-based) but targets vim users rather than nano users

🪄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 comprehensive unit tests for internal/buffer/cursor.go

The cursor module handles position tracking and movement logic critical to editor functionality. Currently, internal/buffer/ has limited test coverage (only buffer_test.go, buffer_generated_test.go, line_array_test.go, and stack_test.go). The cursor.go file lacks dedicated tests, making refactoring risky. Adding tests would improve code confidence and serve as documentation for cursor behavior (line wrapping, bounds checking, tab handling).

  • [ ] Create internal/buffer/cursor_test.go with test cases for cursor movement methods
  • [ ] Test boundary conditions: BOF, EOF, line wrapping
  • [ ] Test interaction with different line types (tabs, unicode, empty lines)
  • [ ] Verify cursor position consistency after buffer modifications
  • [ ] Add benchmarks for frequently-called cursor operations

Add GitHub Actions workflow for cross-platform integration tests

The repo has test.yaml, nightly.yaml, and release.yaml workflows, but test.yaml likely only runs basic unit tests. Terminal-based editors critically depend on platform-specific behavior (POSIX vs Windows, different terminal emulators). The codebase has terminal_supported.go and terminal_unsupported.go, plus platform-specific files (defaults_darwin.go, actions_posix.go), indicating complex cross-platform logic. A dedicated integration test workflow running on Linux, macOS, and Windows would catch platform-specific regressions before release.

  • [ ] Create .github/workflows/integration-tests.yaml with matrix strategy for ubuntu-latest, macos-latest, windows-latest
  • [ ] Add test build targets in Makefile for integration tests (separate from unit tests)
  • [ ] Test basic editor workflows: open file, edit, save, search, terminal integration
  • [ ] Verify tcell/terminal compatibility on each platform (uses micro-editor/terminal fork)
  • [ ] Configure workflow to run on PRs targeting main branches

Add unit tests for internal/action/command.go and infopane.go

The command execution and info pane systems are core to micro's user interaction model (visible in the presence of command.go, infopane.go, and infocomplete.go). These modules handle user input parsing, command routing, and UI feedback—yet no dedicated test files exist for them. Testing command parsing and execution would prevent regressions in the scripting/keybinding system and improve Lua integration quality (repo uses yuin/gopher-lua).

  • [ ] Create internal/action/command_test.go with tests for command parsing and execution
  • [ ] Test command aliasing, argument parsing, and error handling
  • [ ] Create internal/action/infopane_test.go for info message formatting and completion logic
  • [ ] Test autocomplete suggestions (internal/buffer/autocomplete.go integration)
  • [ ] Mock buffer and view dependencies to isolate command logic from UI layer

🌿Good first issues

  • Add integration tests for internal/action/bufpane.go covering multiple cursor operations (insert, delete, movement) in parallel—currently micro_test.go exists but test coverage for concurrent cursor state appears minimal based on file sizes
  • Document Lua plugin API: create a examples/plugins/ directory with 3-5 runnable sample plugins (syntax highlighter hook, status line modifier, custom keybinding) and add Plugin API docs to main README—currently plugin system exists but no example plugins in repo
  • Add platform-specific keybinding tests for internal/action/defaults_darwin.go and defaults_other.go to validate macOS vs Linux conflicts (e.g., Cmd+S vs Ctrl+S)—keybinding parsing in bindings.go lacks cross-platform test matrix

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 253065a — Merge pull request #3997 from JoeKar/fix/symlinks (JoeKar)
  • 2cb49c4 — buffer: Resolve symlinks in file paths (JoeKar)
  • bd0003b — Fix README capitalization (#4081) (aolingge)
  • e323cde — buffer: Don't Serialize in case the buffer is shared (JoeKar)
  • ef57bdc — buffer: Don't cancel the backup in case the buffer is shared (JoeKar)
  • 5dabe17 — Merge pull request #4052 from niltonperimneto/master (JoeKar)
  • 8f14c3c — buffer: check sudo binary exists before creating backup (niltonperimneto)
  • d9ad831 — buffer: fix sudo TTY race on privileged file save (niltonperimneto)
  • 1c88f24 — Suspend the whole process group along with micro. (#4060) (kousu)
  • 25faa84 — Fix documentation for Loc.LessThan() and other similar functions (#4058) (JoeKar)

🔒Security observations

  • High · Outdated Go version — go.mod. The project specifies 'go 1.19' which is below the current stable versions. Go 1.19 reached end of life in December 2023. Using outdated Go versions exposes the project to known security vulnerabilities in the Go standard library and runtime. Fix: Update to Go 1.22 or later (current stable version). Review and test compatibility before upgrading.
  • High · Outdated dependencies with known vulnerabilities — go.mod (golang.org/x/* dependencies). Multiple dependencies have outdated versions that may contain known security vulnerabilities: golang.org/x/text v0.4.0 (should be v0.14.0+), golang.org/x/sys v0.30.0 (verify latest), golang.org/x/term v0.29.0 (verify latest). These are fundamental packages used throughout the codebase. Fix: Run 'go get -u golang.org/x/text golang.org/x/sys golang.org/x/term' to update to latest secure versions. Run 'go mod tidy' and verify tests pass.
  • Medium · Lua scripting capability without sandbox — internal/config/plugin_installer.go, internal/config/plugin_manager.go, go.mod (github.com/yuin/gopher-lua). The project includes github.com/yuin/gopher-lua dependency, indicating Lua scripting support. If plugins/scripts are executed with insufficient sandboxing, malicious Lua scripts could access file system, execute commands, or modify editor behavior. The plugin_installer.go and plugin_manager.go suggest dynamic plugin loading. Fix: Implement strict sandboxing for Lua execution. Restrict available Lua libraries. Validate plugin sources and checksums before installation. Consider implementing a plugin allowlist. Add security warnings for plugin installations from untrusted sources.
  • Medium · Shell command execution via go-shellquote — go.mod (github.com/kballard/go-shellquote), internal/action/command.go likely. The dependency on go-shellquote (github.com/kballard/go-shellquote) suggests shell command parsing/execution. If user input or file content is passed to shell commands without proper validation, command injection vulnerabilities could occur. Fix: Audit all uses of go-shellquote. Avoid passing unsanitized user input to shell commands. Use parameterized execution when possible. Implement input validation and use allowlists for permitted commands. Consider using exec.Command with arguments array instead of shell parsing.
  • Medium · Terminal interaction without validation — internal/action/termpane.go, go.mod (github.com/micro-editor/terminal). The custom terminal dependency (github.com/micro-editor/terminal v0.0.0-20250324214352) with recent modification date and terminal pane implementation (internal/action/termpane.go) suggests direct terminal command execution. Insufficient input sanitization could lead to terminal escape sequence injection or command execution. Fix: Validate and sanitize all terminal input/output. Implement escape sequence filtering. Avoid executing arbitrary commands from untrusted sources. Review terminal pane implementation for injection risks.
  • Medium · Custom forked dependencies reduce transparency — go.mod (multiple github.com/micro-editor/* entries). The project uses custom forked versions of dependencies (micro-editor/go-shellquote, micro-editor/json5, micro-editor/tcell, micro-editor/terminal) instead of upstream. This increases maintenance burden and makes security updates harder to track. Custom forks may diverge from security patches in upstream. Fix: Document why forks are necessary. Establish a process to regularly sync security patches from upstream. Consider contributing changes back upstream. Monitor upstream repositories for security updates and apply them to forks.
  • Low · Dependency on older testify version — go.mod. github.com/stretchr/testify v1.4.0 is significantly outdated (current is v1.8+). While test dependencies have lower risk, outdated versions may contain bugs or missing features. Fix: Update to github.com/stretchr/testify v1.8.4 or later for better assertion support and bug fixes.
  • Low · — undefined. undefined Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · micro-editor/micro — RepoPilot