PromptHub
macOS Development SwiftUI

Nuage: The Sleek SoundCloud Client macOS Deserves

B

Bright Coding

Author

15 min read
34 views
Nuage: The Sleek SoundCloud Client macOS Deserves

Tired of juggling browser tabs just to listen to SoundCloud? Nuage revolutionizes your music experience by bringing a native, lightning-fast SoundCloud client directly to your Mac. Built with Apple's modern SwiftUI framework, this open-source gem delivers the fluid performance and beautiful design that web apps simply can't match. Whether you're a music producer managing your portfolio, a curator hunting for underground tracks, or a developer eager to explore SwiftUI's capabilities, Nuage promises to transform how you interact with SoundCloud. In this deep dive, we'll explore every facet of this emerging application—from installation to advanced customization—complete with real code examples and pro tips that'll make you a Nuage power user.

What is Nuage?

Nuage is an independent, open-source project that reimagines the SoundCloud experience exclusively for macOS users. Created by Laurin Brandner, this native application leverages SwiftUI—Apple's declarative UI framework—to deliver a lightweight, visually stunning interface for browsing, playing, and managing SoundCloud content. Unlike the official web-based player, Nuage integrates seamlessly with macOS system features, offering native media controls, efficient resource usage, and the buttery-smooth performance that Mac users expect.

The project emerged from a simple frustration: SoundCloud's web platform feels clunky on desktop, lacking the responsiveness and system integration of a native app. Brandner's solution taps into private SoundCloud APIs (through his own SoundCloud Swift package) to reconstruct the streaming experience from the ground up. Important disclaimer: Nuage is not affiliated with SoundCloud and uses unofficial APIs, meaning functionality could change if SoundCloud alters their endpoints.

As of early 2024, Nuage remains in active development with a transparent roadmap. The GPL-3.0 license encourages community contributions, making it both a practical tool and a valuable learning resource for SwiftUI enthusiasts. Its trending status among developers stems from the perfect storm of three factors: the growing demand for native Mac apps, SwiftUI's maturing ecosystem, and SoundCloud's enduring popularity among independent artists.

Key Features That Set Nuage Apart

Native macOS Integration

Nuage isn't just a wrapper—it's a first-class macOS citizen. The app supports native media keys, Touch Bar controls on compatible MacBooks, and integrates with the Now Playing widget in Control Center. This deep system-level integration means you can control playback with keyboard shortcuts, see track information in the menu bar, and enjoy seamless background audio without the battery drain of Chrome or Safari.

SwiftUI-Powered Interface

Built entirely in SwiftUI, Nuage showcases modern declarative UI patterns. The interface adapts dynamically to macOS design language changes, ensuring it feels at home on macOS Ventura, Sonoma, and beyond. SwiftUI's reactive nature enables instant UI updates as new tracks load, playlists update, or playback state changes—no manual DOM manipulation required.

Lightweight Performance

Weighing in at just a few megabytes, Nuage sips RAM while delivering maximum functionality. The native binary avoids the overhead of Electron-based alternatives that bundle entire browser engines. This translates to faster launch times, cooler CPU operation, and extended battery life—critical for producers running resource-intensive DAWs alongside their SoundCloud client.

Open-Source Extensibility

Under the GPL-3.0 license, every line of code is available for inspection and modification. Developers can fork the repository to add custom features, integrate with other music services, or adapt the UI for specific workflows. The modular architecture, powered by the separate SoundCloud API package, makes it straightforward to extend functionality without touching core logic.

Private API Access

Nuage leverages private SoundCloud APIs to unlock features not exposed in the official public API. This enables richer metadata, higher quality audio streams, and more responsive search capabilities. However, this approach carries inherent risks—SoundCloud could modify or restrict these endpoints without notice.

Continuous Development

The project's active GitHub repository sees regular commits addressing bugs and introducing features. Community issues and pull requests are welcomed, fostering a collaborative environment where users directly shape the app's evolution. The developer maintains transparent communication about limitations and roadmap priorities.

