devalang 0.0.1-alpha.8

Write music like code. Devalang is a domain-specific language (DSL) for sound designers and music hackers. Compose, automate, and control sound β€” in plain text.
Documentation

Rust TypeScript Node.js

Project Status Version License: MIT Platform

npm crates

VSCode Extension

🎼 Devalang, by Devaloop Labs

🎢 Compose music with code β€” structured, expressive, and fast.

Devalang is a tiny domain-specific language (DSL) for music makers, sound designers, and audio hackers. Compose loops, control samples, render and play audio β€” all in clean, readable text.

🦊 Whether you're building a track, shaping textures, or performing live, Devalang helps you think in rhythms. It’s designed to be simple, expressive, and fast β€” because your ideas shouldn’t wait.

From studio sketches to live sets, Devalang gives you rhythmic control β€” with the elegance of code.

🚧 v0.0.1-alpha.8 Notice 🚧

NEW: Devalang VSCode extension is now available ! Get it here.

NEW: Devalang supports conditional statements (if, else, else if) for more dynamic compositions !

Currently, Devalang CLI is only available for Windows.
Linux and macOS binaries will be added in future releases via cross-platform builds.


πŸ“š Quick Access

❓ Why Devalang?

  • 🎹 Prototype audio ideas without opening a DAW
  • πŸ’» Integrate sound into code-based workflows
  • πŸŽ›οΈ Control audio parameters through readable syntax
  • πŸ§ͺ Build musical logic with variables and conditions

Producer, coder, or both β€” Devalang gives you musical structure, instantly.

πŸš€ Features

  • 🎡 Audio Engine: Integrated audio playback and rendering
  • 🧩 Module system for importing and exporting variables between files
  • πŸ“œ Structured AST generation for debugging and future compilation
  • πŸ”’ Basic data types: strings, numbers, booleans, maps, arrays
  • πŸ‘οΈ Watch mode for build, check and play commands
  • πŸ“‚ Project templates for quick setup
  • πŸŽ›οΈ Custom samples: easily load and trigger your own audio files
  • πŸ”„ Looping and grouping: create complex patterns with ease

πŸ“† Installation

For users

Install the package globally (NPM)

npm install -g @devaloop/devalang@latest

Usage without install (NPX)

npx @devaloop/devalang@latest

For contributors

git clone https://github.com/devaloop-labs/devalang.git


cd devalang


npm install

Development usage (you can customize arguments in package.json)

# For syntax checking test

npm run rust:dev:check


# For building test

npm run rust:dev:build

❔ Usage

NOTE: Commands are available via devalang or npx @devaloop/devalang.

NOTE: Arguments can be passed to commands using --<argument> syntax. You can also use a configuration file to set default values for various settings, making it easier to manage your Devalang project.

NOTE: Some commands require a mandatory --entry argument to specify the input folder, and a --output argument to specify the output folder. If not specified, they default to ./src and ./output respectively.

For more examples, see docs/COMMANDS.md

Initialize a new project

In the current directory

devalang init

Or use optional arguments to specify a directory name and a template

devalang init --name <project-name> --template <template-name>

Checking syntax only

devalang check --watch

Building output files

devalang build --watch

Playing audio files (once by file change)

devalang play --watch

Playing audio files (continuous playback, even without file changes)

devalang play --repeat

βš™οΈ Configuration

You can use a configuration file to set default values for various settings, making it easier to manage your Devalang project.

To do this, create a .devalang file in the root of your project directory.

See docs/CONFIG.md for more information.

πŸ“„ Syntax example

For more examples, see docs/SYNTAX.md

# index.deva

@import { globalBpm, globalBank, kickDuration } from "global.deva"

@load "./examples/samples/kick-808.wav" as customKick

bpm globalBpm
# Will declare the tempo at the globalBpm variable beats per minute

bank globalBank
# Will declare a custom instrument bank using the globalBank variable

# Loops

loop 5:
    .customKick kickDuration {reverb=50, drive=25}
    # Will play 5 times a custom sample for 500ms with reverb and overdrive effects

# Groups

group myGroup:
    .customKick kickDuration {reverb=50, drive=25}
    # Will play the same sample in a group, allowing for more complex patterns

# Will be executed line by line (sequentially)
call myGroup

# Will be executed in parallel (concurrently)
# ⚠️ Note: `spawn` runs the entire group in parallel, but the group’s internal logic remains sequential unless it uses `spawn` internally.
# spawn myGroup

🧠 Note: call and spawn only work with group blocks. They do not apply to individual samples or other statements.

# variables.deva

let globalBpm = 120
let globalBank = 808
let kickDuration = 500

@export { globalBpm, globalBank, kickDuration }

🧯 Known issues

  • No smart modules yet, all groups, variables, and samples must be explicitly imported where used
  • No support yet for pattern, function, ... statements
  • No support yet for cross-platform builds (Linux, macOS)

πŸ§ͺ Roadmap Highlights

For more info, see docs/ROADMAP.md

  • ⏳ Other statements (e.g function, pattern, ...)
  • ⏳ Cross-platform support (Linux, macOS)
  • ⏳ More built-in instruments (e.g. snare, hi-hat, etc.)

πŸ›‘οΈ License

MIT β€” see LICENSE

🀝 Contributing

Contributions, bug reports and suggestions are welcome !
Feel free to open an issue or submit a pull request.

πŸ“’ Contact

πŸ“§ contact@devaloop.com