Local semantic code search for Neovim. Index your codebase once, search by meaning instead of exact text. 100% offline, no API keys, no cloud.
Ask "where is the auth logic" and get results even if no file contains that exact phrase.
vemory runs a native C++ daemon that:
- Scans your project (respects
.gitignore) - Chunks code into functions, classes, and structs using tree-sitter
- Embeds each chunk with a local ONNX model (all-MiniLM-L6-v2, 384-dim)
- Stores embeddings in SQLite with sqlite-vec for vector search and FTS5 for keyword search
- Searches using hybrid Reciprocal Rank Fusion (vector + keyword combined)
Everything stays on your machine. The index persists in .vemory.db and only re-indexes changed files.
C/C++, Go, Python, JavaScript, TypeScript, TSX, Rust, Lua
- Neovim 0.9+
- CMake 3.20+
- C++20 compiler (GCC 11+ or Clang 14+)
- OpenSSL (dev headers)
- Git
{
"amanyd/vemory",
build = "cmake -S . -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc)",
config = function()
require("vemory").setup({ auto_start = true })
end,
}git clone https://github.com/amanyd/vemory.git
cd vemory
git submodule update --init # pulls vcpkg
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=external/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)Then add to your Neovim config:
vim.opt.rtp:append("/path/to/vemory")
require("vemory").setup({ auto_start = true }):VemoryIndex " index (or re-index) the project
:VemorySearch auth logic " semantic search
:VemorySearch " interactive prompt
:VemoryStats " show index stats
:VemoryStop " stop the daemonSearch results appear in the quickfix list. Jump between them with :cnext / :cprev.
vemory plugs into CodeCompanion.nvim to give your LLM automatic codebase context. When you open a chat, relevant code snippets are injected as context so the AI actually knows your project.
Add vemory as a CodeCompanion extension in your config:
-- lazy.nvim example
{
"olimorris/codecompanion.nvim",
dependencies = {
"amanyd/vemory",
},
config = function()
require("vemory.codecompanion").setup({
auto_index = true, -- index on startup
auto_context = true, -- inject context into every new chat
})
require("codecompanion").setup({
-- your codecompanion config here
})
end,
}-
Auto-context injection -- when you open a CodeCompanion chat, vemory searches the index using your current buffer as a query and silently injects the most relevant code snippets as a system message. The AI sees your codebase without you doing anything.
-
/codebaseslash command -- type/codebasein a CodeCompanion chat to manually search. It prompts for a query, runs semantic search, and adds the results to the conversation. -
Manual injection -- call
:VemoryDebugCCto check integration status, or userequire("vemory.codecompanion").inject_context("your query")from Lua.
local vemory = require("vemory")
vemory.setup({ auto_start = true })
vemory.index(function(res)
print(res.message) -- "indexed_42_chunks_10_files"
end)
vemory.search("database connection pool", { limit = 5 }, function(res)
for _, r in ipairs(res.results) do
print(r.path, r.start_line, r.score, r.signature)
end
end)
vemory.stats(function(res)
print(res.files, res.chunks)
end)
vemory.stop()MIT