Scripting with vimma-ctl
vimma-ctl controls a running Vimma from the command line: send it keys, read its state, open a URL. Use it from scripts or window-manager bindings. It is off until you turn it on.
before you turn it on
Turning it on gives full control of the browser to any program that runs as you: it can type into your logged-in sites, change any setting and open local files. Leave it off unless you use it.
Set it up
- In
about:config, setvimma.control.enabledtotrue. It starts at once. - Build the client:
cargo build --releaseintools/vimma-ctl/of Vimma's checkout. Puttarget/release/vimma-ctlon yourPATH.
Examples
vimma-ctl state # mode, workspace and tabs vimma-ctl state --json # the same, as JSON vimma-ctl send-keys "ctrl+b ?" # as if typed: opens the key list vimma-ctl send-keys esc vimma-ctl open https://example.com # in a new tab
In Hyprland, a key that shows Vimma's key list:
bind = SUPER, slash, exec, vimma-ctl send-keys "ctrl+b ?"
Keys go to the most recently focused Vimma window, exactly as if you typed them.
Details
Everything below is Vimma's own user guide for this topic, in full: every edge case and exception. You do not need it to get started.
vimma-ctl drives a running Vimma from a shell, a window-manager binding or a test: it sends keys, reads the state and opens URLs. It is for when you want your browser to be part of your scripts. It talks to the browser over a local control socket, which is off by default.
Turn the socket on: in
about:config, setvimma.control.enabledtotrue. It starts at once and writesvimma-control.jsoninto your profile directory. Setting it back tofalsestops it and deletes the file.Build the client (Rust, no dependencies):
cargo build --releaseintools/vimma-ctl/; the binary istools/vimma-ctl/target/release/vimma-ctl. Packages will ship it later.Use it:
vimma-ctl state # mode, pending keys, workspace, tabs vimma-ctl state --json # the same, as JSON vimma-ctl send-keys "ctrl+b ?" # typed as if on the keyboard: opens the help overlay vimma-ctl send-keys esc vimma-ctl open https://example.com # a new tab; only http, https, file and about URLs vimma-ctl reload-theme # read the Omarchy theme now (the hook's fallback)It finds your default profile itself; pass
--profile DIR(or setVIMMA_PROFILE) for another one. In Hyprland:bind = SUPER, slash, exec, vimma-ctl send-keys "ctrl+b ?".
send-keys presses the keys in the most recently focused Vimma window, exactly as typing them would: Vimma's bindings, Firefox's shortcuts (ctrl+t, ctrl+q) and the page all see them. Keys meant for the page reach it only while that window has focus, as with a real keyboard.
Security. Turning the socket on hands full control of the browser to whoever has the token: they can type into any page (including your logged-in sites), open about:config and change any setting, and quit Vimma. open loads with the system principal, like a URL given on the command line, so it can open local files (file:) and privileged pages such as about:config; only javascript: and data: are refused. Leave the pref off unless you use it.
What keeps others out:
- The socket listens on
127.0.0.1only, on a random port. Web pages cannot speak to it (they cannot read the token, and an HTTP request is rejected). - A client must send the token from
vimma-control.json: 256 random bits, new at every start, compared in constant time. The file is readable by you alone (mode 0600), andvimma-ctlrefuses a file anyone else can read. Other users on the machine cannot get it; anything running as you can, just as it can already read your profile's cookies and history. - The browser proves it knows the token first:
vimma-ctlsends only a random nonce, and sends the token only after the browser has answered with an HMAC of that nonce made with the token. If Vimma crashed and another program took its old port, that program gets the nonce and nothing else: no token and no command (vimma-ctlexits 4). It can still makevimma-ctlwait until its timeout. - A stale file (Vimma crashed or was killed with
kill -9orSIGTERM) is removed at Vimma's next start, whether or not the socket is on. Until then, on Linux,vimma-ctlsees that the process named in it has exited and says Vimma is not running; if that process number has been reused, the handshake above still protects you.
Limits against a local denial of service: at most 8 authenticated connections (the next is told "busy"); at most 2 connections still authenticating, a new one pushing out the oldest, so idle connections cannot lock vimma-ctl out; 5 s to authenticate; an idle connection closes after 60 s; lines over 1 MiB and clients that stop reading are disconnected. These are limits, not a defence against an active attack: a program of any local user that connects fast enough keeps pushing vimma-ctl out before it authenticates, and any program running as you can keep the 8 slots busy. Turn the pref off to stop either.
With the help overlay open, every key goes to the overlay, ctrl+q included, as when typing; send esc first (vimma-ctl send-keys "esc ctrl+q").
The guide at the top is written for this site; the details are built from Vimma's docs/guide.md and bindings.md at 1050bcc (2026-10-10).