juce-dev Plugin for Claude Code

Make audio plugins
for macOS & iOS.

juce-dev sets up everything you need to build an audio plugin — synth, effect, instrument, whatever you want. Name it, answer a few questions, and you've got a project that builds in Xcode. Add GPU-rendered UI with Visage, add an iOS target, and Claude knows how to help with each — a bundled juce-visage skill activates automatically when you're working on Visage UI.

Using Codex? See the Codex FAQ and the Codex juce-visage skill.

/juce-dev:create "Shimmer Delay"
Creates a ready-to-build plugin project. What happens
Behind that command:
1. Checks your dev tools are installed (offers to set them up if not)
2. Loads your developer settings or walks you through first-time setup
3. Asks about optional features (GPU-rendered UI, crash reporting)
4. Creates the project with all your settings baked in
5. Sets up git, optionally creates a GitHub repo
6. Ready to build and open in Xcode

How It Works

Answer a few questions,
start building.

Starting a new audio plugin usually means wiring up build systems, configuring code signing, setting up project identifiers, and writing boilerplate. It's tedious before you write a single line of audio code.

juce-dev handles all of that. Give it a name, confirm your developer settings, pick your options, and you get a project that compiles immediately. If it's your first time, it checks your tools and walks you through setup.

Go cross-platform: Port between macOS, Windows, and Linux in any direction. The port command scans your project for platform-specific code, shows you exactly what needs to change, and applies the fixes — including building and testing on a remote VM over SSH. Started on Windows and want to ship on macOS? It handles that too, adding AU/AUv3 support, code signing, universal binaries, and everything else macOS needs. Porting to Linux? It adds Clang/Ninja build support, apt dependency installation, and a custom auto-updater — all tested on Ubuntu 24.04.

Context-aware assistance: If you add Visage GPU UI to your project, a bundled juce-visage skill automatically provides Claude with deep knowledge of Metal view embedding, event bridging, keyboard handling in DAW hosts, and more. No Visage? The skill stays out of the way — it only activates when relevant.

Want to go further? Use Chainer to describe what your plugin should do and let Claude build it for you.

What You Get

A complete project — not a tutorial, not a starter guide. A project that builds.

  • Audio Unit, VST3, and Standalone app — all from one project
  • Works in Logic Pro, Ableton Live, and other macOS DAWs
  • Code signing and notarization config ready for distribution
  • Optional GPU-rendered UI with Visage (Metal-accelerated)
  • Optional iOS/iPadOS app target with auto-detected UI mode
  • Bundled juce-visage skill — activates only when working on Visage UI
  • Optional crash reporting for your users
  • In-app auto-updates via Sparkle/WinSparkle
  • CI/CD with proper installers — macOS .pkg and Windows Setup.exe, not just raw binaries
  • One-command certificate export from Keychain to GitHub Secrets
  • Port between macOS, Windows, and Linux — audit platform-specific code, fix, and test on a remote VM
  • Git repo initialized, GitHub repo created if you want
  • Checks your dev environment and installs missing tools
  • Developer settings saved — next project is even faster

Installation

Two steps.

Requires Claude Code on macOS, Windows, or Linux. The plugin checks for other dependencies (Xcode/MSVC/Clang, CMake, Ninja) and helps you install anything missing.

# 1. Add the marketplace (in Claude Code) /plugin marketplace add danielraffel/generous-corp-marketplace # 2. Install the plugin /plugin install juce-dev@generous-corp-marketplace # 3. Restart Claude Code # Quit and reopen Claude Code to load the plugin
View on GitHub →
After installation, verify with /juce-dev:create

Commands

Full lifecycle.

Create, configure, build, port, ship. Start a project on one platform, easily port it to another. Each command does one thing well — combine with Chainer for automated workflows.

