Write music with code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound โ in plain text.
npm install @devaloop/devalang
chmod +x on Linux/Mac).
bash
npm install -g @devaloop/devalang
`
$3
`bash
cargo install devalang
`
$3
`bash
code --install-extension devaloop.devalang-vscode
`
$3
`bash
Initialize a new project
devalang init my-project
Navigate to the project
cd my-project
Check syntax
devalang check --entry examples/index.deva
Build audio files
devalang build --path examples/index.deva --formats wav mid
Play audio (live mode)
devalang play --live --input examples/index.deva
`
๐ฆ (optional) Install addons
Devalang supports addons to extend functionalities. This allows you to easily add sound banks, effects, or other features.
> To create your own addon, please refer to the Devapack documentation.
`bash
List available addons
devalang addon list
Install an addon (format: .)
devalang addon install devaloop.808
`
This will install the devaloop.808 sound bank in your current working directory inside .deva folder.
You can then use it in your Devalang scripts !
๐ต Your First Devalang File
Create a file hello.deva or index.deva (if you do not specify --input argument, it defaults to index.deva).
#### Nomenclature for .deva files
- Devalang files use the .deva extension.
- Devalang engine is indentation-sensitive for blocks, similar to Python.
- Files are plain text and can be edited with any text editor (VSCode recommended).
- Ensure your text editor supports UTF-8 encoding.
- Devalang is case-sensitive, so be consistent with capitalization.
- Devalang reads files from top to bottom, so order matters.
- Devalang files typically starts with :
1. Module system (load, import, use)
2. Global settings (bpm, bank)
3. Definitions (const/let/var, synth, pattern, group)
4. Algorithmic logic (if, loop, for)
5. Musical logic / Execution (trigger calls, automations, call, spawn, sleep)
6. Optional exports (export)
- Devalang files can include comments using # or // for single-line comments.
- You can name your files anything, but index.deva is a common convention for the main entry file.
- You can organize your project with subfolders as needed. (use module system like import { var } from ' and export { var }).
Refer to the documentation for a complete syntax reference.
`deva
Import some variables from other modules
import { myTempo } from "./shared/variables.deva"
Load an external sample and a MIDI file
load "./samples/my-sample.wav" as mySample
load "./midi/my-midi-file.mid" as myMidiFile
Set the tempo with the imported variable
bpm myTempo
Load a bank of sounds (make sure you have the bank installed)
bank devaloop.808 as drums
Create a simple kick pattern (can also use "mySample")
pattern kickPattern with drums.kick = "x--- x--- x--- x---"
Define a constant for synth, with a global LFO effect
You can define variables scopes using const/let/var
const mySynth = synth saw
-> lfo({
rate: "1/8",
depth: 1.0,
waveform: "triangle",
target: "pitch",
semitones: 3.0
})
Define a melody using a group to organize notes
group myMelody:
mySynth -> note(C5)
-> duration(500) # Note playing for 500ms
mySynth -> note(E5)
-> duration(1/4) # Note playing for 1/4 beats
mySynth -> chord(Gmaj7)
-> duration(1/8) # Chord playing for 1/8 beats
-> velocity(100) # Velocity (0.0 to 1.0) or 0-127
-> lpf({
cutoff: 800.0, # Lowpass filter at 800 Hz
resonance: 0.5 # Filter resonance at 50%
})
-> reverb({ size: 0.3 }) # Small reverb effect
Play the kick pattern (in parallel) (non-blocking)
layer kickPattern
Play the melody (in sequential) (blocking)
sequence myMelody
Bind and play the loaded MIDI pattern with 'mySynth' synth
bind myMidiFile -> mySynth
Pause for 1/4 beats
sleep 1/4
Store the sample in a variable and apply effects to it
let myAwesomeSample = .mySample
-> reverse(true) # Reverse the sample audio
-> speed(2.0) # Multiply the playing speed by 2
-> dist({
amount: 1.0, # Apply a maximal distortion
mix: 0.5 # Apply a 50% mixing
})
-> reverb({
size: 1.0, # Apply a maximal reverb size
decay: 0.1, # Apply a short decay
mix: 0.5 # Apply a 50% mixing
})
-> reverb({ # Duplicate reverb for a stronger effect
size: 1.0,
decay: 0.1,
mix: 0.5
})
Playing the stored sample trigger in different ways
.myAwesomeSample # Play the full sample length
.myAwesomeSample auto # Use maximal sample length by default
.myAwesomeSample 1/8 # Play the sample for 1/8 beats
Play the sample in conditional loop
for i in 0..3:
if i == 2:
.myAwesomeSample 1/4 # Play for 1/4 beats on iteration 2
else:
.myAwesomeSample 1/8 # Play for 1/8 beats otherwise
Play the sample in a blocking loop (run 10 times before continuing)
loop 10:
.myAwesomeSample auto
Play the sample in an (infinite) passthrough loop (non-blocking)
This will continue playing in the background and let the script continue
You can also specify a duration using "loop pass():"
loop pass:
.myAwesomeSample auto
Export the melody
export { myMelody }
`
$3
You can create a devalang.json (recommended) or devalang.toml or even .devalang (legacy) file to customize check/build/play settings.
This typically evitate to re-type common arguments like --path, --formats, etc.
> Comments are not supported in config files, please use devalang init to generate a default config.
`jsonc
{
"project": {
"name": "My Awesome Project" // Change this to adjust project name
},
"paths": {
"entry": "audio/helloWorld.deva", // Change this to adjust entry file path
"output": "output" // Change this to adjust output directory
},
"audio": {
"format": ["wav", "mid"], // Change this to adjust output formats (options: wav, mid, mp3)
"bit_depth": 16, // Change this to 24 or 32 for higher quality
"channels": 2, // Change this to 1 for mono output
"sample_rate": 44100, // Change this to 48000 for higher quality
"resample_quality": "sinc24", // Change this to adjust resampling quality (options: sinc8, sinc16, sinc24, sinc32)
"bpm": 120 // Change this to adjust the project tempo (only if not set in code)
},
"live": {
"crossfade_ms": 50 // Change this to adjust crossfade duration when playing live
},
"rules": {
"explicit_durations": "warning",
"deprecated_syntax": "warning",
"var_keyword": "error", // Change this to "warning", "info" or "off" to relax the rule
"missing_duration": "info",
"implicit_type_conversion": "info",
"unused_variables": "warning"
}
}
`
$3
`bash
Build to WAV, MP3, and MIDI
devalang build --path hello.deva --formats wav,mp3,mid
`
$3
`bash
Play the audio file
devalang play --input hello.deva
Play live (repeats and watch until stopped)
devalang play --live --input hello.deva
Play live loop without crossfade
With 0ms, transitions between loops are no more distinguishable
devalang play --live --crossfade-ms 0 --input hello.deva
`
๐ Features
$3
- โ
Lexer & Parser โ Complete tokenization and AST generation
- โ
Patterns โ Rhythmic notation with swing, humanize, velocity
- โ
Synths โ Built-in synthesizers with ADSR envelopes
- โ
Filters โ Lowpass, highpass, bandpass audio filtering
- โ
Effects โ Reverb, delay, distortion, drive, chorus
- โ
Variables โ let, const, var with scoping
- โ
Groups & Spawn โ Organize and parallelize execution
- โ
Loops & Conditions โ for, if, else control flow
- โ
Triggers โ Conditional audio triggering
- โ
Events โ Event system with on and emit
$3
- โ
devalang init โ Scaffold new projects
- โ
devalang build โ Compile to WAV/MIDI/MP3
- โ
devalang check โ Validate syntax
- โ
devalang play โ Audio playback
- โ
devalang addon โ Manage addons (install, list, discover)
- โ
devalang login/logout โ Authentication
- โ
devalang telemetry โ Privacy controls
$3
- โ
render_audio() โ Browser audio rendering
- โ
render_midi_array() โ MIDI export
- โ
debug_render() โ Debug information
- โ
parse() โ Parse Devalang code
- โ
TypeScript types included
$3
- โ
WAV โ 16/24/32-bit audio export
- โ
MIDI โ Standard MIDI file export
- โ
MP3 โ Lossy audio export (via LAME)
$3
- โก Fast builds โ 7-10ms for typical projects
- โก Low latency โ Optimized audio engine
- โก Release builds โ 5-6x faster than debug
$3
- โ
Online Docs โ Complete language reference
- โ
VSCode Extension โ Syntax highlighting
๐ก Why Devalang?
- ๐น Prototype audio ideas without opening a DAW
- ๐ป Integrate sound into code-based workflows
- ๐๏ธ Control audio parameters with readable syntax
- ๐งช Build musical logic with variables and conditions
- ๐ Create patterns with expressive notation
- ๐จ Live code with fast iteration cycles
- ๐ฆ Version control your music with git
๐ง Development
$3
`bash
Clone the repository
git clone https://github.com/devaloop-labs/devalang.git
cd devalang
NPM (TypeScript) and Cargo (Rust) are required
npm install
Build CLI (Rust)
cargo build
Build WASM (Web & Node.js)
npm run rust:wasm:all
Build TypeScript
npm run ts:build
Run tests
cargo test --features cli
npm test
``