One of the most important features of NixOS is the ability to configure the entire system declaratively, including packages to be installed, services to be run, as well as other settings and options.
NixOS configurations can be used to test and use NixOS using a virtual machine, independent of an installation on a "bare metal" computer.
A NixOS configuration is a Nix language function following the [NixOS module](https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules) convention.
- A working [Nix installation](https://nixos.org/manual/nix/stable/installation/installation.html) on Linux, or [NixOS](https://nixos.org/manual/nixos/stable/index.html#sec-installation), with a graphical environment
- Basic knowledge of the [Nix language](reading-nix-language)
## Starting from the default NixOS configuration
In this tutorial you will use the default configuration that is shipped with NixOS.[^nixosconf]
[^nixosconf]: This [configuration template](https://github.com/NixOS/nixpkgs/blob/4e0525a8cdb370d31c1e1ba2641ad2a91fded57d/nixos/modules/installer/tools/tools.nix#L122-L226) is used.
:::{admonition} NixOS
On NixOS, use the `nixos-generate-config` command to create a configuration file that contains some useful defaults and configuration suggestions.
By default, the configuration file is located at `/etc/nixos/configuration.nix`.
To avoid overwriting this file you have to specify the output directory.
Create a NixOS configuration in your working directory:
```shell-session
nixos-generate-config --dir ./
```
In the working directory you will then find two files:
1.`hardware-configuration.nix` is specific to the hardware `nix-generate-config` is being run on.
You can ignore that file for this tutorial because it has no effect inside a virtual machine.
2.`configuration.nix` contains various suggestions and comments for the initial setup of a desktop computer.
Do not use plain text passwords outside of this example unless you know what you are doing. See [`initialHashedPassword`](https://nixos.org/manual/nixos/stable/options.html#opt-users.extraUsers._name_.initialHashedPassword) or [`ssh.authorizedKeys`](https://nixos.org/manual/nixos/stable/options.html#opt-users.extraUsers._name_.openssh.authorizedKeys.keys) for more secure alternatives.
- The [`-A` option](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-attr) specifies the attribute to pick from the provided Nix expression `<nixpkgs/nixos>`.
To build the virtual machine, we choose the `vm` attribute as defined in [`nixos/default.nix`](https://github.com/NixOS/nixpkgs/blob/7c164f4bea71d74d98780ab7be4f9105630a2eba/nixos/default.nix#L19).
- The [`-I` option](https://nixos.org/manual/nix/stable/command-ref/opt-common.html#opt-I) prepends entries to the search path.
Here we set `nixpkgs` to refer to a [specific version of Nixpkgs](ref-pinning-nixpkgs) and set `nix-config` to the `configuration.nix` file in the current directory.
On NixOS the `$NIX_PATH` environment variable is usually set up automatically, and there is also [a convenience command for building virtual machines](https://nixos.org/manual/nixos/stable/#sec-changing-config).
You can use the current version of `nixpkgs` to build the virtual machine like this: