title: "Midnight Development on Windows via WSL2: Complete Setup Guide"
published: true
description: "A comprehensive guide to setting up Midnight development environment on Windows using WSL2"
tags: ["midnight", "wsl2", "blockchain", "zkshield", "web3"]
cover_image: https://images.unsplash.com/photo-1629654297299-c8506221ca97?w=800
canonical_url: null
series: null
Midnight Development on Windows via WSL2: Complete Setup Guide
Midnight's toolchain is designed to run on Linux and macOS, which presents a challenge for Windows developers. While native Windows development isn't supported, WSL2 (Windows Subsystem for Linux) provides an excellent workaround. This tutorial walks you through setting up a complete Midnight development environment on Windows 10/11.
Prerequisites
Before we begin, ensure you have:
- Windows 10 (version 2004+) or Windows 11
- At least 8GB RAM (16GB recommended)
- 20GB free disk space
- Administrator access on your Windows machine
Part 1: Installing WSL2
Enable WSL2
First, open Windows PowerShell as Administrator and run:
# Enable required Windows features
wsl --install
β οΈ WSL Terminal: These commands run in Windows PowerShell
After installation, restart your computer. On restart, Ubuntu will automatically install. Create your Linux username and password when prompted.
Install Ubuntu (Recommended)
If WSL installed a different distribution, install Ubuntu explicitly:
# WSL Terminal
wsl --install -d Ubuntu-22.04
Configure .wslconfig
This is the most critical step for Midnight development. The default WSL2 memory allocation (usually 2GB) is insufficient for the proof server, which requires at least 4GB.
Create or edit .wslconfig in your Windows user home directory:
Windows Terminal (not WSL):
# Create the config file
notepad $env:USERPROFILE\.wslconfig
Add the following content:
[wsl2]
# Allocate 6GB memory to WSL2 (adjust based on your RAM)
memory=6GB
# Use all available processors
processors=8
# Set appropriate swap size
swap=4GB
# Enable DNS tunneling
dnsTunneling=true
# Enable automatic memory reclamation
autoMemoryReclaim=gradual
# Enable local port forwarding
localhostForwarding=true
# Set localhostForwarding
localhostForwarding=true
Important: After saving
.wslconfig, restart WSL from PowerShell:
wsl --shutdown
Part 2: Docker Desktop Configuration
Install Docker Desktop
- Download Docker Desktop from docker.com
- During installation, check "Use WSL2 instead of Hyper-V"
- Start Docker Desktop
- Go to Settings β Resources β WSL Integration
- Enable integration with your Ubuntu distribution
Verify Docker in WSL
Open a new WSL terminal and verify Docker is accessible:
# WSL Terminal
docker --version
docker-compose --version
# Test Docker is running
docker run hello-world
π‘ Pro Tip: If you get "permission denied while trying to connect to the Docker daemon," add your user to the docker group:
# WSL Terminal
sudo usermod -aG docker $USER
newgrp docker
Part 3: Midnight Toolchain Setup
Install Node.js
Midnight requires Node.js 18+. Install using nvm for version management:
# WSL Terminal
# Install nvm if not already installed
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Reload shell
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install and use Node.js 20
nvm install 20
nvm use 20
# Verify installation
node --version # Should output v20.x.x
npm --version
Install Compact Compiler
Install the Midnight Compact compiler:
# WSL Terminal
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh
# Reload shell configuration
source ~/.bashrc
# Verify installation
compact --version
compact compile --version
which compact
β οΈ Common Issue: If
compactcommand is not found after installation, manually add it to your PATH:
# WSL Terminal
echo 'export PATH="$HOME/.compact/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Install Midnight MCP
The Midnight MCP (Model Context Protocol) provides essential tooling:
# WSL Terminal
npm install -g @midnight/mcp
Setup Docker Stack for Local Development
Create a docker-compose file for the Midnight local stack:
# WSL Terminal
mkdir -p ~/midnight-project
cd ~/midnight-project
mkdir -p docker
Create docker/docker-compose.yml:
version: '3.8'
services:
proof-server:
image: ghcr.io/midnightntwrk/proof-server:latest
container_name: midnight-proof-server
ports:
- "8080:8080"
environment:
- PROOF_SERVER_PORT=8080
- RUST_LOG=info
mem_limit: 4g
mem_reservation: 2g
shm_size: 2g
volumes:
- proof-data:/data
networks:
- midnight-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
indexer:
image: ghcr.io/midnightntwrk/indexer:latest
container_name: midnight-indexer
ports:
- "3000:3000"
depends_on:
- proof-server
environment:
- PROOF_SERVER_URL=http://proof-server:8080
- NETWORK=devnet
networks:
- midnight-network
volumes:
proof-data:
networks:
midnight-network:
driver: bridge
Start the stack:
# WSL Terminal
cd ~/midnight-project/docker
docker-compose up -d
# Check services are running
docker-compose ps
docker-compose logs -f proof-server
Part 4: End-to-End Verification
Create Your First Midnight Contract
Create a new project:
# WSL Terminal
cd ~/midnight-project
compact new hello-midnight
cd hello-midnight
ls -la
Edit contract.compact with a simple counter contract:
// A simple counter contract for Midnight
// Demonstrates basic state management and increment operations
contract hello_midnight {
// Store a counter value
pub counter: u32;
// Constructor - initialize counter to 0
pub fn new() -> Self {
Self {
counter: 0,
}
}
// Increment the counter
pub fn increment(self, mut ctx: Context) -> u32 {
self.counter = self.counter + 1;
return self.counter;
}
// Get current counter value
pub fn get_counter(self, ctx: Context) -> u32 {
return self.counter;
}
}
Compile the Contract
# WSL Terminal
cd ~/midnight-project/hello-midnight
compact compile contract.compact
If successful, you'll see:
β Compiled successfully
Output: build/contract.json
Deploy to Local Devnet
# WSL Terminal
# Ensure proof server is running
curl http://localhost:8080/health
# Deploy using the CLI (requires Lace wallet installed)
compact deploy --network devnet --proof-server http://localhost:8080
Note: For deployment, you'll need the Lace wallet browser extension installed and configured with testnet tokens. See the Midnight Documentation for details.
Part 5: What Does NOT Work
Understanding what doesn't work is crucial to avoid frustration:
β Native Windows PowerShell
- The Compact compiler does not work in Windows PowerShell or CMD
- All compilation must happen inside WSL2
- Even with WSLg (WSL GUI), some tools may behave unexpectedly
β Windows-native Node.js/npm
- Do not install Node.js directly on Windows
- Use Node.js only inside WSL2
- Windows npm packages may have binary dependencies that won't work
β Windows Docker without WSL2
- Docker Desktop without WSL2 backend is not supported
- Ensure Docker is using WSL2 backend (check Docker Desktop settings)
β VSCode Remote-WSL Without Proper Setup
- When using VSCode with Remote-WSL extension, ensure your terminal is actually in WSL
- Always verify with
uname -ashowing "Linux"
Part 6: Troubleshooting
Proof Server Out of Memory (OOM)
If you see errors like "memory allocation failed":
- Verify
.wslconfighas sufficient memory allocation (minimum 4GB, recommended 6GB) - Restart WSL:
wsl --shutdownin PowerShell - Restart Docker Desktop
- Check container memory:
docker stats
Detailed fix for OOM:
# Windows PowerShell (Administrator)
# Check current WSL memory allocation
wsl -e cat /proc/meminfo
# If you see less than 4GB available, update .wslconfig
notepad $env:USERPROFILE\.wslconfig
# Ensure these settings:
[wsl2]
memory=6GB
swap=4GB
Docker Access Denied
If you get "Cannot connect to Docker daemon":
# WSL Terminal
# Check if Docker is running
sudo systemctl status docker
# Start Docker if needed
sudo systemctl start docker
# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in, or run:
newgrp docker
# Alternative: Use Docker without systemd
sudo service docker start
Compact Command Not Found
If compact is not recognized:
# WSL Terminal
# Check if it's installed
ls -la ~/.compact/bin/
# Add to PATH manually
export PATH="$HOME/.compact/bin:$PATH"
echo 'export PATH="$HOME/.compact/bin:$PATH"' >> ~/.bashrc
# Reload
source ~/.bashrc
# Verify with full path
~/.compact/bin/compact --version
PATH Issues Between Windows and WSL
- Never mix Windows and WSL paths
- Always use
/home/username/notC:\Users\...paths inside WSL - VSCode Remote-WSL will handle path translation automatically
- If VSCode opens files in Windows temp directory, use
code .from WSL terminal
Network Connectivity Issues
If proof server cannot connect to indexer:
# Check Docker network
docker network ls
docker network inspect midnight-network
# Restart services
cd ~/midnight-project/docker
docker-compose down
docker-compose up -d
# Check logs
docker-compose logs --tail=50
Disk Space Issues
WSL2 can consume significant disk space. Clean up periodically:
# WSL Terminal
# Clean Docker
docker system prune -a
# Clean WSL
wsl --shutdown
# Then run Disk Cleanup on Windows and select "Clean up system files" > "Windows Update Cleanup"
Performance Optimization
For faster development:
- Use VSCode Remote-WSL - Best development experience
- Enable WSL2 localhost forwarding - Reduces network latency
- Store projects in WSL - Not on Windows filesystem
- Use SSD for WSL - If possible, store WSL on SSD
# Recommended VSCode extensions for Midnight development:
# - Remote - WSL
# - Compact
# - Docker
# - GitLens
Common Error Messages
| Error | Solution |
|---|---|
| "proof-server OOM" | Increase .wslconfig memory to 6GB+ |
| "docker: permission denied" | Add user to docker group |
| "compact: command not found" | Add ~/.compact/bin to PATH |
| "Connection refused" | Ensure Docker containers are running |
| "Node version mismatch" | Use Node.js 18+ inside WSL |
Conclusion
You now have a fully functional Midnight development environment running on Windows via WSL2. The key takeaways are:
- Always use WSL2 - Never try to run Midnight tools directly on Windows
-
Configure
.wslconfig- Allocate sufficient memory (6GB recommended) - Use Docker with WSL2 backend - Not Hyper-V or native Windows
- Keep all development inside WSL - Including Node.js, npm, and Compact
- Use VSCode Remote-WSL - For the best development experience
With this setup, you can now develop privacy-preserving DApps on Midnight directly from your Windows machine. The initial setup takes about 30-45 minutes, but you'll have a production-ready development environment.
Quick Reference Commands
# Start development
wsl # Enter WSL
cd ~/midnight-project/docker && docker-compose up -d
# Compile contract
cd ~/midnight-project/hello-midnight
compact compile contract.compact
# Deploy (requires Lace wallet)
compact deploy --network devnet
# Check proof server
curl http://localhost:8080/health
# Stop development
docker-compose down
exit # Exit WSL
Next Steps:
- Explore the Midnight Documentation
- Join the Midnight Discord
- Try the Hello World Tutorial
- Build your first privacy-preserving DApp!
Published on Dev.to | #MidnightforDevs | @midnightntwrk
Top comments (0)