সেই সকাল এখনও মনে আছে যখন New Project-এ Join করেছিলাম আর তিন ঘন্টা Node.js Versions-এর সাথে Fight করতে হয়েছিল। README বলেছিল "Requires Node 18," কিন্তু System-এ 20 ছিল, আর nvm Moody ছিল। Environment কাজ করতে যখন Time নিলো, ততক্ষণে Forget করেছিলাম কেন Contribute করতে চেয়েছিলাম। সেই মুহূর্তে Realize করেছিলাম: Nix আর direnv development environment সেটআপ করা ছাড়া এই "Works on my machine" পেইন থেকে মুক্তি নেই।
"Just Install It"-এর Chaos
Traditional Development Setup Familiar Pattern Follow করে। Repo Clone করো, README পড়ো, Right Language Version Install করো, Dependencies Install করো, বুঝতে পারো Specific Database Version দরকার, সেটা Install করো, Environment Variables Configure করো, Project-এর Older CLI Tool Version দরকার Discover করো, Package Manager-এর সাথে Fight করো, আর Eventually — Lucky হলে — Application Run করো।
Problems Multiply হয় যখন Projects-এর মধ্যে Switch করো। Node 18 Project তোমার Node 20 Side Project-এর সাথে Conflict করে। Python 3.9 Dependency তোমার System Tools Break করে। গতকাল কাজ করা Database Version আজ Production-এর সাথে Match করে না। আর New Team Member Onboard করাও — তাদের দেখতে হবে Same Three-hour Ritual-এর মধ্য দিয়ে।
যা দরকার ছিল তা হলো Environment Declare করার Way: "This project needs Node 18.17, PostgreSQL 15, Redis 7, আর এই Specific CLI Tools।" আর চাইলাম এটা Just Work করুক যখন Project Directory-এ Enter করি।
Nix আর direnv development environment কেন দরকার?
Nix প্রথম Problem Solve করে। এটা এমন Package Manager যেটা Any Version of Any Package Side-by-side Install করতে পারে Conflicts ছাড়া। direnv দ্বিতীয় Problem Solve করে — এটা Automatic Activate করে Environment Variables আর Tools যখন Directory-এ Enter করো।
Together, তারা কিছু Powerful Create করে: Development Environment যেটা Automatic Activate হয় যখন cd দিয়ে Project-এ যাও আর Disappear হয় যখন Leave করো। No Manual Switching। No Global System Pollution। Just Clean, Isolated, Reproducible Environments।
Actually কিভাবে কাজ করে
যখন Project Directory-এ Enter করি, direnv .envrc File Detect করে আর Load করে Environment যেটা Defined আছে। সেই File Nix-কে বলে Build করতে Shell Exactly Packages দিয়ে যেগুলো Project-এর flake.nix-এ Specified। Directory Leave করলে direnv Unload করে Everything। System Pristine থাকে।
Go Project-এর Typical Setup দেখি:
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
go_1_22
golangci-lint
gotools
gopls
# Project-specific Tools
postgresql_16
redis
jq
# এই Versions `flake.lock` দিয়ে Pinned
# Team-এর Everyone Exact Same Versions পায়
];
shellHook = ''
echo "Go $(go version)"
echo "PostgreSQL $(pg_config --version)"
# Local Project Paths Setup করো
export PGDATA="$PWD/.postgres"
export REDIS_DATA="$PWD/.redis"
'';
};
});
}আর .envrc File যেটা Activate করে:
# .envrc
use flakeThat's it। cd দিয়ে Project-এ গেলে direnv Nix Flake Load করে, আর Suddenly Go 1.22, Exact Linter Version, PostgreSQL 16, Redis, আর সব Configured Tools থাকে। cd দিয়ে বের হলে Gone। System Shell Untouched থাকে।
যে Features Matter করে
flake.lock File প্রতিটা Dependency-কে Exact Commit-এ Pin করে। Teammate Run করলে Bit-for-bit Identical Versions পায় প্রতিটা Tool-এর। No "works on my machine" কারণ Everyone Literally Same Machine Defined in Code।
Dependencies Update করতে চাও? nix flake update Lock File Regenerate করে। Exactly কী Change হলো জানতে চাও? git diff flake.lock প্রতিটা Package Version Change দেখায়। Roll Back করতে চাও? git checkout Previous Lock File। Development Environment-এর জন্য Version Control।
True Isolation
প্রতিটা Project নিজের Namespace of Packages পায়। একটা Project Node 18.17-এর উপর Specific npm Version-এ, আরেকটা Node 20-এর উপর Different npm-এ, আরেকটা Ancient Node 16-এ Legacy Maintenance-এর জন্য। Never Interfere with each other বা System Packages।
Environment Variables-এর জন্যও Extend হয়। Flake-এর shellHook Project-specific Paths আর Configuration Set করে। Directory Leave করলে Those Variables Disappear। Accidentally Production Commands Development Credentials দিয়ে Run করার Fear নেই Environment Files Switch করতে ভুলে।
Instant Onboarding
New Team Member Join করে? তারা Nix Install করে, Repo Clone করে, cd দিয়ে Directory-এ যায়, আর direnv allow Run করে। That's it। Entire Environment Automatic Build হয়। Same Go Version, Same Linter, Same Database, Same Everything। Onboarding Time Hours থেকে Minutes-এ Drop করে।
Real-World Project Examples
Different Projects Need Different Setups। Common Scenarios কিভাবে Structure করি:
Database সহ Web Project
{
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
pnpm
postgresql_16
redis
];
shellHook = ''
# Services Automatic Start করো যদি Already Running না হয়
if [ ! -d "$PGDATA" ]; then
initdb --auth=trust --no-locale --encoding=UTF8
fi
pg_ctl start -l log/postgres.log 2>/dev/null || true
redis-server --daemonize yes --dir "$PWD/.redis" 2>/dev/null || true
echo "Node $(node --version)"
echo "Database ready on localhost:5432"
'';
};
});
}এখন Directory Enter করলে Automatic PostgreSQL আর Redis Start হয় (Already Running না থাকলে) আর Leave করলে Stop। Entire Development Stack Self-contained।
Multi-Language Project
কখনও এক Project-এ Multiple Ecosystem দরকার:
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
# Backend
go_1_22
# Frontend
nodejs_20
pnpm
# Infrastructure
terraform
kubectl
awscli2
# Common Tools
jq
yq
git
];
};
}Team-এর Everyone Exact Same Terraform Version Use করে। "Upgrade your CLI" Slack Messages নেই যখন কেউ Infrastructure Code Update করে।
Honest Trade-offs
এই Setup কোনোভাবেই Free না। First Time কেউ Nix Environment Run করে, Build করতে কিছু সময় লাগতে পারে — বিশেষ করে Binary Caches Miss করলে। সেই "Instant Onboarding" হয়ে যায় "Wait 20 minutes while Nix Compiles Everything।" Subsequent Runs Fast থাকে, Caching-এর জন্য, কিন্তু সেই Initial Build এর পেইন একদম সহ্য করার মতো না।
আর Nix এর এরর মেসেজগুলো? জঘন্য। মনে হয় যেন কোনো এলিয়েন ল্যাঙ্গুয়েজ পড়তেছি। মাঝে মাঝে ছোট একটা টাইপো ঠিক করতে গিয়ে ঘন্টার পর ঘন্টা চলে যায়। Nix-এর নিজের Language, নিজের Concepts, আর Documentation যেটা Often Assume করে তুমি Already সেই Concepts বুঝো। Junior Developer-কে Nix শেখানো তাদের First Line of Code লেখার আগে Probably Overkill। Simple Projects-এর জন্য Overhead Worth না হতে পারে।
Docker Compose Similar Problems Solve করে আর Better Fit হতে পারে যদি Team Already Comfortable থাকে। Trade-off হলো Docker-এর Overhead আর Commands Container-এর ভিতর Run করার দরকার Rather than Native Shell। Nix Container-like Isolation দেয় Native Performance-এর সাথে।
কখন এটা Shine করে
Nix + direnv Reach করি যখন:
- Multiple Projects Same Tool-এর Different Versions চায়
- Team Onboarding Painful আর Inconsistent
- "Works on my machine" Regularly হয়
- CI আর Local Environment Exactly Match করতে চাই
- Complex Development Stacks দরকার (Multiple Databases, Message Queues, etc.)
Reach করি না যখন:
- এটা Quick One-off Script
- Team Development-এ New আর Already Overwhelmed
- Project শুধু একটা Common Tool চায় (যেমন শুধু Node.js)
- Everyone Already তাদের Setup-এ Happy
Getting Started
নিজে Try করতে চাইলে:
- Nix Install করো Flakes Enable করে: Determinate Systems installer Easy বানায়
- direnv Install করো:
nix profile install nixpkgs#direnv(Ironically) বা System Package Manager Use করো - direnv-কে Shell-এ Hook করো:
direnv hook bash(বা zsh, fish) Shell Config-এ - Project Root-এ
flake.nixCreate করো (উপরের Examples থেকে Start করো) .envrcCreate করো শুধুuse flakeদিয়ে- Project Directory-এ
direnv allowRun করো
That's it। Environment Automatic Activate হয়।
Resources
- direnv documentation - Shell-এর জন্য Hook Setup
- nix.dev - Practical Nix Guide, বিশেষ করে Flakes Tutorial
- Zero to Nix - Beginner-friendly Intro
- My dotfiles - Real-world Development Shell Examples
Meta Description: Nix আর direnv development environment সেটআপ করে আপনার প্রোজেক্টকে Isolated এবং Reproducible বানান। "Works on my machine" ঝামেলার চিরস্থায়ী সমাধান।