Create a plugin
/juce-dev:create "Shimmer Delay"
Name it, answer a few questions, open in Xcode. What happens
Walks through developer settings, creates a complete JUCE project with AU + VST3 + Standalone targets, initializes git, optionally creates a GitHub repo. Ready to build immediately.
Create with GPU UI
/juce-dev:create "My Synth" --visage
Same project, plus Metal-rendered UI at 60fps. What happens
Everything from create, plus: clones the Visage framework, applies patches, adds a Metal-rendered editor template with event bridging. The bundled juce-visage skill activates automatically to help with Visage development.
Build & launch
/juce-dev:build standalone
Build any target and run it. What happens
Auto-detects if CMake regeneration is needed, builds the standalone app, and launches it. Replace standalone with au, vst3, or all for other formats.
Ship to users
/juce-dev:build publish
Build, sign, notarize, package, release. What happens
Full pipeline: builds all formats, code-signs with your Apple developer identity, notarizes with Apple, creates a .pkg installer, publishes a public GitHub Release, and updates your website download links — only activating buttons for platforms with actual assets. Use /juce-dev:build draft for a draft release instead. On Windows, creates a Setup.exe via Inno Setup.
macOS + iOS with GPU UI
/juce-dev:create "My Synth" --visage # then, from the project directory: /juce-dev:setup-ios
Create a plugin with Metal UI, then add an iOS target. What happens
First command creates a macOS plugin with Visage GPU-rendered UI (Metal, 60fps). Then setup-ios adds an iOS/iPadOS app target — it auto-detects Visage and creates a matching Metal UI with native touch handling. Both platforms share the same codebase. There's no --ios flag on create because the iOS target needs the project to exist first.
Project status
/juce-dev:status
See your project config, features, and VMs at a glance. What happens
Shows your project name, bundle ID, JUCE version, enabled features (Visage, DiagnosticKit), configured VMs, build targets, and git status. Use --verbose for full .env details.
Port macOS to Windows
/juce-dev:port windows --vm win
Audit macOS-specific code, fix, build, and test on a Windows VM. What happens
Scans your project for macOS-specific code: Objective-C++ files, Cocoa imports, Apple frameworks, macOS paths. Generates a severity-ranked report, then applies CMake conditionals, #if JUCE_MAC guards, and MSVC flags. Can SSH to your Windows VM to build and test. Visage is fully cross-platform and is never flagged.
Port Windows to macOS
/juce-dev:port macos --vm mac
Audit Windows-specific code, fix, build, and test on a macOS VM. What happens
Scans your project for Windows-specific code: Win32 API calls, COM/DirectX code, MSVC pragmas, Windows paths. Generates a severity-ranked report, then adds AU/AUv3 formats, universal binary config, code signing, and macOS build scripts. Can SSH to your macOS VM to build and test. Visage is fully cross-platform and is never flagged.
Port to Linux
/juce-dev:port linux --vm ubuntu
Audit platform-specific code, fix, build, and test on a Linux VM. What happens
Scans your project for macOS/Windows-specific code: Objective-C++ files, Win32 APIs, platform-specific paths. Generates a severity-ranked report, then adds Linux CMake conditionals, Clang/Ninja build support, apt dependency installation, and a custom auto-updater (pure JUCE, no external library). Can SSH to your Ubuntu VM to build and test. Tested on Ubuntu 24.04 LTS. Visage is fully cross-platform (Vulkan on Linux) and is never flagged.
Port to All Platforms
/juce-dev:port all
Port your project to every supported platform in one pass. What happens
Detects which platforms your project already supports (macOS, Windows, Linux) and runs the port audit + fix for each missing platform in sequence. Adds CMake conditionals, platform-specific build scripts, auto-updater support, and dependency setup for every target. Optionally builds and tests on VMs if configured. One command to go from single-platform to fully cross-platform.
Auto-updates
/juce-dev:setup-updates
Add in-app auto-updates to your standalone app. What happens
Adds Sparkle (macOS) or WinSparkle (Windows) for automatic update checking. The updater UI lives in the standalone app — "Check for Updates" in the macOS app menu, or the Settings panel on Windows. Updates are full product installers (PKG on macOS, Inno Setup on Windows) that replace all plugin formats at once. EdDSA-signed for integrity. Use --doctor to validate your update chain.
CI/CD
/juce-dev:ci publish
Trigger cloud builds, sign, and publish from GitHub Actions. What happens
Four modes: verify (build + test), sign (build + sign), publish (build + sign + public GitHub Release + website update), draft (same as publish but creates a draft release). CI creates proper installers — macOS .pkg (pkgbuild + productbuild + productsign + notarytool + stapler) and Windows Setup.exe via Inno Setup. Auto-detects which platforms your project supports. Per-platform signing controls — skip macOS or Windows signing with --no-sign-macos / --no-sign-windows. Gracefully skips signing if certs aren't configured. After publish, download buttons on your GitHub Pages site are activated only for platforms with actual release assets, and the repo homepage URL is set automatically. If your .env is gitignored, CI falls back to .env.ci — a committed file with only non-secret values (PROJECT_NAME, versions, CI_PLATFORMS). Use status and logs to monitor runs. Use secrets to export signing certs from Keychain to GitHub Secrets.
Website
/juce-dev:website
Create a GitHub Pages download page for your plugin. What happens
Creates a gh-pages branch with a clean, responsive landing page — your plugin name, description, and download buttons. Supports light and dark mode. The generated index.html includes <!-- DOWNLOAD-MACOS-START --> / <!-- DOWNLOAD-MACOS-END --> marker comments around each download button. When you publish, update_download_links.sh replaces the content between these markers with active download links — "Coming Soon" stubs become real buttons. For pages without markers (e.g., custom designs), the script falls back to regex-based URL replacement, updating versioned release URLs in-place. Only platforms with actual release assets get active buttons (macOS checks for .pkg, Windows for Setup.exe or .zip, Linux for .tar.gz). The repo homepage URL is set to the GitHub Pages URL automatically, with custom domain detection. For private repos, the GitHub source link is omitted. Customize by editing index.html on the gh-pages branch — both marker-based and markerless pages are supported.
Manage VMs
/juce-dev:vm add win win-ssh windows
Register cross-platform test VMs for build and test. What happens
Saves a VM configuration (name, SSH alias, platform) to your .env file so that /juce-dev:port and /juce-dev:build can SSH in to build and test on that platform. Use /juce-dev:vm list to see configured VMs. Supports Windows, Linux, and macOS VMs — Proxmox, UTM, Parallels, or any SSH-accessible machine.

