Known limits
Vimma is pre-alpha, and this is the honest list, so nothing catches you by surprise: every known gap or catch, one line each, as Vimma's repository records it. When a limit is fixed, its line goes. Lines that name a spec link to it in Vimma's repository.
Features
- Tab keys count Firefox's visible tabs: the current workspace's and any pinned tab.
- The first key of a sequence with nothing runnable under it passes through to the page or Firefox (m1-actor-insert-scroll, Settled).
ctrl+w's pane keys run only with two panes or more, so with one panectrl+wreaches the page; with a split, in normal mode, it is Vim's window prefix (m4-split-panes, sub-spec 3). - Firefox's shortcuts on Vimma's keys (
ctrl+wclose tab,ctrl+uview source,ctrl+hhistory sidebar,ctrl+dbookmark,ctrl+oOpen File,ctrl+iPage Info,ctrl+kweb search,ctrl+bbookmarks sidebar) are off in every mode, so they needx,gf,ctrl+shift+h,ctrl+b a,:open, the menus or[firefox] enable.[firefox]reaches only the window's#mainKeyset: tab switching (ctrl+tab,ctrl+pagedown) and the developer tools' keys cannot be turned off there (key-handling-batch). - The text-field keys (
ctrl+w,ctrl+u,ctrl+h) wait for the page: one that takes the key keeps it, and the edit runs a moment after the key, so a key typed in that moment can land before it. A text field with focus in normal mode (a page's autofocus) gets no edit. On macOSctrl+his Cocoa's own backspace, and onlyctrl+…(notcmd) shortcuts are matched; it is untested there (key-handling-batch). - AltGr and Option characters are told from real
altchords by what the physical key types on a US layout: on a layout where a key's plain character differs from the US one, actrl+altchord on it that types another character counts as AltGr (Windows'ctrl+altstand-in) (key-handling-batch, § 3). - The side panel takes no count:
3xselects row 3 and closes the panel, and thexthen closes that tab in normal mode (key-handling-batch, § 4). - Pages that take keys outside a text field (games, Google Docs' canvas, Figma) lose their bare keys to normal mode; press
ito let every key through untilEsc. Text editors are detected (m1-actor-insert-scroll, Limits). - Bare digits are counts in normal mode, so a page's own digit shortcuts need
ifirst (m1-actor-insert-scroll, Limits). - Extension pages (
moz-extension:),data:,view-source:andblob:pages have no content actor: they stay in insert, with no Vim keys (m1-actor-insert-scroll, Settled). - Closed shadow roots in pages are seen (the actor is privileged), but a page script that moves focus from a frame to the top page's
<body>can leave insert on untilEsc(m1-actor-insert-scroll, Limits). Escin a text field leaves insert and does not reach the page; pressEscagain for the site's ownEsc(closing an autocomplete or a dialog) (m1-actor-insert-scroll, Settled).- After
Escin adesignModepage, it stays in normal until the next click into it (m1-actor-insert-scroll, Settled). - Command line: history is kept in memory only, until Vimma quits; arguments (URLs, workspace names) are not completed, except
:addon's add-on names; there is no:set, and no ranges or counts (m1-cmdline, Settled; addon-manager). - Link hints label only what the page has as elements: canvas and WebGL apps (Google Docs, Figma, maps, games) have nothing to label, and delegated click handlers with no role or listener of their own, image-map
<area>links and pinch-zoomed pages are missed or misplaced (m1-hints, Limits). - Hint labels are drawn for the layout at
f; a page that scrolls itself while they show leaves them stale. Frames inside a CSS-transformed<iframe>get misplaced labels, and a frame that takes over 150 ms to answer (busy) gets none that time.Fdoes not openblob:links (m1-hints, Limits). config.tomlchanges show up to 2 s late (the poll;:sourceis at once). Two saves within one millisecond that keep the file's size are seen as one. A workspace removed from[workspaces]stays, as a runtime workspace with its tabs and container. Only the first error is in the status bar (all are in the Browser Console andabout:vimma) (m5-config-load).- Without the
theme-set.dhook Vimma installs (no Omarchy hooks folder,vimma.theme.omarchyHookoff, or the hook deleted), an Omarchy theme change shows up to 2 s late: Vimma pollscolors.toml's stat every 2 s (Firefox has no portable file watcher; plan §3). With the hook, Vimma follows only after Omarchy has retinted its own apps; a hook run in the moment between Vimma's start and its first window opens a window (m5-omarchy-theme, Limits and "Instant reload by default"). - If the Omarchy theme directory disappears after a theme was shown (as during
omarchy-theme-set's swap), the colours stay until a theme is back; Tokyo Night only when no theme was found since startup or the lastvimma.theme.*change (m5-omarchy-theme). about:vimmais read when it opens:ror Refresh updates it, it does not follow changes live. It is registered when the first window opens, so a session that restores anabout:vimmatab before that shows Firefox's error page until reloaded. Its key log keeps the last 20 keys Vimma dispatched; keys the goto picker, the/search and the help filter take are not in it, and an ambiguous key resolved by its timeout shows as….:bugcopies to the clipboard only; it writes no file (m5-about-vimma).
Find
?searches forward while you type, as Firefox's find bar does;Enterthen steps back to the last match before where the search started (m1-find, Settled).Escscrolls the page back, not a frame or an inner scroller it scrolled (pdf.js scrolls its own viewer: thereEscleaves the view at the match) (m1-find).- In the PDF viewer
/,Enter,nandNwork through pdf.js, but the status bar shows no match count: pdf.js reports it to the find bar only (m1-find). - A count before
n(3n) searches once.Nright afterEsc, or after the page reloads, searches forward once: Firefox's finder has no previous match to step back from (m1-find). - A search starts at the top-left corner of the viewport; a fixed header there makes it start at the header's place in the document (m1-find).
Copy mode
- Copy mode works in the frame that has focus; a frame from another site needs a click first, and the caret does not cross from one frame into another (m1-copy-mode).
w/bare Firefox's word steps: on Linuxwstops at the end of a word, not at the start of the next as in Vim;e,W,BandEare Vim's (m1-copy-mode).e,ge,W,B,E,^,f,t,iwandawread the text around the caret (a few thousand characters each way, more with a count) and stop at its edge. They do not enter a shadow root or a frame, andf/tsearch the text between line breaks, not the wrapped line on screen (m1-copy-mode).Vselects visual lines, asj/kmove: a paragraph the page wraps is several lines. At a soft wrap the end of one line and the start of the next are the same point, soVthere can take the neighbouring line (m1-copy-mode).iw/awalways select the word at the caret; they do not grow a selection by a word as in Vim, and take no count.Ycopies the lines without a trailing line break (m1-copy-mode).- The primary selection (middle-click paste) follows the mouse and the motions Firefox moves (
h j k l w b 0 $ { } gg G); aftere,W,f,V,o,iwand the other Vim text motions it still holds the selection from before them.ycopies to the clipboard (m1-copy-mode). - A click in copy mode that selects nothing moves the caret there and stays in copy mode (m1-copy-mode).
ycopies plain text only. Text inside text fields is not part of the page's selection: focus the field and usectrl+c(m1-copy-mode).- After the page navigates, the first copy-mode key only ends copy mode (m1-copy-mode).
Tabs and window
- "List all tabs" (View menu,
#alltabs-button, thectrl+tabpanel's "show all") is unavailable while the tab strip is hidden; thectrl+b ggoto picker lists every tab instead (m0-tabstrip-hidden). ctrl+shift+tabwithbrowser.ctrlTab.sortByRecentlyUsedon does nothing while the strip is hidden (m0-tabstrip-hidden).vimma.ui.tabstrip.hiddenhas no Settings UI; useabout:config(m0-tabstrip-hidden).- The nav bar's drag region on GNOME (client-side decorations) has not been checked by hand (m0-tabstrip-hidden).
Workspaces
These are the trade-offs the workspaces' design accepts on purpose (m3-workspaces).
- Containers do not isolate history, bookmarks, form history, the downloads list, HSTS or site permissions: they are shared by every workspace, and the URL bar suggests other workspaces' history.
- Saved passwords are not per container: a login saved in one workspace autofills in all of them until the per-workspace
autofillsetting (M6). - Moving a tab to another workspace reopens its URL in the other container: back/forward history, form data, scroll position and POST data are lost.
- Closing a workspace created at runtime deletes its container's cookies and site data, and its closed tabs cannot be reopened.
- Setting
privacy.userContext.enabledtofalsecloses every workspace tab and deletes all containers and their data (Firefox's behaviour). - Deleting a workspace's container outside Vimma (Settings → Containers, an extension) deletes its cookies and site data; the workspace gets a new, empty container, and tabs an extension left open in the deleted one stay there, marked
foreign. - A corrupt
containers.jsonmakes Firefox reset containers; workspace logins can be lost and tabs come back markedforeign. - Pinned tabs belong to no workspace: they show in every workspace, and a tab opened pinned stays in no container (decision 11 plans to unpin them). A tab sharing camera, microphone or screen cannot be hidden and stays visible in other workspaces while it shares.
- Workspaces are saved with Firefox's session, so a crash loses what the session file has not caught yet: up to 15 seconds of changes while you are active, and up to an hour after 3 minutes without input (
browser.sessionstore.interval.idle). Tabs then come back in the workspace that owns their container, but a workspace's selected tab, its panes and new tab names may be older. - A window saved by a newer Vimma keeps its saved workspaces untouched: this version starts it with its tabs sorted into workspaces by container, without its panes, and does not save over it.
- Tabs in hidden workspaces keep playing audio, and they are never unloaded automatically.
- Closing the last tab opens a new tab instead of closing the window (
browser.tabs.closeWindowWithLastTabisfalse); setting it totruelets the window close with every hidden workspace in it. - Restoring workspaces needs
browser.startup.page = 3(Vimma's default); with any other value tabs are not restored and workspaces start empty. - New tabs get no preloaded
about:newtab: Firefox preloads only for tabs without a container, so Vimma turns preloading off (browser.newtab.preload). A new tab paints about 40 ms later than with a preload (measured 76 ms against 35 ms, median of 20). - On a new profile the very first tab opens before the first workspace exists, so it has no container and is marked
foreign; later tabs and windows open in the workspace's container. browser.link.force_default_user_context_id_for_external_openssends links from other apps to the active workspace's container, not to "no container".- Firefox Sync no longer syncs
browser.startup.pageorprivacy.userContext.enabledto Vimma. - After 3 minutes without input, the session is saved hourly, so a crash can lose an hour of changes made by pages (tabs they opened), as in Firefox.
- Private windows and pop-ups have no workspaces.
- Firefox's sidebar keys (
ctrl+alt+x,ctrl+alt+u,ctrl+alt+z;ctrl+his off) still open its own sidebar beside Vimma's side panel; Firefox's four default containers stay in Settings. - Extensions that hide or show tabs (
tabs.hide) conflict with workspace visibility.
Routing rules
- A page's own navigation (link click, redirect, sign-in bounce) is never moved to the workspace a rule names; the status bar hints and
:route movereopens it there, without its history. - Rules never route a link a page opens (a click, middle- or ctrl-click,
Fhints,target="_blank",window.open): it stays in the page's container, so a page cannot open a site with another workspace's cookies. The tab gets the same hint when shown. - App rules need
vimma-open(the packages' desktop entry). Apps in Flatpak or other sandboxes open links through the desktop portal, apps started by systemd (uwsm app,app2unit) are not in the link's process tree, andgio openmay exit beforevimma-openlooks: those links have no app. A script run by an interpreter may be named after the interpreter (python3). A link opened from a shell is the terminal's. - The app name is a hint any local program can send (
vimma -vimma-from slack <url>); it can only pick a workspace a rule already names, as typing the URL would. - With
browser.link.open_newwindowset to open external links in a window or in the current tab, app rules do not apply to them (domain rules do in a new window). - A cold start from a link routes its first tab with the rules cached at the last run; a rule added while Vimma was closed applies from its next read of
config.toml.
Bookmarks
- Tags, keywords, separators, sorting, drag and drop, undo and editing a bookmark's address are left to Firefox's Library (
ctrl+shift+o); a folder's bookmarks cannot be opened all at once (bookmarks, Out of scope). javascript:anddata:bookmarks (bookmarklets) are listed but never open from Vimma, nor does anything buthttp,https,fileandabout:(bookmarks, decision 6).- A
/inside a folder or bookmark name is typed\/in a path; a top-level folder namedtoolbar,otherormobileis reached by Firefox's root of that name instead (bookmarks, decision 2). - The panel's
aadds the page even when it is bookmarked already (Firefox allows several); onlyctrl+b aand:bookmarkoffer to move the existing one. The filter lists bookmarks, not folders (bookmarks, decisions 7 and 10).
Add-ons
- Installing stays Firefox's: an add-on's page on addons.mozilla.org and the permission prompt. The picker's
uonly checks for an update; Firefox installs it (in the background, or from about:addons), so an update asking for new permissions still gets Firefox's prompt (addon-manager, decision 9). - A key cannot open one particular add-on's popup from
config.toml: keymap actions carry no argument. Bindaddon_popup(it opens:addon) or set the add-on's own shortcut in about:addons → Manage Extension Shortcuts (addon-manager, decision 12). - An extension's own shortcut on a key Vimma binds never reaches the add-on: Vimma's wins.
- Keys inside an add-on's popup are the popup's (no Vim keys there), as on other extension pages;
Esccloses it. - Only browser-action (toolbar button) popups open from Vimma; page actions (the address bar's buttons), sidebar actions and an add-on's context-menu entries need Firefox's own UI (addon-manager, Out of scope).
- An inline options page (
open_in_tab: false) opens in a tab of its own, not inside about:addons (addon-manager, decision 6).
Panes
- Panes are resized from the keyboard only (resize mode); dividers cannot be dragged with the mouse, and tabs cannot be dropped onto a pane (m4-split-panes, Out of scope).
- A pinned tab cannot be shown in a pane; Firefox's split view refuses pinned tabs, so Vimma unpins a tab before it joins a split (ADR-013).
- Firefox's own split-view UI is off: the tab and link context-menu items and alt-click (
browser.tabs.splitView.enabledfalse), the URL bar's split button and the tab-group items of a split (hidden bysplit.css); splits come from Vimma's keys (ADR-013). - At most
[panes] maxpanes (default 4, up to 16) in a workspace: a further split is refused with "at most N panes". Every visible pane's page stays live, so each one costs memory and CPU; a zoomed-away pane is paused (its docshell inactive) until unzoom (m4-split-panes, sub-spec 2). - A tab whose pane is closed stays open in its workspace; it is not hidden.
- One split per workspace: a split made outside Vimma (Firefox's split-view command, an extension, a restored Firefox session) is adopted as a row of panes; a second one in the same workspace, or one whose tabs are in different workspaces, is separated with a notice. Firefox's
about:opentabstab in such a split closes when Vimma separates it, as in Firefox (m4-split-panes, sub-spec 6). - The accessible name of the third pane on ("<title>, pane 3 of 4") is English only; Firefox names the first two panes "left" and "right" whatever the layout (m4-split-panes, sub-spec 2).
- With three or more panes, extensions that move a split tab (
tabs.move) and the all-tabs list's drag targets assume two tabs per split and may misplace them (ADR-013). - A split's tabs become adjacent in Firefox's own tab order; Vimma's tab numbers come from its own list and are unaffected (m4-split-panes).
Privacy, security and services
- Safe Browsing works only in builds made with a Google API key (the nightly, and local builds with the key file). Keyless builds, including PR CI's, fetch no phishing, malware or download lists and default the protection off, so Settings shows it unticked (m0-safebrowsing-key).
- Every keyed build shares one Google key. Google's Safe Browsing API is free for non-commercial use only and has per-project quotas (Cloud console → Quotas); a large user base or commercial use needs a quota increase or Google's Web Risk API. The key is compiled into the binaries and can be extracted from them; that is normal for browsers (Firefox ships its own the same way) and accepted. Rotation: runbook (m0-safebrowsing-key).
- No download reputation: Google serves its download lists (
goog-badbinurl-proto,goog-downloadwhite-proto) and its remote download check only to Mozilla's key, so Vimma asks for neither, and "Block dangerous downloads" in Settings adds nothing beyond the site lists (m0-safebrowsing-key, Settled). - Safe Browsing's
goog-harmful-protolist is requested but did not arrive in the smoke run with our key (phishing, malware and unwanted did); treat it as unavailable. See m0-safebrowsing-key. - No update mechanism of our own and no update manifest until M6 (m0-app-version, Out of scope).
- No crash reporting: builds have no crash reporter, so crashes leave only a local core dump. Opt-in reporting to our own server is M6 (m0-mozilla-services).
- Once Vimma writes its
falsefor sponsored address-bar suggestions, that value looks like the user's own, and anabout:configreset is undone at the next window (m0-mozilla-services, Settled). - The ASRouter
cfrprovider pref is a copy of upstream's value and must be refreshed on every Firefox bump (runbook, Upstream bumps).
Compatibility and versions
runtime.getBrowserInfo().nameisVimma, notFirefox(m0-app-version, Out of scope).- A Firefox backup cannot be restored into Vimma: BackupService refuses a different app name (m0-app-version, Out of scope).
- Sidebar/GenAI Nimbus
minVersion,PageloadEventand Glean's display version still read Vimma's0.1.0. Harmless while Nimbus and telemetry are off (m0-app-version). - The About dialog shows
0.1.0, not the planned "Vimma 0.x · Firefox N" line (m0-app-version, Out of scope). - Builds from before the app-version change see newer profiles as a downgrade and refuse them. Use a separate
--profileor--allow-downgrade(runbook, Smoke check). - Profiles from the old
unofficial-brand builds are not picked up (m0-branding, Settled). vimma --versionprintsVimma Vimma 0.1.0(vendor and name are both Vimma) (m0-branding, Settled).
Files and profiles
~/.config/vimma/holds bothconfig.tomland the profiles (vimma/). The config loader reads onlyconfig.tomland never scans the folder (m5-config-load; m0-branding, Settled).
Branding
- The about dialog's wordmark (
about-wordmark.svg) is still the placeholder "VIMMA" in plain strokes; the logo and app icon are the real window+V mark (m0-branding). - Windows and macOS assets (installer bitmaps,
.icns, MSIX) are still Surfer'sunofficialcopies until those platforms are built (m0-branding, Out of scope). - The default bookmarks are still Mozilla's links (m0-branding).
--screenshoton a brand-new profile logs a bookmarks import error, and--screenshot about:homehangs. Both are upstream headless quirks (m0-branding, Settled).
Platforms and packaging
- Only Linux x86_64 is built and tested. aarch64, macOS and Windows ("when cheap") come later (plan.md §6).
- No binaries, packages or releases: build from source. Tarball, AppImage,
.deband AUR are M6 (plan.md §6). - The smol-toml BSD-3-Clause notice is not in
about:licenseyet (M6, issue #16). vimma-ctlchecks the discovery file's permissions on Unix only; on Windowscheck_modedoes nothing (ACLs, not mode bits) (m0-control-protocol-and-vimma-ctl).
The guide at the top is written for this site; the details are built from Vimma's docs/limits.md and bindings.md at 1050bcc (2026-10-10).