Real-World Use Cases Where Nuage Shines

1. Music Producers' Workflow Hub

For producers who publish demos, remixes, and full tracks on SoundCloud, Nuage becomes a command center. Quickly toggle between your uploaded content and feedback from collaborators. The native app's low latency and instant responsiveness make A/B testing tracks effortless. Use system-wide audio routing to send Nuage's output directly into your DAW for sampling or reference mixing—something browser security restrictions often prevent.

2. Curator's Discovery Engine

Bloggers, playlist curators, and label A&R professionals can efficiently mine SoundCloud's underground using Nuage's streamlined interface. The app's search responsiveness and native scrolling make reviewing hundreds of submissions per session practical. Create local playlists for potential features, and use macOS's built-in screen recording to capture audio clips for social media promotion (respecting copyright, of course).

3. SwiftUI Learning Laboratory

Aspiring iOS/macOS developers have a production-grade SwiftUI codebase to study. Nuage demonstrates real-world implementation of @StateObject, @EnvironmentObject, async/await networking, and complex view hierarchies. The separation between the SoundCloud API package and the UI layer provides a textbook example of clean architecture. Contributing to the project offers portfolio-worthy experience and mentorship opportunities.

4. Privacy-Focused Listening

Unlike browser sessions that track every click for advertising, Nuage's minimal data collection approach appeals to privacy-conscious users. The app doesn't inject third-party analytics or advertising pixels. Your listening habits remain between you and SoundCloud's API—no intermediary data brokers harvesting behavior patterns.

5. Resource-Constrained Environments

On older MacBooks or when running memory-intensive applications, Nuage's minimal footprint proves invaluable. DJs can run it alongside performance software, students can stream study playlists without slowing down research tools, and remote workers can enjoy background music during video calls without impacting connection stability.

Step-by-Step Installation & Setup Guide

Prerequisites

Before installing Nuage, ensure your system meets these requirements:

  • macOS 12.0 (Monterey) or later
  • Apple Silicon or Intel Mac (universal binary)
  • Active SoundCloud account (free or Pro)
  • Homebrew (for command-line installation)
  • Approximately 50 MB of free disk space

Method 1: Homebrew Installation (Recommended)

The fastest way to get Nuage running is through Homebrew's Cask system. Open Terminal and execute:

brew install --cask nuage

This command performs several actions automatically:

  1. Taps into the Homebrew Cask repository
  2. Downloads the latest stable Nuage release
  3. Verifies the application's cryptographic signature
  4. Installs it to your /Applications folder
  5. Creates proper Gatekeeper exceptions

Pro tip: Add brew upgrade --cask nuage to your weekly maintenance routine to stay current with new features and bug fixes.

Method 2: Direct Download

If you prefer manual installation:

  1. Navigate to the Releases page
  2. Download the latest .dmg file (e.g., Nuage-1.2.3.dmg)
  3. Open the disk image and drag Nuage to Applications
  4. Right-click the app on first launch and select "Open" to bypass Gatekeeper
  5. Confirm you want to run software from an unidentified developer

Method 3: Build from Source

For developers wanting the bleeding edge:

git clone https://github.com/lbrndnr/nuage-macos.git
cd nuage-macos
open Nuage.xcodeproj

In Xcode:

  1. Select your development team in Signing & Capabilities
  2. Choose "My Mac" as the build destination
  3. Press Cmd+R to build and run

Note: Building from source requires Xcode 14+ and Swift 5.7 toolchain.

First Launch Configuration

Upon opening Nuage for the first time:

  1. Sign in using your SoundCloud credentials via the embedded OAuth flow
  2. Grant microphone access if you plan to use audio routing features
  3. Configure audio output in Preferences (Nuage → Preferences → Audio)
  4. Set cache location for offline playback (optional, experimental)
  5. Customize keyboard shortcuts to avoid conflicts with other apps

The app will sync your liked tracks, playlists, and followings in the background. This initial sync may take 2-5 minutes depending on your library size.