Reference

All the options.

Every argument shown with an example. Most have smart defaults — you only need what's relevant to you.

# ── Create ────────────────────────────────────────── # New plugin project (walks through setup) /juce-dev:create "Shimmer Delay" # With GPU-rendered Visage UI (Metal, 60fps) /juce-dev:create "My Synth" --visage # Local only — skip GitHub repo creation /juce-dev:create "My Synth" --no-github # Both flags work together /juce-dev:create "My Synth" --visage --no-github # ── Configure (run from project root) ─────────────── # Add Visage GPU UI to an existing project /juce-dev:setup-visage # Add iOS/iPadOS app target (auto-detects Visage) # iOS is always added after create — not a create flag /juce-dev:setup-ios # ── Build ─────────────────────────────────────────── # Build and launch standalone app /juce-dev:build standalone # Build Audio Unit (installs to ~/Library/Audio/Plug-Ins/) /juce-dev:build au # Build VST3 /juce-dev:build vst3 # Build everything at once /juce-dev:build all # ── Test ──────────────────────────────────────────── # Build all formats + validate with PluginVal /juce-dev:build all test # Quick unsigned installer for local testing /juce-dev:build unsigned # ── Ship ──────────────────────────────────────────── # Code-sign and notarize with Apple /juce-dev:build all notarize # Full pipeline: build → sign → notarize → installer → GitHub Release /juce-dev:build publish # ── Port (cross-platform) ─────────────────────────── # Audit project for target platform compatibility /juce-dev:port windows --audit-only /juce-dev:port linux --audit-only /juce-dev:port macos --audit-only # Port and test on a VM /juce-dev:port windows --vm win /juce-dev:port linux --vm ubuntu /juce-dev:port macos --vm mac # Port to all other platforms /juce-dev:port all # Port and trigger GitHub Actions CI /juce-dev:port windows --test-ci # ── Auto-Updates ──────────────────────────────────── # Add auto-update support to your project /juce-dev:setup-updates # Validate the full update chain /juce-dev:setup-updates --doctor # ── CI/CD ─────────────────────────────────────────── # Show CI config and trigger a verify build /juce-dev:ci # Build specific platforms /juce-dev:ci macos /juce-dev:ci macos,windows # Sign-only (no release) /juce-dev:ci sign # Full publish: build, sign, package, public GitHub Release /juce-dev:ci publish # Draft release (same as publish, but not public) /juce-dev:ci draft # Publish but skip signing for a platform /juce-dev:ci publish --no-sign-windows # Check recent CI run results /juce-dev:ci status # View build logs /juce-dev:ci logs # Export signing certs from Keychain to GitHub Secrets /juce-dev:ci secrets # ── Website ───────────────────────────────────────── # Create a GitHub Pages download page /juce-dev:website # ── Status & VMs ──────────────────────────────────── # Show project config, features, and VMs /juce-dev:status # Add VMs for cross-platform builds /juce-dev:vm add win win-ssh windows /juce-dev:vm add mac mac-ssh macos # List configured VMs /juce-dev:vm list # ── Help ──────────────────────────────────────────── # Show full build reference (targets, actions, options) /juce-dev:build --help

