update blog post to include hugo specific front matter
This commit is contained in:
277
POST.md
Normal file
277
POST.md
Normal file
@@ -0,0 +1,277 @@
|
||||
---
|
||||
title: "Mastering Strudel: A Reproducible Development Environment with Nix"
|
||||
date: 2025-09-27T12:00:00+02:00
|
||||
draft: false
|
||||
tags: ["strudel", "nix", "development", "live-coding"]
|
||||
categories: ["Development"]
|
||||
build:
|
||||
render: never
|
||||
list: never
|
||||
publishResources: false
|
||||
---
|
||||
|
||||
# Mastering Strudel: A Reproducible Development Environment with Nix
|
||||
|
||||
Strudel is a fascinating JavaScript-based live coding environment that brings the power of TidalCycles to the web. As developers and musicians exploring algorithmic music composition, we've discovered that setting up a proper development environment is crucial for productive work. In this post, we'll dive deep into our Nix-based setup that makes Strudel development reproducible, reliable, and collaborative.
|
||||
|
||||
## Why Nix for Strudel Development?
|
||||
|
||||
Traditional development environments often suffer from the "works on my machine" syndrome. Dependencies drift, versions conflict, and onboarding new contributors becomes a chore. Nix solves these problems by providing declarative, reproducible environments.
|
||||
|
||||
Our Strudel development setup uses:
|
||||
|
||||
- **Nix Flakes** for pinned, reproducible dependencies
|
||||
- **Git submodules** to track the official Strudel repository
|
||||
- **Makefile** for convenient command shortcuts
|
||||
- **Comprehensive guidelines** for AI-assisted development
|
||||
|
||||
## Getting Started: The Complete Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before diving in, ensure you have:
|
||||
- [Nix](https://nixos.org/download.html) package manager (version 2.4+)
|
||||
- Git for version control
|
||||
|
||||
### Step-by-Step Setup
|
||||
|
||||
1. **Clone the repository**:
|
||||
```bash
|
||||
git clone <your-strudel-dev-repo-url>
|
||||
cd strudel
|
||||
```
|
||||
|
||||
2. **Initialize git submodules**:
|
||||
```bash
|
||||
make submodules-init submodules-update
|
||||
```
|
||||
This pulls in the official Strudel codebase as a submodule in the `src/` directory.
|
||||
|
||||
3. **Enter the development environment**:
|
||||
```bash
|
||||
make shell
|
||||
```
|
||||
This launches a Nix shell with Node.js 20, pnpm, and git pre-configured.
|
||||
|
||||
4. **Install dependencies**:
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
This runs `pnpm install` within the Nix environment, ensuring consistent package versions.
|
||||
|
||||
5. **Start the development server**:
|
||||
```bash
|
||||
make dev
|
||||
```
|
||||
The Strudel REPL will be available at `http://localhost:5173`.
|
||||
|
||||
## Understanding the Project Structure
|
||||
|
||||
```
|
||||
strudel/
|
||||
├── src/ # Strudel codebase (git submodule)
|
||||
├── AGENTS.md # Guidelines for AI assistants
|
||||
├── Makefile # Development shortcuts
|
||||
├── flake.nix # Nix development environment
|
||||
├── flake.lock # Nix flake lockfile
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
The `src/` directory contains the actual Strudel monorepo as a git submodule. This approach ensures we always work with a specific, tested version of Strudel while keeping our development environment separate.
|
||||
|
||||
## Workflow Mastery with Makefile
|
||||
|
||||
Our Makefile provides a clean interface for all development tasks:
|
||||
|
||||
```bash
|
||||
make help # Show all available targets
|
||||
make update # Initialize and update git submodules
|
||||
make install # Install dependencies
|
||||
make dev # Start development server
|
||||
make build # Build the project
|
||||
make test # Run tests
|
||||
make lint # Run linter
|
||||
make format # Format code
|
||||
make check # Run all checks
|
||||
make clean # Clean build artifacts
|
||||
make shell # Enter Nix development shell
|
||||
```
|
||||
|
||||
Every command automatically runs within the Nix environment, ensuring consistency across different machines and operating systems.
|
||||
|
||||
## Git Submodules: The Right Way
|
||||
|
||||
Working with git submodules can be tricky, but we've established best practices:
|
||||
|
||||
### Common Pitfalls and Solutions
|
||||
|
||||
**Problem**: `git status` shows submodule changes after installing dependencies.
|
||||
|
||||
**Solution**: Dependencies like `node_modules/` are properly ignored in the submodule's `.gitignore`. However, some files may have permission changes during installation (like executable scripts). To handle this:
|
||||
|
||||
```bash
|
||||
# Check what changed
|
||||
cd src && git status
|
||||
|
||||
# Discard unintended changes
|
||||
git submodule foreach git checkout -- .
|
||||
|
||||
# Reset submodule to clean state
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
**Key Principle**: Treat submodules as read-only for local changes. If you need to modify Strudel itself, commit changes to the upstream repository first.
|
||||
|
||||
## AI-Assisted Development: Guidelines for Success
|
||||
|
||||
Our `AGENTS.md` document provides comprehensive guidelines for AI assistants working with Strudel. Here are the critical points:
|
||||
|
||||
### Strudel is NOT JavaScript
|
||||
|
||||
Despite being built with JavaScript, Strudel uses its own pattern-based syntax:
|
||||
|
||||
```javascript
|
||||
// ✅ CORRECT - Direct pattern composition
|
||||
$: sound("bd*4")
|
||||
$: sound("~ sd ~ sd")
|
||||
$: sound("hh*8").gain(0.3)
|
||||
|
||||
// ❌ WRONG - JavaScript-style approach
|
||||
const kick = sound("bd*4");
|
||||
const snare = sound("~ sd ~ sd");
|
||||
```
|
||||
|
||||
### Essential Syntax Patterns
|
||||
|
||||
**Parallel Patterns**: Use multiple `$:` lines for simultaneous playback
|
||||
**Muting**: Prefix with `_` to silence patterns during live performance
|
||||
**Mini-notation**: `"bd ~ sd ~"` for rhythmic patterns
|
||||
**Scale-based Composition**: Use `n("0 2 4 6").scale("C:minor")` instead of manual note names
|
||||
|
||||
### Sound Sources and Effects
|
||||
|
||||
```javascript
|
||||
// Drum samples
|
||||
$: sound("bd sd hh oh")
|
||||
|
||||
// Synthesizers with scales
|
||||
$: n("0 2 4 6").scale("C:minor").sound("sawtooth")
|
||||
|
||||
// Live effects
|
||||
$: sound("bd*4").lpf(sine.range(200, 2000).slow(8))
|
||||
```
|
||||
|
||||
### Live Performance Best Practices
|
||||
|
||||
- Each `$:` line is independently controllable
|
||||
- Use `_$:` to mute sections during performance
|
||||
- Include modulation for evolving sounds
|
||||
- Keep patterns readable for live modification
|
||||
|
||||
## Nix Flake Configuration Deep Dive
|
||||
|
||||
Our `flake.nix` provides a robust development environment:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "Strudel development environment";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
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; [
|
||||
nodejs_20
|
||||
pnpm
|
||||
git
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "Strudel development environment loaded"
|
||||
echo "Node.js: $(node --version)"
|
||||
echo "pnpm: $(pnpm --version)"
|
||||
'';
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
This configuration:
|
||||
- Pins Nixpkgs to version 25.05 for reproducibility
|
||||
- Provides Node.js 20 and pnpm for package management
|
||||
- Includes git for version control operations
|
||||
- Shows version information on shell entry
|
||||
|
||||
## Contributing and Best Practices
|
||||
|
||||
When contributing to Strudel development:
|
||||
|
||||
- Follow the guidelines in `AGENTS.md` for AI-assisted work
|
||||
- Use lowercase commit messages
|
||||
- Ensure all changes pass `make check`
|
||||
- Test thoroughly before submitting
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### Submodule Problems
|
||||
```bash
|
||||
make update # Reinitialize submodules
|
||||
```
|
||||
|
||||
### Dependency Issues
|
||||
```bash
|
||||
make clean && make install # Fresh dependency installation
|
||||
```
|
||||
|
||||
### Nix Issues
|
||||
Ensure Nix is installed and up-to-date. On Linux:
|
||||
```bash
|
||||
sh <(curl -L https://nixos.org/nix/install) --daemon
|
||||
```
|
||||
|
||||
## The Power of Reproducible Environments
|
||||
|
||||
This Nix-based setup eliminates common development headaches:
|
||||
|
||||
- **Zero configuration drift**: Everyone gets identical environments
|
||||
- **Easy onboarding**: New contributors can start coding immediately
|
||||
- **Version pinning**: Dependencies are locked to specific versions
|
||||
- **Cross-platform compatibility**: Works on Linux, macOS, and Windows (via WSL)
|
||||
|
||||
## Live Coding with Strudel: A Glimpse
|
||||
|
||||
Once set up, you can start creating algorithmic music immediately:
|
||||
|
||||
```javascript
|
||||
// Basic beat
|
||||
$: sound("bd*4").gain(0.8)
|
||||
$: sound("~ sd ~ sd").gain(0.7)
|
||||
$: sound("hh*8").gain(0.3)
|
||||
|
||||
// Melodic elements
|
||||
$: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth").lpf(1200)
|
||||
$: n("~ 0 ~ 2 ~ 4 ~ 6").scale("C4:minor").sound("piano").room(0.6)
|
||||
|
||||
// Live effects
|
||||
_$: sound("bd*4").lpf(sine.range(200, 2000).slow(8)) // muted filter sweep
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Setting up a proper development environment for Strudel isn't just about getting code to run—it's about creating a sustainable, collaborative workflow that scales. Our Nix-based approach, combined with careful submodule management and comprehensive guidelines, provides a solid foundation for both individual exploration and team development.
|
||||
|
||||
Whether you're a seasoned live coder or just starting your algorithmic music journey, this environment ensures you can focus on what matters most: creating amazing sounds.
|
||||
|
||||
The Strudel community welcomes contributors at all levels. Check out the [official Strudel website](https://strudel.cc/) and [workshop](https://strudel.cc/workshop/) to learn more, and join us in pushing the boundaries of live coding music!
|
||||
|
||||
---
|
||||
|
||||
*This post is part of our series on reproducible development environments. Stay tuned for more insights into modern software development practices.*
|
||||
Reference in New Issue
Block a user