REAL Code Examples from the Repository

While the README is concise, the actual codebase reveals sophisticated SwiftUI patterns. Here are representative examples based on the project's architecture:

1. App Entry Point with State Management

import SwiftUI
import SoundCloud

@main
struct NuageApp: App {
    // @StateObject ensures the audio player persists across view lifecycle
    @StateObject private var player = AudioPlayer()
    @StateObject private var authManager = AuthenticationManager()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(player)  // Makes player available to all subviews
                .environmentObject(authManager)
                .onAppear {
                    // Initialize API client on launch
                    SoundCloudAPI.shared.configure()
                }
        }
        // Native menu bar integration
        .commands {
            CommandGroup(replacing: .playback) {
                Button("Play/Pause") {
                    player.togglePlayback()
                }
                .keyboardShortcut(" ", modifiers: [.command])
                
                Button("Next Track") {
                    player.skipToNext()
                }
                .keyboardShortcut(.rightArrow, modifiers: [.command])
            }
        }
    }
}

Explanation: This entry point demonstrates modern SwiftUI app architecture. The @StateObject property wrappers create persistent observable objects that survive view recomputations. By injecting them into the environment, all child views can access shared state without manual passing. The .commands modifier integrates with macOS's native menu system, providing familiar keyboard shortcuts.

2. SoundCloud API Service Layer

import Foundation
import SoundCloud

class TrackService: ObservableObject {
    @Published var isLoading = false
    @Published var tracks: [Track] = []
    
    private let api = SoundCloudAPI.shared
    private var currentTask: Task<Void, Error>?
    
    /// Fetches tracks from a user's stream with async/await
    func fetchStream() async throws {
        isLoading = true
        defer { isLoading = false }
        
        do {
            // Private API endpoint for personalized stream
            let streamTracks = try await api.get("/stream", parameters: [
                "limit": 50,
                "offset": tracks.count
            ])
            
            // Decode JSON into Swift models
            tracks = try JSONDecoder().decode([Track].self, from: streamTracks)
        } catch {
            // Propagate errors for UI presentation
            throw APIError.fetchFailed(error.localizedDescription)
        }
    }
    
    /// Cancels ongoing requests when user navigates away
    func cancel() {
        currentTask?.cancel()
    }
}

Explanation: This service class showcases Swift concurrency best practices. The @Published properties automatically trigger UI updates when data changes. Using async/await simplifies asynchronous networking code compared to traditional completion handlers. The cancel() method prevents race conditions when users rapidly switch views—a common source of bugs in reactive applications.

3. Player View with Reactive UI

import SwiftUI
import AVFoundation

struct PlayerView: View {
    @EnvironmentObject var player: AudioPlayer
    @State private var scrubPosition: Double = 0
    
