- Notifications
You must be signed in to change notification settings - Fork 0
Development
NullString1 edited this page Feb 2, 2026
·
3 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=withpkgs;[nodejsyarnnodePackages.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}:
letsystem="x86_64-linux";pkgs=nixpkgs.legacyPackages.${system};in{devShells.${system}.default=pkgs.mkShell{buildInputs=withpkgs;[nodejspython3rustccargo];shellHook='' echo "Development environment ready!" '';};};}nix develop# shell.nix{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[python311python311Packages.pippython311Packages.virtualenvpython311Packages.numpypython311Packages.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=withpkgs;[nodejs_20nodePackages.npmnodePackages.pnpmnodePackages.typescriptnodePackages.eslint];}{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[rustccargorustfmtclippyrust-analyzer];RUST_SRC_PATH="${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";}{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[gogoplsgotoolsgo-tools];}{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[gcccmakegnumakegdbclang-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:20volumes:
- .:/appworking_dir: /appcommand: npm run devports:
- "3000:3000"# Add to home/vscode.nixextensions=withpkgs.vscode-extensions;[ms-azuretools.vscode-dockerms-vscode-remote.remote-containers];{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[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=withpkgs;[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.nixprograms.vscode={enable=true;extensions=withpkgs.vscode-extensions;[jnoortheen.nix-iderust-lang.rust-analyzerms-python.python# Add project-specific extensions];};Configured via NixVim in home/nixvim.nix.
Already included in NullOS:
# modules/software/android-studio.nixprograms.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=withpkgs;[awscli2terraformkubectl];}buildInputs=withpkgs;[google-cloud-sdk];{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[# Python testingpython311Packages.pytestpython311Packages.pytest-cov# Node testingnodePackages.jestnodePackages.mocha# Load testingk6wrk];}With direnv, environment loads automatically:
cd~/project # Loads environment
which node # /nix/store/...-nodejs/bin/nodecd~# 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 .envrcecho"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 .envrcecho"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 directorypwd# 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