https://github.com/theblob42/alpacka.nvim
A simple plugin manager for Neovim
https://github.com/theblob42/alpacka.nvim
lua neovim neovim-lua neovim-plugin nvim nvim-lua nvim-plugin
Last synced: about 2 months ago
JSON representation
A simple plugin manager for Neovim
- Host: GitHub
- URL: https://github.com/theblob42/alpacka.nvim
- Owner: TheBlob42
- License: gpl-3.0
- Created: 2025-02-10T19:00:49.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-28T12:47:59.000Z (about 1 year ago)
- Last Synced: 2025-04-07T23:18:08.080Z (12 months ago)
- Topics: lua, neovim, neovim-lua, neovim-plugin, nvim, nvim-lua, nvim-plugin
- Language: Lua
- Homepage:
- Size: 43.9 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Alpacka 🦙
A simple plugin manager for Neovim
## Motivation
Moving from [vim-plug](https://github.com/junegunn/vim-plug) to [packer.nvim](https://github.com/wbthomason/packer.nvim) for Lua support and then to [lazy.nvim](https://github.com/folke/lazy.nvim) for its lockfile feature refined my expectations of a plugin manager for Neovim. However, when I encountered issues with the `lazy-lock.json` file not behaving as I expected (see [here](https://github.com/folke/lazy.nvim/issues/1787) and [here](https://github.com/folke/lazy.nvim/issues/1740) for examples) I took the opportunity to create a simpler solution tailored toward my personal needs:
- I don't care about lazy loading and startup time optimizations
- I don't need support for [luarocks](https://luarocks.org/)
- I prioritize determinism and simplicity over raw speed
### Features
- Leverage Neovim's built-in `packages` system
- Install and load plugins synchronously
- Load exactly in the order of definition
- Simple and predictable dependency management
- Provide hook functions for building, initializing and configuring plugins
- Includes a lockfile (`alpacka-lock.json`)
- Track commits of installed plugins
- Sync your state to different machines
- Only manual file updates for full control
### Non-Features
- **NO** lazy loading functionality
- **NO** caching or bytecode compilation
- **NO** luarocks support
## Installation & Setup
Requires the following dependencies:
- Neovim >= `0.10.0`
- Git >= `2.19.0` (for partial clone support)
```lua
-- automatically bootstrap alpacka
local alpacka_path = vim.fn.stdpath('data') .. '/site/pack/alpacka/opt/alpacka.nvim'
if not vim.uv.fs_stat(alpacka_path) then
local out = vim.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/theblob42/alpacka.nvim.git',
alpacka_path,
}):wait()
if out.code ~= 0 then
print('Error when cloning "alpacka.nvim":\n' .. out.stderr)
end
end
-- IMPORTANT so that alpacka gets loaded on startup
vim.cmd.packadd('alpacka.nvim')
require('alpacka').setup {
-- alpacka can manage itself
'theblob42/alpacka.nvim',
-- simple plugins can be specified as strings
'tpope/vim-sleuth',
-- full git URLs are supported (e.g. for non-Github repositories)
'https://github.com/tpope/vim-sensible.git',
-- define a specific commit that should be checked out
{
'eraserhd/parinfer-rust',
commit = '327fc9a'
},
-- set a git tag that should be checked out
{
'folke/noice.nvim',
tag = 'v4.7.0'
},
-- specify a git branch that should be checked out
{
'echasnovski/mini.nvim',
branch = 'stable'
},
-- local plugins can be loaded as well
{
'my-local-plugin',
dir = '~/Dev/my-local-plugin'
},
-- plugins can have post-install/update hooks
{
'nvim-treesitter/nvim-treesitter',
build = function()
vim.cmd('TSUpdate')
end
},
-- run lua function before load
{
'Olical/conjure',
init = function()
vim.g['conjure#mapping#doc_word'] = 'gk'
end
},
-- run lua function after load
{
'lukas-reineke/indent-blankline.nvim',
config = function()
require('ibl').setup {}
end
},
-- only load plugins if a certain condition is met
{
'github/copilot.vim',
load = function()
return vim.env.USER == 'work-laptop'
end
},
}
```
More details about the configuration options
### `dir`
Specify the directory for a local plugin
Local plugins should be managed by you and therefore come with the following "restrictions":
- Not added to the lock file
- The `build` function will be ignored
- The `branch` property will be ignored
- Updates have to be done manually
### `commit`, `tag` & `branch`
Define a specific reference that should be checked out for a plugin. While these are separate properties **only one** of them will be applied in cases where you provide more than one. The first item from the following table will be used (top to bottom) all others will be ignored:
| Property | Description |
| --- | --- |
| `commit` | The specific GIT commit will be checked out |
| `tag` | The specific GIT tag will be checked out |
| `branch` | The specific GIT branch will be checked out |
**NOTE**: If a plugin is already installed simply specifying any of these properties will not update it automatically. Either update the plugin manually or reinstall it for the desired change to take place
### `build`
Function to trigger after a plugin has either been cloned or updated. Use this to download assets, build binaries etc.
- Called after a plugin has been loaded
- **After** the `init` function
- **Before** the `config` function
- Switches the current working directory temporarily to the plugin folder
- Receives the plugin name and spec as parameters
- Updating the plugin via `require('alpacka').update(...)` or the status window will trigger this function again
- But only if the update actually changed something
```lua
{
'iamcco/markdown-preview.nvim',
build = function()
vim.sytem(
{ 'yarn', 'install' },
{ cwd = './app' }) -- build is switching to the plugin directory temporarily
end
}
```
### `init`
Function to setup anything **before** a plugin is being loaded. Use this to setup global variables or other prerequisites. Receives the plugin name and spec as parameters
### `config`
Function to setup any configuration **after** a plugin has been loaded. This is the place for setup instructions (usually by calling a `setup` function), creating keybindings and so on. Receives the plugin name and spec as parameters
### `load`
Function that decides if a plugin should be loaded. Has to return a boolean value. Receives the plugin name and spec as parameters
If the function returns `true` the package will be loaded via `packadd`. This is the default if no `load` function is specified. Otherwise this step will be skipped. The installation of a plugin is not influenced by this property
> You could use this property to build your own "lazy loading" functionality
> Just call `packadd` at any given occasion to load the plugin (autocommand, custom user command etc.)
## Usage
Use the `:Alpacka` command to open a status window with more information about your configured plugins:

- Overview about all plugins managed by alpacka
- List unmanaged plugins that you might want to get rid off
- List lockfile entries that can be deleted
- Check for new commits available
- Update plugins to the newest commit
- See if a plugin's current commit differs from the lockfile (`Lock*`)
- Restore plugins to their locked state
- Update the lockfile
- Show specified plugin ref: `dir`, `commit`, `tag` or `branch`
- A trailing asterisk indicates a discrepancy between the spec definition and the current plugin state
## References
- [vim-plug](https://github.com/junegunn/vim-plug)
- [packer.nvim](https://github.com/wbthomason/packer.nvim)
- [lazy.nvim](https://github.com/folke/lazy.nvim)