-
Notifications
You must be signed in to change notification settings - Fork 0
Development
NullString1 edited this page Jan 13, 2026
·
2 revisions
Setting up and managing development environments in NullOS.
NullOS provides multiple ways to create isolated development environments:
- direnv + nix-shell - Per-project automatic environments
- nix develop - Flake-based development
- Docker - Containerized development
- Global tools - System-wide development packages
NullOS includes direnv for automatic project environments.
When you cd into a project directory:
- direnv detects
.envrc - Loads specified Nix environment
- Provides project-specific tools
- Automatically cleans up when leaving directory
1. Create .envrc in project:
# To use flake's devShell
use flakeOr for shell.nix:
# To use legacy nix-shell
use nix2. Allow direnv:
direnv allow3. Tools are now available:
# Automatically in PATH when in directory
node --version
python --versionCreate shell.nix in your project:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
nodejs
yarn
nodePackages.typescript
];
shellHook = ''
echo "Node development environment loaded"
echo "Node: $(node --version)"
'';
}nix-shell{
description = "My Project";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.${system}.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs
python3
rustc
cargo
];
shellHook = ''
echo "Development environment ready!"
'';
};
};
}nix develop# shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
python311
python311Packages.pip
python311Packages.virtualenv
python311Packages.numpy
python311Packages.pandas
];
shellHook = ''
# Create venv if doesn't exist
if [ ! -d .venv ]; then
python -m venv .venv
fi
source .venv/bin/activate
'';
}.envrc:
use nix
layout python python3.11{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
nodePackages.npm
nodePackages.pnpm
nodePackages.typescript
nodePackages.eslint
];
}{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
rustc
cargo
rustfmt
clippy
rust-analyzer
];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
}{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
go
gopls
gotools
go-tools
];
}{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
gcc
cmake
gnumake
gdb
clang-tools
];
}NullOS includes Docker support.
# Start container
docker run -it ubuntu bash
# Docker Compose
docker-compose up
# Build image
docker build -t myapp .docker-compose.yml:
version: '3.8'
services:
dev:
image: node:20
volumes:
- .:/app
working_dir: /app
command: npm run dev
ports:
- "3000:3000"# Add to home/vscode.nix
extensions = with pkgs.vscode-extensions; [
ms-azuretools.vscode-docker
ms-vscode-remote.remote-containers
];{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
postgresql
];
shellHook = ''
export PGDATA=$PWD/postgres_data
export PGHOST=$PWD/postgres
export LOG_PATH=$PWD/postgres/LOG
export PGDATABASE=postgres
export DATABASE_URL="postgresql:///postgres?host=$PGHOST"
if [ ! -d $PGHOST ]; then
mkdir -p $PGHOST
fi
if [ ! -d $PGDATA ]; then
echo 'Initializing postgresql database...'
initdb $PGDATA --auth=trust >/dev/null
fi
pg_ctl start -l $LOG_PATH -o "-c listen_addresses= -c unix_socket_directories=$PGHOST"
trap "pg_ctl stop" EXIT
'';
}{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
mongodb
];
shellHook = ''
mkdir -p $PWD/.mongo
mongod --dbpath=$PWD/.mongo --bind_ip 127.0.0.1 &
export MONGO_PID=$!
trap "kill $MONGO_PID" EXIT
'';
}Already configured in NullOS with extensions:
# home/vscode.nix
programs.vscode = {
enable = true;
extensions = with pkgs.vscode-extensions; [
jnoortheen.nix-ide
rust-lang.rust-analyzer
ms-python.python
# Add project-specific extensions
];
};Configured via NVF in home/nvf.nix.
Already included in NullOS:
# modules/software/android-studio.nix
programs.adb.enable = true;Tools available:
- Android Studio
- adb (Android Debug Bridge)
- SDK tools
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
awscli2
terraform
kubectl
];
}buildInputs = with pkgs; [
google-cloud-sdk
];{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
# Python testing
python311Packages.pytest
python311Packages.pytest-cov
# Node testing
nodePackages.jest
nodePackages.mocha
# Load testing
k6
wrk
];
}With direnv, environment loads automatically:
cd ~/project # Loads environment
which node # /nix/store/...-nodejs/bin/node
cd ~ # Unloads environment
which node # command not foundCommit flake.nix or shell.nix to Git:
git clone your-project
cd your-project
nix develop # Everyone gets same environment{
devShells.${system} = {
default = pkgs.mkShell { ... };
python = pkgs.mkShell {
buildInputs = [ pkgs.python311 ];
};
node = pkgs.mkShell {
buildInputs = [ pkgs.nodejs ];
};
};
}Use with:
nix develop .#python
nix develop .#nodeInstalled system-wide in NullOS:
- Version control: git, gh
- Editors: neovim, vscode
- Build tools: gcc, cmake, make
- Containers: docker, docker-compose
- Debug: gdb
- Analysis: binwalk, hexdump
See modules/software/packages.nix for full list or check System Applications.
mkdir my-project
cd my-project
# Create flake
nix flake init
# Edit flake.nix for your needs
# Create .envrc
echo "use flake" > .envrc
direnv allow
# Start coding!git clone project
cd project
# If has flake.nix
nix develop
# If has shell.nix
nix-shell
# Or create .envrc
echo "use nix" > .envrc
direnv allow# Check if allowed
direnv status
# Allow
direnv allow
# Reload
direnv reload# Check what's in PATH
which python
readlink $(which python)
# Ensure in correct directory
pwd
# Check .envrc
cat .envrc# Clear cache
rm -rf .direnv
# Reload
direnv reload
# Or rebuild
nix develop --rebuild- Adding Applications - Install development tools
- Customization Guide - Customize development setup
- Troubleshooting - Fix common issues