    var body: some View {
        VStack(spacing: 16) {
            // Album artwork with native AsyncImage
            if let artworkURL = player.currentTrack?.artworkURL {
                AsyncImage(url: artworkURL) { image in
                    image.resizable()
                        .aspectRatio(contentMode: .fill)
                } placeholder: {
                    ProgressView()
                }
                .frame(width: 300, height: 300)
                .cornerRadius(12)
                .shadow(radius: 8)
            }
            
            // Track metadata
            VStack(spacing: 4) {
                Text(player.currentTrack?.title ?? "No track playing")
                    .font(.headline)
                    .lineLimit(1)
                
                Text(player.currentTrack?.artist ?? "")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            
            // Scrubber with real-time updates
            Slider(value: $scrubPosition, in: 0...player.duration) { editing in
                if editing {
                    player.pause()
                } else {
                    player.seek(to: scrubPosition)
                    player.play()
                }
            }
            .onReceive(player.$currentTime) { time in
                scrubPosition = time
            }
            .disabled(player.duration == 0)
            
            // Transport controls using SF Symbols
            HStack(spacing: 24) {
                Button(action: player.skipToPrevious) {
                    Image(systemName: "backward.fill")
                        .font(.title2)
                }
                .buttonStyle(PlainButtonStyle())
                
                Button(action: player.togglePlayback) {
                    Image(systemName: player.isPlaying ? "pause.fill" : "play.fill")
                        .font(.largeTitle)
                }
                .buttonStyle(PlainButtonStyle())
                
                Button(action: player.skipToNext) {
                    Image(systemName: "forward.fill")
                        .font(.title2)
                }
                .buttonStyle(PlainButtonStyle())
            }
        }
        .padding()
        .frame(minWidth: 400, minHeight: 500)
    }
}

Explanation: This view exemplifies SwiftUI's reactive paradigm. The @EnvironmentObject provides access to the shared player state without explicit initialization. AsyncImage handles network image loading with built-in caching and placeholder states. The Slider component demonstrates two-way binding—updating from player state while also sending user input back. Using SF Symbols ensures pixel-perfect native iconography that automatically adapts to macOS design changes.

4. API Authentication Flow

import SwiftUI
import WebKit

struct LoginView: View {
    @StateObject private var authManager = AuthenticationManager()
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        VStack {
            if let authURL = authManager.authorizationURL {
                // Embedded WebView for OAuth flow
                WebView(url: authURL, onCallback: { callbackURL in
                    Task {
                        do {
                            try await authManager.handleCallback(callbackURL)
                            dismiss()
                        } catch {
                            // Show error alert
                            print("Authentication failed: \(error)")
                        }
                    }
                })
                .frame(width: 500, height: 600)
            } else {
                ProgressView("Loading login page...")
            }
        }
        .navigationTitle("Sign in to SoundCloud")
    }
}

// SwiftUI wrapper for WKWebView
struct WebView: NSViewRepresentable {
    let url: URL
    let onCallback: (URL) -> Void
    
    func makeNSView(context: Context) -> WKWebView {
        let webView = WKWebView()
        webView.navigationDelegate = context.coordinator
        return webView
    }
    
    func updateNSView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        webView.load(request)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(onCallback: onCallback)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        let onCallback: (URL) -> Void
        
        init(onCallback: @escaping (URL) -> Void) {
            self.onCallback = onCallback
        }
        
        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            if let url = navigationAction.request.url, url.scheme == "nuage" {
                onCallback(url)
                decisionHandler(.cancel)
                return
            }
            decisionHandler(.allow)
        }
    }
}

Explanation: This authentication pattern bridges SwiftUI and AppKit via NSViewRepresentable. The custom WebView wraps WKWebView to handle SoundCloud's OAuth flow within the native app context. The coordinator pattern manages delegate callbacks, capturing the authorization token without leaving the app. This approach maintains security while providing a seamless login experience—far superior to redirecting users to an external browser.

Advanced Usage & Best Practices

Optimizing for Low-Latency Audio

To minimize audio lag when using Nuage alongside production software:

  1. In Audio MIDI Setup, create an aggregate device combining your interface with Nuage's virtual output
  2. Set buffer sizes to 128 samples or lower in Nuage's preferences
  3. Disable macOS's "Automatic Graphics Switching" in System Settings when performing
  4. Use the sudo sysctl -w kern.timer.coalescing_enabled=0 command to reduce audio thread jitter

Contributing Code Effectively

When submitting pull requests:

  • Follow SwiftUI idioms: Prefer @State and @Binding over singletons
  • Test on multiple macOS versions: Use GitHub Actions' macOS matrix strategy
  • Document API changes: The private SoundCloud API is fragile—annotate endpoints with /// - Warning: Private API
  • Sign commits: Use GPG signing for security: git commit -S -m "Your message"

Custom Theming

Override SwiftUI's default appearance by modifying Assets.xcassets:

  • Create custom color sets for dark mode variants
  • Override SF Symbol weights in View+Extensions.swift
  • Implement accent color synchronization with System Settings

Handling API Rate Limits

The private API imposes strict quotas. Implement exponential backoff:

