CosmicNvim is a lightweight and opinionated Neovim config for web development, specifically designed to provide a ๐ซ COSMIC programming experience!
Historical screenshot (December 2021); the current UI and plugin defaults differ.
Full featured native LSP functionality!
While CosmicNvim is geared specifically toward TypeScript/JavaScript development, it should be able to provide a great experience with any LSP supported language.
For the corresponding features, also install:
cc, gcc or clang) for parser installation and syntax highlightingmake and a C compiler for LuaSnip's regex transformationsripgrep (rg) for picker text searchesfd 8.4+ (fd or fdfind) for file explorer searches; it also speeds up file pickerscurl and tar for parser/package downloads and extractionThese support specific features rather than core startup. :checkhealth cosmic checks external tools after installation.
# Create and enter Neovim's config parent directory.
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}" && cd "${XDG_CONFIG_HOME:-$HOME/.config}" || exit 1
# Move an existing config or symlink into a unique backup directory.
if [ -e nvim ] || [ -L nvim ]; then
backup_dir=$(mktemp -d "$PWD/nvim.backup.XXXXXX") || exit 1
mv nvim "$backup_dir/nvim" || exit 1
printf 'Previous config saved to %s/nvim\n' "$backup_dir"
fi
# Clone into the now-empty destination, then install plugins on first launch.
git clone https://github.com/CosmicNvim/CosmicNvim.git nvim && nvim
By default, Cosmic uses the Git checkout at vim.fn.stdpath('config'), usually ~/.config/nvim.
A whole-directory symlink from that location to your checkout works without additional configuration.
If you link individual files or otherwise keep the checkout elsewhere, set the shell environment variable
COSMICNVIM_INSTALL_DIR to the checkout path so Cosmic can locate its lockfile and update the correct repository.
For individual-file installations, include the after/ directory as well as init.lua and lua/ so built-in LSP
settings are on Neovim's runtimepath.
After plugins finish installing, run :checkhealth cosmic to check the installation and external tools.
Conform formats on save with the tools configured in lua/cosmic/plugins/conform/init.lua.
Install the tools for your filetypes and make sure Neovim can find their executables on PATH.
Mason's LSP installation does not install every configured formatter. Some servers, such as oxlint and Ruff,
share their executable with Conform's tools and may already provide it.
JavaScript and web files follow each project's own tooling. Linters and formatters are selected independently. For JS/TS files, lint fixes run before formatting:
| Project's linter setup | Lint fixes on save | Linter diagnostics from |
|---|---|---|
| oxlint present, no ESLint configured | oxlint |
oxlint server |
| oxlint present and ESLint configured | oxlint, then eslint_d |
Both servers |
| ESLint configured, no oxlint | eslint_d |
ESLint server |
| Neither linter configured | oxlint (default) |
oxlint server |
For JS/TS, CSS, SCSS, HTML, JSON and Markdown, the first matching rule selects the formatter:
| Project's formatter setup | Formatter |
|---|---|
| oxfmt present | oxfmt |
| Otherwise, Prettier present | prettierd; plain prettier is also enabled when prettierd is absent from PATH |
| Otherwise, ESLint configured | No separate web formatter; only JS/TS ESLint fixes |
| None of the above | oxfmt |
For example, oxlint + Prettier uses oxlint fixes and Prettier formatting, while ESLint + oxfmt uses ESLint fixes and oxfmt. CSS, SCSS, HTML, JSON and Markdown use the formatter selection above, but do not run the JS/TS lint-fix commands.
Detection searches the file's directory and its ancestors for supported config files, such as .prettierrc or
eslint.config.js, and package.json settings (eslintConfig or prettier). An oxlint, oxfmt or Prettier dependency
in dependencies or devDependencies also counts; an ESLint dependency alone does not.
Conform prefers project-local binaries where supported by the tool's formatter definition.
The Prettier fallback check only looks at PATH: a project-local-only prettierd can cause both Prettier commands to run.
When no external formatter is available, Conform can fall back to an eligible LSP formatter.
| Other filetypes | Formatters, in order |
|---|---|
| Lua | stylua |
| Go | goimports, gofmt |
| Python | ruff_fix, ruff_format, ruff_organize_imports, all using the ruff executable |
For web tooling, install Node.js and npm, then install the tools globally or with Mason:
npm install -g oxlint oxfmt eslint_d @fsouza/prettierd
:MasonInstall oxlint oxfmt eslint_d prettierd
For other languages, install only what you need:
cargo install stylua --locked. Put ~/.cargo/bin on PATH.gofmt, then run go install golang.org/x/tools/cmd/goimports@latest.
Add $(go env GOPATH)/bin to PATH, or your GOBIN directory if you set one.pipx install ruff and pipx ensurepath.Restart your shell and Neovim after changing PATH.
Open a source file and run :ConformInfo to see which formatters are available and inspect the formatter log.
Use :checkhealth cosmic for broader setup checks.
Plugin customization in lua/cosmic/config/config.lua uses:
plugins = { ... } for direct lazy.nvim specs{ 'repo/name', enabled = false } to disable a built-in pluginlsp.servers.NAME = true | false | { ... } to enable, disable, or override an LSP serverBuilt-in LSP defaults come from nvim-lspconfig and are extended by after/lsp/*.lua. User config under
lsp.servers.NAME is merged on top of those defaults when the server is enabled.
Enabled servers are installed through Mason automatically unless lsp.servers.NAME.mason = false is set.
With mason = false, install the server yourself and ensure its command is available to Neovim.
Cosmic enables configured servers with vim.lsp.enable() in either case.
See LSP config merging for server configuration and installation options.
disable_builtin_plugins, plugins.add, plugins.disable, plugins.opts, plugins.override,
and lsp.servers.NAME.opts have been removed.
Fetches CosmicNvim updates and fast-forwards your checkout without blocking the editor.
:CosmicUpdate
lazy-lock.json and your copy has local plugin updates, for example from :Lazy update,
asks before discarding them.After a successful update, restart Neovim to load the changes.
Run these checks from the repository root:
nvim -l tests/run.lua
stylua --check .
npx --yes markdownlint-cli@0.49.1 '*.md' 'docs/*.md' 'lua/**/*.md'
The test runner installs plugins into an isolated .tests/ directory, so your own setup is not touched.
Use stylua . to apply Lua formatting. CI runs all three checks on pull requests and pushes to main.
See AGENTS.md for project conventions.
Historical screenshots show earlier versions, not the current UI.