What Gets Generated

From name
to namespace.

All the identifiers your plugin needs are derived automatically from the name you give it.

# You provide Plugin name: "My Cool Synth" Developer name: "Generous Corp" # Automatically generated Class name: MyCoolSynth Project folder: my-cool-synth Bundle ID: com.generouscorp.my-cool-synth Plugin code: MYCO Manufacturer code: GECO GitHub repo: My-Cool-Synth

FAQ

Common questions.

What is JUCE?

JUCE is the most widely used C++ framework for building audio plugins and music software. It's used by companies like Ableton, ROLI, and hundreds of independent plugin developers. If you've used a software synth or effect in a DAW, there's a good chance it was built with JUCE.

juce-dev uses the JUCE-Plugin-Starter template — a pre-configured project setup that includes build scripts, version management, code signing, and distribution tooling on top of JUCE. You don't need to download JUCE separately; it's fetched automatically when you build.

What do I need before using this?

Just Claude Code and a Mac. The plugin checks for everything else (Xcode command-line tools, Homebrew, CMake, GitHub CLI) and offers to install whatever's missing.

Optional: An Apple Developer account if you want to code-sign and distribute your plugin. You can skip this and add it later — you don't need it to build and test locally.

What kind of plugins can I make?

Anything that processes or generates audio on macOS: synthesizers, effects (delay, reverb, distortion), MIDI processors, samplers, drum machines, audio analyzers — whatever you can code in C++.

Each project builds three formats from one codebase: Audio Unit (for Logic Pro, GarageBand), VST3 (for Ableton, Reaper, etc.), and a Standalone app for testing without a DAW.

Can Claude also build the actual plugin for me?

Yes. juce-dev sets up your project. To go from project to working plugin, install Chainer and describe what you want to build. Chainer will find the right tools and start implementing your idea.

For example: create a project with /juce-dev:create "Shimmer Delay", then tell Chainer you want "a stereo delay with pitch-shifted feedback and a wet/dry mix control." It handles the rest.

What is Visage, and how does the bundled skill work?

Visage is a GPU-accelerated UI framework for audio plugins on macOS. Instead of the standard JUCE graphics, Visage renders your plugin's interface using Metal at 60fps — smooth knobs, sliders, and animations with no CPU overhead.

It's optional. If you enable it, juce-dev sets up the framework, applies compatibility patches, and gives you a Visage-powered editor template to start from.

Bundled skill behavior: This plugin includes a juce-visage skill that is available after the plugin is installed. It works independently from command execution, so you don't need to run a separate command just to "turn it on." When you're working on Visage UI code, Claude uses that skill automatically for guidance (Metal view embedding, event bridging, DAW keyboard handling, popups/modals, iOS touch handling, and the Visage API).

