🌐 boundary.nvim

October 23, 2025 Β· View on GitHub

See React/RSC 'use client' boundaries at the call site. Inspired by the VS Code extension RSC Boundary Marker, brought to Neovim.

If this helps, please ⭐ star the repo!


πŸ“Έ Examples

default

Screenshot

custom marker text

Screenshot from 2025-10-20 11-37-52

custom hl color

Screenshot from 2025-10-20 11-42-47

✨ Features

  • Detects components that declare 'use client'.
  • Shows a right-aligned 'use client' marker as virtual text next to each JSX usage.
  • Auto-watches buffers to keep markers in sync (or use a manual refresh).
  • Handles default / named / aliased imports and directory imports resolving to index.

πŸš€ Quick Start

With lazy.nvim:

{
  "Kenzo-Wada/boundary.nvim",
  branch = "release",
  opts = {
    auto = true, -- automatic refresh enabled by default
    -- marker_text = "'use client'",
  },
}

Manual refresh:

:BoundaryRefresh

πŸ“¦ Installation

Works with any plugin manager. Once on your runtimepath, just:

require("boundary").setup()

All options are optional; sensible defaults are provided.


βš™οΈ Configuration

require("boundary").setup({ ... }) accepts:

OptionTypeDefaultDescription
marker_textstring'use client'Virtual text displayed next to each matching JSX usage.
marker_hl_groupstringBoundaryMarkerHighlight group for the marker (links to Comment by default).
hover_onlybooleanfalseOnly display markers when the cursor is on the matching line.
directivesstring[]{ "'use client'", '"use client"' }Directive strings recognized in imported files.
search_extensionsstring[]{ ".tsx", ".ts", ".jsx", ".js" }File extensions tried when resolving bare relative imports.
filetypesstring[]{ "javascript", "javascriptreact", "typescript", "typescriptreact" }Filetypes that trigger scanning.
max_read_bytesnumber4096Max bytes read from each import when scanning for directives.
autobooleantrueEnable automatic refresh via autocommands.
eventsstring[]{ "BufEnter", "BufWritePost", "TextChanged", "InsertLeave" }Events used to refresh when auto is true.

πŸ”„ Usage

  1. Import a local component in a supported React file (.tsx, .jsx, …).
  2. Ensure the component’s file begins with a 'use client' (or "use client").
  3. Edit or save (with auto = true) or run :BoundaryRefresh to populate markers.
// components/Button.tsx
"use client";

export default function Button() {
  return <button>Click me</button>;
}

// app/page.tsx
import Button from "../components/Button";

export default function Page() {
  return (
    <div>
      <Button /> 'use client' // boundary.nvim shows virtual text here
    </div>
  );
}

πŸ“‘ Auto-refresh events

Default events:

  • BufEnter β€” when entering a buffer
  • BufWritePost β€” after saving
  • TextChanged / InsertLeave β€” during edits / leaving insert mode

Tune this list to balance responsiveness and cost.


🧰 Commands

  • :BoundaryRefresh β€” Re-scan the current buffer.

🀝 Contributing

Issues and PRs are welcome! We label good first issue to help newcomers get started.


πŸ“œ License

MIT