How to Install and Configure Neovim for Development on Fedora

Install Neovim on Fedora using DNF and create a basic Lua configuration file for development.

The fresh install reality

You boot a fresh Fedora Workstation or Server install and open a terminal. You type vim and get the legacy editor. You run sudo dnf install neovim and get the modern version, but the first launch shows a blank screen with no line numbers, no syntax highlighting, and no indentation rules. You need a development environment that actually understands modern code. The default Neovim experience is intentionally minimal. It expects you to define your preferences in Lua, not Vimscript. This guide walks you through installing the Fedora package, creating a functional Lua configuration, and verifying that the editor behaves like a modern development tool.

How Neovim handles configuration

Neovim separates its runtime files from user configuration. The package manager drops the core binary and standard library into /usr/share/nvim. Your settings live in ~/.config/nvim. This follows the XDG Base Directory specification, which keeps your home directory clean and makes backups straightforward. When Neovim starts, it looks for init.lua in that directory. If the file exists, it executes it as a Lua script before rendering the UI. This replaces the old vimrc approach. Lua gives you direct access to Neovim's internal APIs. You can toggle options, map keys, and load plugins using standard programming constructs instead of domain-specific macros. Fedora ships Neovim with a bundled Lua interpreter, so you do not need to install system-wide Lua packages unless you are writing external plugins that call external libraries.

The configuration loader reads init.lua from top to bottom. Every line is evaluated immediately. If a line fails, the loader stops and prints a traceback. This strict evaluation model prevents silent failures. You will know exactly which line broke the editor. Trust the package manager for runtime files. Manual edits to /usr/share/nvim/runtime/ drift during updates. Keep your customizations in your home directory.

Setting up the Lua environment

Run the installation command first. The package manager resolves dependencies and places the binary in your standard executable path.

sudo dnf install neovim -y
# -y skips the confirmation prompt. The package pulls in lua and shared libraries automatically.

Create the configuration directory structure. Neovim will not create it for you, and it will silently ignore missing configuration files.

mkdir -p ~/.config/nvim
# -p ensures parent directories are created without error if they already exist.
# ~/.config/nvim is the standard location for user-level Neovim settings on Fedora.

Write the initial configuration file. This script sets up line numbers, converts tabs to spaces, and defines indentation width. These are baseline requirements for collaborative development.

-- Enable line numbers in the left gutter
vim.opt.number = true
-- Convert tab characters to spaces on save
vim.opt.expandtab = true
-- Define the visual width of a tab character
vim.opt.tabstop = 4
-- Set the actual indentation width for auto-indent and formatting
vim.opt.shiftwidth = 4
-- Enable syntax highlighting and terminal true color support
vim.opt.termguicolors = true

The vim.opt table is the modern way to change editor settings. It replaces the older vim.cmd('set number') syntax. Using vim.opt gives you type safety and direct access to the underlying option flags. The termguicolors option tells Neovim to bypass the terminal's 256-color palette and request direct RGB values. This requires a terminal emulator that supports the 24-bit color escape sequence, which GNOME Terminal, Konsole, and Alacritty all handle by default on Fedora.

Save the file and launch the editor. Neovim reads the Lua file on startup. If the syntax is valid, the options apply immediately. If the file contains a syntax error, Neovim prints a traceback to the command line and falls back to defaults. Run dnf upgrade --refresh weekly to keep the Neovim package and its Lua dependencies current. The refresh flag forces a metadata check before applying updates.

Understanding the Lua runtime on Fedora

Fedora packages Neovim with a statically linked LuaJIT runtime for performance. This means the editor does not rely on the system lua package for its internal scripting. You can still install lua via dnf if you want to run standalone Lua scripts, but Neovim will ignore it. The bundled runtime includes the standard library and the vim.api module. You can call any internal Neovim function using vim.api.nvim_ prefixes. This design isolates the editor from system library changes. It also means you cannot accidentally break Neovim by updating a system Lua package.

When you write larger configurations, you will eventually split init.lua into multiple files. Neovim supports a lua/ directory inside ~/.config/nvim/. The editor automatically adds this path to the runtimepath. You can require modules using standard Lua syntax. This keeps your main configuration file short and delegates complex logic to dedicated scripts. Structure your files by feature. Put keymaps in lua/keymaps.lua. Put plugin specifications in lua/plugins.lua. Keep the root init.lua as a loader that requires each module. This pattern scales better than a single monolithic file.

Global variables live in vim.g. Use vim.g for plugin settings that expect a boolean or string flag. Use vim.opt for editor behavior like indentation, line numbers, and search highlighting. Mixing the two tables causes silent misconfigurations. The vim.g table does not trigger UI redraws. The vim.opt table does. Choose the correct table for the setting you are changing.

Verify the configuration

Open a test file and check the active settings. The :set command displays the current state of any option.

nvim test.lua
# Launch Neovim with a dummy file to trigger the configuration load.

Inside the editor, run the following command to confirm indentation settings:

:set expandtab? tabstop? shiftwidth?

The output should read expandtab, tabstop=4, shiftwidth=4. If you see noexpandtab or different values, the configuration file either failed to load or contains a typo. Exit the editor with :q and check the file permissions. Neovim requires read access to ~/.config/nvim/init.lua. A restrictive permission mask like 600 is fine. A mask of 000 will block the editor from reading the file.

Run nvim --version to confirm the package manager installed the correct build. The output lists the compiled features and the Lua version. Look for +lua in the feature list. If you see -lua, the package is broken or you are running a custom build. Reinstall the package if the flag is missing. Check the startup time with nvim --startuptime /tmp/nvim.log. This command writes a detailed breakdown of every configuration file and plugin that loaded. Read the log before guessing why the editor feels slow.

Common pitfalls and error patterns

Lua is strict about syntax. A missing comma or an unclosed bracket will halt the configuration loader. Neovim prints the exact line number and error type to the terminal.

Error detected while processing /home/user/.config/nvim/init.lua:
E5108: Error executing lua [string ":lua"]:1: '<name>' expected near 'opt'

This error usually means you typed vimopt.number instead of vim.opt.number. The dot operator is mandatory. Another frequent issue involves mixing Vimscript and Lua in the same file. Neovim treats init.lua as pure Lua. If you paste a set number command directly into the file, the Lua parser will reject it. You must wrap legacy commands in vim.cmd() or migrate them to vim.opt.

Configuration drift happens when you edit files in /usr/share/nvim/runtime/. Those files belong to the package manager. Any manual change will be overwritten during a dnf upgrade. Always keep your customizations in ~/.config/nvim. The package manager trusts the upstream runtime files. Your home directory is the only place you should modify editor behavior.

Plugin managers add another layer of complexity. Tools like lazy.nvim or packer.nvim require an internet connection during the first launch. If your Fedora system sits behind a corporate proxy or lacks DNS resolution, the plugin manager will timeout and leave the editor in a broken state. Run nviv --headless +q to force a background configuration check without opening the UI. This command triggers the Lua loader and exits immediately, printing any errors to standard output. Snapshot your configuration directory before adding a new plugin manager. Future-you will thank you when the dependency tree breaks.

Choosing your editor path

Use Neovim when you want a terminal-native editor with Lua-driven extensibility and a modern plugin ecosystem. Use Vim when you need guaranteed compatibility with legacy vimrc files and server environments that only ship the base vim-minimal package. Use a graphical IDE when you require built-in debugging, graphical profiling, and zero configuration overhead. Stick with the Fedora dnf package when you want automatic security updates and system-wide runtime integration. Download the official GitHub release when you need the absolute latest nightly features and do not mind managing dependencies manually.

Where to go next