If your JUCE project does not include Visage, the skill stays out of the way and won't push Visage-specific patterns. Add Visage first (for example via /juce-dev:create ... --visage or /juce-dev:setup-visage) to make that guidance relevant.

What if I use Codex instead of Claude Code?

You can use Codex with the Codex juce-visage skill. It provides Visage-focused implementation guidance (Metal embedding, JUCE↔Visage event bridging, DAW keyboard behavior, popups/modals/dropdowns, iOS touch handling, and debugging patterns).

What it does not replace: the Codex skill is guidance-only. It does not provide the command workflow this plugin provides (no /juce-dev:create, no automated dependency checks/setup, no automatic Visage clone+patch flow, and no project bootstrapping/repo setup commands).

Recommended workflow: scaffold first using this plugin (in Claude Code) or the JUCE-Plugin-Starter, then use Codex + juce-visage for day-to-day Visage implementation and troubleshooting. If Visage is not added to the project, the skill stays out of the way.

Install the Codex skill:

mkdir -p ~/.codex/skills cd ~/.codex/skills git clone --no-checkout --depth 1 --filter=blob:none --sparse \ https://github.com/danielraffel/generous-corp-marketplace.git tmp-juce-visage cd tmp-juce-visage git sparse-checkout set skills/codex/juce-visage git checkout mv skills/codex/juce-visage ~/.codex/skills/ cd ~/.codex/skills rm -rf tmp-juce-visage

This uses a sparse checkout to pull just the skill folder without downloading the entire repository.

Are my credentials safe?

Yes. Developer credentials (Apple ID, certificates, API keys) are stored in .env files which are listed in .gitignore. They're never committed or pushed to GitHub.

The template's .env is read-only — juce-dev reads your settings from it but never modifies it. All settings go to the new project's .env only.

Can I skip Apple Developer settings?

Yes. Code signing settings (Apple ID, Team ID, certificates) are only needed when you're ready to distribute your plugin to other people. Skip them during setup and add them to your project's .env later.

You can build, test, and develop locally with no Apple Developer account at all.

Why is this useful if I've never made a plugin before?

Making an audio plugin from scratch means learning a build system, configuring Xcode, understanding plugin formats (AU vs VST3), setting up code signing, figuring out bundle identifiers, and writing a lot of boilerplate — all before you write a single line of audio code.

juce-dev skips all of that. You get a project that compiles and runs immediately. The build scripts handle everything from debug builds to signed, notarized releases you can distribute. You just focus on making your plugin do something interesting.

I already know JUCE. Why would I use this?

If you already have a JUCE workflow, this saves you the boilerplate of starting new projects. Beyond the template setup, you get:

Build script with multiple actions: build.sh au debug, build.sh all publish, build.sh unsigned (fast installer testing), build.sh vst3 test (PluginVal integration)
Code signing + notarization configured from .env — no manual Xcode setup
Automatic versioning that increments on every build with proper AU version integers
Visage integration with pre-applied patches for keyboard handling, popup positioning, FPS caps — plus a bundled juce-visage skill that helps Claude navigate the tricky parts (Metal view embedding, event bridging, DAW keyboard conflicts, iOS touch handling)
GitHub release publishing with auto-download landing pages
Shared JUCE cache at ~/.juce_cache/ so you don't re-download JUCE for each project

What build commands are available?

Use /juce-dev:build from Claude Code, or run build.sh directly. Both support the same targets and actions:

Local development:
/juce-dev:build standalone — Build and launch standalone app
/juce-dev:build au — Build Audio Unit
/juce-dev:build vst3 — Build VST3
/juce-dev:build au vst3 — Build multiple targets at once

Testing:
/juce-dev:build all test — Build and validate with PluginVal
/juce-dev:build unsigned — Create an unsigned installer for quick testing

Distribution:
/juce-dev:build all sign — Build and code-sign
/juce-dev:build all notarize — Build, sign, and notarize with Apple
/juce-dev:build publish — Full pipeline: build, sign, notarize, and publish to GitHub Releases
/juce-dev:build pkg — Signed installer without GitHub release
/juce-dev:build uninstall — Remove all installed plugin components

