Skip to content

Development

NullString1 edited this page Feb 2, 2026 · 3 revisions

Development Environments

Setting up and managing development environments in NullOS.

Overview

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

Direnv Integration

NullOS includes direnv for automatic project environments.

How It Works

When you cd into a project directory:

  1. direnv detects .envrc
  2. Loads specified Nix environment
  3. Provides project-specific tools
  4. Automatically cleans up when leaving directory

Using Direnv

1. Create .envrc in project:

# To use flake's devShell
use flake

Or for shell.nix:

# To use legacy nix-shell
use nix

2. Allow direnv:

direnv allow

3. Tools are now available:

# Automatically in PATH when in directory
node --version
python --version

Nix Shell

Basic shell.nix

Create shell.nix in your project:

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[nodejsyarnnodePackages.typescript];shellHook='' echo "Node development environment loaded" echo "Node: $(node --version)" '';}

Enter shell:

nix-shell

Flake-Based Development

Create flake.nix

{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!" '';};};}

Enter development shell:

nix develop

Language-Specific Setups

Python

# 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

Node.js

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[nodejs_20nodePackages.npmnodePackages.pnpmnodePackages.typescriptnodePackages.eslint];}

Rust

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[rustccargorustfmtclippyrust-analyzer];RUST_SRC_PATH="${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";}

Go

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[gogoplsgotoolsgo-tools];}

C/C++

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[gcccmakegnumakegdbclang-tools];}

Docker Development

NullOS includes Docker support.

Using Docker

# Start container
docker run -it ubuntu bash
# Docker Compose
docker-compose up
# Build image
docker build -t myapp .

Docker Development Template

docker-compose.yml:

version: '3.8'services:
dev:
image: node:20volumes:
- .:/appworking_dir: /appcommand: npm run devports:
- "3000:3000"

VS Code + Docker

# Add to home/vscode.nixextensions=withpkgs.vscode-extensions;[ms-azuretools.vscode-dockerms-vscode-remote.remote-containers];

Database Development

PostgreSQL

{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 '';}

MongoDB

{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 '';}

IDE Configuration

VSCode

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];};

Neovim

Configured via NixVim in home/nixvim.nix.


Android Development

Android Studio

Already included in NullOS:

# modules/software/android-studio.nixprograms.adb.enable=true;

Tools available:

  • Android Studio
  • adb (Android Debug Bridge)
  • SDK tools

Environment Variables

export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

Cloud Development

AWS CLI

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[awscli2terraformkubectl];}

Google Cloud

buildInputs=withpkgs;[google-cloud-sdk];

Testing Tools

General Testing

{pkgs ? import<nixpkgs>{}}:
pkgs.mkShell{buildInputs=withpkgs;[# Python testingpython311Packages.pytestpython311Packages.pytest-cov# Node testingnodePackages.jestnodePackages.mocha# Load testingk6wrk];}

Tips & Tricks

Automatic Environment Loading

With direnv, environment loads automatically:

cd~/project # Loads environment
which node # /nix/store/...-nodejs/bin/nodecd~# Unloads environment
which node # command not found

Sharing Environments

Commit flake.nix or shell.nix to Git:

git clone your-project
cd your-project
nix develop # Everyone gets same environment

Multiple Shells

{devShells.${system}={default=pkgs.mkShell{ ... };python=pkgs.mkShell{buildInputs=[pkgs.python311];};node=pkgs.mkShell{buildInputs=[pkgs.nodejs];};};}

Use with:

nix develop .#python
nix develop .#node

Global Development Tools

Installed 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.


Common Workflows

Starting New Project

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!

Existing Project

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

Troubleshooting

Direnv Not Loading

# Check if allowed
direnv status
# Allow
direnv allow
# Reload
direnv reload

Wrong Tool Version

# Check what's in PATH
which python
readlink $(which python)# Ensure in correct directorypwd# Check .envrc
cat .envrc

Build Fails

# Clear cache
rm -rf .direnv
# Reload
direnv reload
# Or rebuild
nix develop --rebuild

Next Steps

Clone this wiki locally