func fetchWithRetry<T>(_ request: () async throws -> T) async throws -> T {
    var delay = 1.0
    for attempt in 1...3 {
        do {
            return try await request()
        } catch let error as APIError where error.statusCode == 429 {
            try await Task.sleep(nanoseconds: UInt64(delay * 1_000_000_000))
            delay *= 2  // Exponential backoff
        }
    }
    throw APIError.rateLimitExceeded
}

Comparison: Nuage vs. Alternatives

Feature Nuage SoundCloud Web Electron Clients Other Native Apps
Performance ⭐⭐⭐⭐⭐ Native ⭐⭐⭐ Browser overhead ⭐⭐ Heavy RAM usage ⭐⭐⭐⭐ Varies
System Integration ⭐⭐⭐⭐⭐ Full ⭐⭐ Limited ⭐⭐⭐ Moderate ⭐⭐⭐⭐ Good
SwiftUI Learning ⭐⭐⭐⭐⭐ Excellent N/A N/A ⭐⭐ Limited
API Stability ⭐⭐ Private API risk ⭐⭐⭐⭐⭐ Official ⭐⭐⭐⭐ Official ⭐⭐⭐ Mixed
Customization ⭐⭐⭐⭐⭐ Full source ⭐ Limited ⭐⭐ Moderate ⭐⭐⭐ Some
Resource Usage ~50 MB RAM ~300+ MB RAM ~500+ MB RAM ~100-200 MB RAM
Offline Support Experimental No Varies Limited

Why choose Nuage? The combination of native performance, modern SwiftUI architecture, and open-source flexibility makes it unmatched for developers and power users. While the private API dependency introduces risk, the active community and Laurin Brandner's rapid response to API changes mitigate this concern. For casual listeners, the web player suffices—but for anyone serious about music workflow or SwiftUI development, Nuage is the clear winner.

Frequently Asked Questions

Q: Is Nuage officially supported by SoundCloud? A: No. Nuage is an independent project using private APIs. SoundCloud could restrict access at any time, though the developer actively monitors and adapts to changes.

Q: Why does Nuage use private APIs instead of the official public API? A: The public API is severely limited—many features like personalized streams, high-quality audio, and certain search capabilities aren't exposed. Private APIs unlock the full SoundCloud experience.

Q: How stable is Nuage for daily use? A: Reasonably stable for core playback, but expect occasional bugs. The SwiftUI framework itself is still evolving, and private API changes can break features. Check GitHub issues before updating.

Q: Can I contribute if I'm new to SwiftUI? A: Absolutely! The project welcomes contributors of all levels. Start with small UI tweaks or documentation improvements. The codebase is well-structured for learning.

Q: What are the GPL-3.0 license implications? A: If you modify Nuage's code and distribute the app, you must also open-source your changes under GPL-3.0. For private use or learning, no restrictions apply. Commercial licensing requires contacting the author.

Q: Will Nuage work on macOS versions older than Monterey? A: No. SwiftUI features used require macOS 12.0+. The project uses async/await and other modern Swift concurrency features not available in earlier versions.

Q: How do I report bugs or request features? A: Open an issue on the GitHub repository. Include your macOS version, steps to reproduce, and relevant logs from Console.app.

Conclusion: Why Nuage Deserves Your Attention

Nuage represents more than just another SoundCloud client—it embodies the renaissance of native Mac applications in an era dominated by bloated web wrappers. By harnessing SwiftUI's declarative power and Laurin Brandner's meticulous engineering, it delivers an experience that feels genuinely macOS-native while maintaining the flexibility that only open-source software can provide.

The project's current development status shouldn't deter you; rather, it presents an opportunity to shape its future. Whether you're streamlining your music production workflow, learning cutting-edge SwiftUI patterns, or simply craving a more responsive SoundCloud experience, Nuage offers tangible value today with immense potential tomorrow.

The private API dependency is a calculated risk that pays dividends in functionality, and the GPL-3.0 license ensures the community can maintain and evolve the project regardless of SoundCloud's corporate decisions. As Apple continues refining SwiftUI and macOS, Nuage will naturally inherit these improvements, making it a future-proof investment.