Smart builds: The /juce-dev:build command auto-detects whether CMake regeneration is needed. If nothing changed in CMakeLists.txt or .env, it skips regeneration for faster builds.

Use /juce-dev:build --help for the full reference, or ./scripts/generate_and_open_xcode.sh to open the project in Xcode.

Does this work on Windows or Linux?

Port in either direction between macOS and Windows. Started on macOS? Use /juce-dev:port windows to scan for macOS-specific code and apply Windows-compatible fixes. Started on Windows? Use /juce-dev:port macos to scan for Windows-specific code and add macOS support (AU/AUv3 formats, universal binaries, code signing, notarization). Both directions can build and test on a remote VM over SSH. Linux support is coming soon.

The JUCE-Plugin-Starter template already includes cross-platform CMake configuration, a macOS build script (build.sh), and a Windows build script (build.ps1). The port command handles your project-specific code — the things you add on top of the template.

The build command (/juce-dev:build) also works on Windows and Linux if you're running Claude Code there — it detects the platform and uses the appropriate build script. Visage is fully cross-platform: Metal on macOS, Direct3D11 on Windows, Vulkan on Linux.

How does the port command work?

The port command supports porting between macOS, Windows, and Linux in any direction. It auto-detects your source platform and scans for the right patterns. It runs through four stages:

1. Audit — detects your source platform and scans for platform-specific code. macOS → Windows: finds Objective-C++, Cocoa/AppKit imports, CoreAudio/CoreMIDI, macOS paths. Windows → macOS: finds Win32 API calls (HWND, CreateWindow), COM interfaces, DirectX headers, MSVC pragmas, Windows registry access, .dll/.exe references. Categorizes by severity. Use --audit-only for just the report.

2. Plan — shows you the full list of changes and asks whether to apply all at once, go through them one by one, or export a plan to a markdown file.

3. Execute — creates a port/<platform> branch and applies fixes. To Windows: CMake conditionals, #if JUCE_MAC guards, MSVC flags, Windows build scripts. To macOS: #if JUCE_WINDOWS guards, AU/AUv3 format support, universal binary config (arm64;x86_64), code signing/notarization setup, macOS build scripts, Xcode project generation. To Linux: Clang/Ninja build config, apt dependency setup, custom auto-updater (pure JUCE, no external library), if(UNIX AND NOT APPLE) CMake blocks.

4. Test — optionally SSHs to your target VM, pushes the branch, runs the build there, and reports back. For macOS targets, also validates AU plugins with auval. If the build fails, it analyzes errors, fixes locally, pushes again, and retries. You can also trigger GitHub Actions CI instead.

Your project needs to be cloned on the VM as well — the port command pushes your branch to GitHub and pulls it on the VM via SSH.

How do I set up a VM for cross-platform testing?

You need SSH access to the target machine (a VM, a remote server, or another computer on your network). Add an SSH config entry in ~/.ssh/config:

# ~/.ssh/config Host windows10 HostName 192.168.20.30 User joesmith IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes ConnectTimeout 5 Host macmini HostName 192.168.20.40 User joesmith IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes ConnectTimeout 5 Host ubuntu HostName 192.168.20.50 User joesmith IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes ConnectTimeout 5

Then register VMs with juce-dev:

/juce-dev:vm add windows10 windows10 windows
/juce-dev:vm add macmini macmini macos
/juce-dev:vm add ubuntu ubuntu linux

Now you can port and test in one step:

/juce-dev:port windows --vm windows10
/juce-dev:port macos --vm macmini
/juce-dev:port linux --vm ubuntu

The port command will SSH to your VM, pull the branch, build with the platform's toolchain, and report results. For macOS targets, it also validates AU plugins with auval. Your project repo needs to be cloned on the VM — the command pushes your branch to GitHub and pulls it remotely.

Use /juce-dev:vm list to see configured VMs, or /juce-dev:status for a full project overview.

How do auto-updates work?

Auto-updates use Sparkle on macOS, WinSparkle on Windows, and a custom appcast poller on Linux — the same Sparkle-compatible appcast XML feed works across all three platforms.

