A Neovim plugin that monitors HTTP traffic from your browser and inspects browser storage — all inside Neovim buffers, using Chrome DevTools Protocol.
No external dependencies. Pure Lua using Neovim's built-in vim.loop (libuv).
- Network monitor — captures every request/response the browser makes via CDP
Network.*events - Request inspector — browse all captured requests with headers and body
- Direction filter — show only inbound (→ dev server) or outbound (→ external) requests
- Resource type filter — filter by
xhr,js,css,doc,ws, etc. - Storage inspector — view and manage
localStorage,sessionStorageand cookies - Clear site data — wipe all storage for the active origin in one keypress
Browser → dev server (localhost:4200 / Vite / Angular / etc.)
↓ observed passively via Chrome DevTools Protocol
Chrome CDP (port 9222)
↓
┌──────────────────┬──────────────────────┐
│ Requests list │ Detail inspector │
│ (all traffic) │ headers + body │
└──────────────────┴──────────────────────┘
┌─────────────────────────────────────────┐
│ Storage inspector │
│ localStorage / sessionStorage / cookies│
└─────────────────────────────────────────┘
The plugin connects to Chrome's CDP WebSocket endpoint (/json/list). Chrome
does all networking normally — devtools.nvim subscribes to Network.enable
events and receives request/response data as they happen. No proxy, no port
forwarding, no system configuration needed.
The storage inspector evaluates JavaScript in the active tab via
Runtime.evaluate to read localStorage, sessionStorage and document.cookie.
- Neovim >= 0.9
- Treesitter parsers:
markdown(storage buffer highlighting),json(value folds) - Chrome launched with
--remote-debugging-port=9222and a separate--user-data-dir
-- lazy.nvim
{
"jugarpeupv/devtools.nvim",
config = function()
require("devtools").setup({
target_port = 4200, -- your dev server port (used for IN/OUT classification)
})
end,
}require("devtools").setup({
-- Dev server to monitor (used to classify requests as inbound vs outbound)
target_host = "localhost",
target_port = 4200,
target_aliases = {}, -- extra hostnames treated as the target
-- Chrome DevTools Protocol port
cdp_port = 9222,
-- Fetch response bodies via CDP (Network.getResponseBody)
cdp_capture_bodies = true,
-- Maximum number of requests to keep in memory
max_requests = 500,
-- Show newest requests at the top
newest_first = true,
-- Panel layout: "horizontal" or "vertical"
split = "horizontal",
detail_split = "vertical",
keymaps = {
open = "<leader>dt", -- global: open the requests panel
close = "q", -- close panels
clear = "C", -- clear all captured requests
detail = "<CR>", -- inspect request under cursor
toggle_capture = "p", -- pause / resume capture
next_request = "]r", -- navigate to next request
prev_request = "[r", -- navigate to previous request
copy_url = "yu", -- copy URL to clipboard
copy_body = "yb", -- copy response body to clipboard
filter = "F", -- set host/path filter
clear_filter = "gF", -- clear active filter
toggle_dir_filter = "D", -- cycle direction filter (all/IN/OUT)
type_filter = "T", -- pick resource type filter
open_storage = "S", -- open storage inspector
-- Storage inspector
storage_refresh = "R", -- refresh storage
storage_domain = "D", -- change domain
storage_clear = "X", -- clear all site data (with confirmation)
},
})Set any keymap to false to disable it.
| Command | Description |
|---|---|
:DevTools or :DevTools open |
Connect to CDP and open the requests panel |
:DevTools open --target-port 3000 --cdp-port 9222 |
Override ports per-call |
:DevTools close |
Disconnect and close panels |
:DevTools toggle |
Show/hide panels (CDP stays connected) |
:DevTools clear |
Clear captured requests |
:DevTools status |
Show connection status |
:DevTools storage |
Open the browser storage inspector |
- Start your dev server:
ng serve(Angular on:4200) orviteetc. - Launch Chrome with remote debugging enabled (see below)
- Open Neovim and run
:DevTools - Browse your app normally — requests appear live in the Neovim panel
- Press
<CR>on any request to inspect headers and body
The storage inspector reads localStorage, sessionStorage and cookies
directly from the running Chrome tab via CDP.
Setup — Chrome must be launched with remote debugging enabled:
# Add to your shell config (~/.zshrc / ~/.bashrc)
# Chrome blocks --remote-debugging-port on its default data dir (security
# restriction since Chrome ~115), so a separate --user-data-dir is required.
# Data in ~/.chrome-dev persists across reboots; sign in once to sync your
# extensions and bookmarks via Chrome Sync.
# Change Chrome binary location based on your OS
alias chrome-dev='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.chrome-dev" \
--no-first-run \
--no-default-browser-check \
"http://localhost:4200" \
&>/dev/null &'Why a separate data dir? Chrome intentionally refuses
--remote-debugging-porton its default profile directory as a security measure. The~/.chrome-devdirectory is a dedicated profile — sign into your Google account once and Chrome Sync restores your extensions, bookmarks and passwords automatically.
Workflow:
- Run
chrome-devfrom your terminal (quit any running Chrome first withCmd+Q) - Run
:DevToolsin Neovim to connect and open the requests panel - Run
:DevTools storageto open the storage inspector
| Key | Action |
|---|---|
<CR> |
Open detail for request under cursor |
]r / [r |
Navigate next / previous request |
C |
Clear all captured requests |
p |
Pause / resume capture |
F |
Set host/path filter |
gF |
Clear active filter |
D |
Cycle direction filter (all → IN → OUT) |
T |
Pick resource type filter |
S |
Open storage inspector |
yu |
Copy URL to clipboard |
q |
Close all panels |
| Key | Action |
|---|---|
]r / [r |
Navigate next / previous request |
yu |
Copy URL to clipboard |
yb |
Copy response body to clipboard |
p |
Pause / resume capture |
q |
Close all panels |
| Key | Action |
|---|---|
R |
Refresh storage from current domain |
D |
Change domain |
X |
Clear all site data (prompts yes to confirm) |
<CR> / <C-s> |
Open value in a horizontal split |
<C-v> |
Open value in a vertical split |
za / zc |
Fold / unfold a storage section (## localStorage etc.) |
q |
Close panel |
JSON values open in a jsonc buffer with treesitter folds — top-level keys are
visible and nested objects/arrays are folded. Use za to expand them.