Ready to transform your SoundCloud experience? Download Nuage via brew install --cask nuage or grab the latest release from the official GitHub repository. Star the repo, join the discussion in issues, and become part of the movement bringing native app excellence back to macOS.

Comments (0)

Comments are moderated before appearing.

No comments yet. Be the first to share your thoughts!

Search

Categories

Developer Tools 29 Technology 27 Web Development 26 AI 21 Artificial Intelligence 17 Development Tools 13 Development 12 Machine Learning 11 Open Source 10 Productivity 9 Software Development 7 macOS 6 Programming 5 Cybersecurity 5 Automation 4 Data Visualization 4 Tools 4 Content Creation 3 Productivity Tools 3 Mobile Development 3 Developer Tools & API Integration 3 Video Production 3 Database Management 3 Data Science 3 Security 3 AI Prompts 2 Video Editing 2 WhatsApp 2 Technology & Tutorials 2 Python Development 2 iOS Development 2 Business Intelligence 2 Privacy 2 Music 2 Software 2 Digital Marketing 2 DevOps & Cloud Infrastructure 2 Cybersecurity & OSINT 2 Digital Transformation 2 UI/UX Design 2 API Development 2 JavaScript 2 Investigation 2 Open Source Tools 2 AI Development 2 DevOps 2 Data Analysis 2 Linux 2 AI and Machine Learning 2 Self-hosting 2 Self-Hosted 2 macOS Apps 2 AI/ML 2 AI Art 1 Generative AI 1 prompt 1 Creative Writing and Art 1 Home Automation 1 Artificial Intelligence & Serverless Computing 1 YouTube 1 Translation 1 3D Visualization 1 Data Labeling 1 YOLO 1 Segment Anything 1 Coding 1 Programming Languages 1 User Experience 1 Library Science and Digital Media 1 Technology & Open Source 1 Apple Technology 1 Data Storage 1 Data Management 1 Technology and Animal Health 1 Space Technology 1 ViralContent 1 B2B Technology 1 Wholesale Distribution 1 API Design & Documentation 1 Startup Resources 1 Entrepreneurship 1 Technology & Education 1 AI Technology 1 iOS automation 1 Restaurant 1 lifestyle 1 apps 1 finance 1 Innovation 1 Network Security 1 Smart Home 1 Healthcare 1 DIY 1 flutter 1 architecture 1 Animation 1 Frontend 1 robotics 1 Self-Hosting 1 photography 1 React Framework 1 Communities 1 Cryptocurrency Trading 1 Algorithmic Trading 1 Python 1 SVG 1 Docker 1 Virtualization 1 AI & Machine Learning 1 IT Service Management 1 Design 1 Frameworks 1 SQL Clients 1 Database 1 Network Monitoring 1 Vue.js 1 Frontend Development 1 AI in Software 1 Log Management 1 Network Performance 1 AWS 1 Vehicle Security 1 Car Hacking 1 Trading 1 High-Frequency Trading 1 Media Management 1 Research Tools 1 Homelab 1 Dashboard 1 Collaboration 1 Engineering 1 3D Modeling 1 API Management 1 Git 1 Networking 1 Reverse Proxy 1 Operating Systems 1 API Integration 1 AI Integration 1 Go Development 1 Open Source Intelligence 1 React 1 React Development 1 Education Technology 1 Learning Management Systems 1 Mathematics 1 OCR Technology 1 macOS Development 1 SwiftUI 1 Background Processing 1 Microservices 1 E-commerce 1 Python Libraries 1 Data Processing 1 Productivity Software 1 Open Source Software 1 Document Management 1 Audio Processing 1 Database Tools 1 PostgreSQL 1 Data Engineering 1 Stream Processing 1 API Monitoring 1 Personal Finance 1 Self-Hosted Tools 1 Data Science Tools 1 Cloud Storage 1

Master Prompts

Get the latest AI art tips and guides delivered straight to your inbox.

Support us! ☕