The updater UI lives in the standalone app only — you can't trigger an update from within a DAW plugin. On macOS, "Check for Updates..." appears in the app name menu. On Windows and Linux, it's in the Help menu. On Linux, the updater shows an alert with a download link — matching Linux conventions where users manage updates themselves.

When an update is available, the frameworks handle the download, progress UI, and installation. The update payload is a full product installer (PKG on macOS, Inno Setup on Windows) that replaces all plugin formats (AU, VST3, CLAP, Standalone) at once — no version skew between formats.

Installers are EdDSA-signed for integrity verification. Use /juce-dev:setup-updates to add auto-update support to your project, and --doctor to validate your update chain end-to-end.

How does publishing an update work?

If auto-updates are enabled, /juce-dev:build publish handles everything in a single command: build, code-sign, notarize, create the installer, EdDSA-sign it, upload to GitHub Releases, and generate the appcast XML that tells users a new version is available.

The appcast (appcast-macos.xml / appcast-windows.xml) is committed to your repo and served via raw.githubusercontent.com. It's always published last, after the installer is already uploaded — so users never see an update they can't download.

Manual "Check for Updates" picks up the new version immediately. Automatic background checks find it within 24 hours (configurable).

What if I don't want auto-updates?

Everything is opt-in. If ENABLE_AUTO_UPDATE isn't set to true in your .env, the publish pipeline works exactly as before — no EdDSA signing, no appcast generation, no Sparkle/WinSparkle linking, no "Check for Updates" menu item. Zero impact on your build.

You can add auto-updates later at any time with /juce-dev:setup-updates.

What if my .env is gitignored?

Create a .env.ci file with only non-secret values and commit it. The CI workflow automatically falls back to .env.ci when .env doesn't exist.

.env.ci should contain: PROJECT_NAME, PROJECT_BUNDLE_ID, DEVELOPER_NAME, version numbers, GITHUB_USER, GITHUB_REPO, CI_PLATFORMS, and cert names (not secrets). Sensitive values like APPLE_ID and APP_SPECIFIC_PASSWORD stay as GitHub Secrets only.

Can I publish releases to a separate repo?

Not recommended. The default single-repo pattern (source + releases + website in one repo) is simpler and works well for most plugins. It's what /juce-dev:build publish and /juce-dev:ci publish are built for.

If you have a specific reason to separate releases from source code (e.g., private source with a public download page), a split-repo pattern is possible but requires manual configuration: a separate release repo, a PAT for cross-repo access, and custom appcast setup. This is tracked as a future enhancement. Stick with the default unless you know you need it.

How does the download page know which platforms to show?

When you publish, the update_download_links.sh script checks the actual release assets on GitHub. If the release has a .pkg, the macOS button is activated. If it has a _Setup.exe (or .zip fallback), the Windows button is activated. If it has a .tar.gz, the Linux button is activated.

This means you can publish macOS-only first and add Windows later — each platform's button only appears when there's a real file to download. The script also updates versioned URLs in your README.md.

How do I report a bug or request a feature?

We use GitHub issue templates so you can report the right thing in the right place:

JUCE Dev (Claude Code plugin)
Report a bug — command/setup/scaffolding issues
Request a feature — plugin workflow improvements

juce-visage (Codex skill)
Report a bug — incorrect or missing Codex skill guidance
Request a feature — new Codex skill coverage or patterns

Should I use this or Pamplejuce?

If you're an experienced C++ developer comfortable with CMake, Pamplejuce is probably the better choice. It's maintained by Sudara, a serious audio developer, and has a large community. It stays closer to standard CMake conventions and has excellent documentation.

juce-dev is designed for people who are newer to audio plugin development or want a more hands-off workflow. It handles prerequisites, scaffolding, building, signing, and publishing through natural language commands — you don't need to learn the underlying toolchain. It also adds features like in-app auto-updates, AI release notes, download pages, and diagnostic tooling that go beyond what a template typically provides.

Many of the build system patterns in JUCE Plugin Starter (the template juce-dev builds on) were inspired by Pamplejuce's approach to CI/CD, testing, and packaging. We're grateful for the example it set for the JUCE community.