Raycast : L'Art de la Productivité UI

Comment Raycast a atteint des temps de réponse inférieurs à 50ms tout en conservant sa personnalité : design natif macOS, excellence du clavier, écosystème d'extensions et patterns HUD. Avec des modèles d'implémentation Swift.

7 min de lecture 1265 mots
Raycast : L'Art de la Productivité UI screenshot

Raycast : L'art de l'interface de productivité

« Nous croyons que les meilleurs outils savent se faire oublier. » — Équipe Raycast

Raycast est un lanceur macOS qui a remplacé Spotlight pour les utilisateurs avancés. Il illustre comment concevoir pour une efficacité maximale tout en conservant chaleur et personnalité.


Pourquoi Raycast compte

Raycast prouve qu'un logiciel utilitaire n'a pas à être froid. Il combine : - Une vitesse fulgurante (lancement en <50ms) - Une interaction centrée sur le clavier - Une extensibilité via un store - Une personnalité à travers des détails soignés

Réalisations clés : - A redéfini ce qu'un lanceur peut être - A prouvé que les outils pour développeurs peuvent avoir de la personnalité - A créé un écosystème d'extensions florissant - A établi de nouveaux standards pour le design natif macOS


Points essentiels

  1. 50ms est le seuil de vitesse - Les utilisateurs perçoivent toute latence au-delà de 50ms ; considérez cela comme une contrainte technique absolue, pas comme une recommandation
  2. L'intégration native crée la confiance - La vibrancy, les SF Symbols, les couleurs d'accentuation système et les raccourcis standards font que Raycast semble faire partie intégrante de macOS
  3. Les raccourcis clavier doivent être découvrables - Affichez les raccourcis directement dans les résultats (⌘1, ⌘2), pas cachés dans des tooltips ou de la documentation
  4. De la personnalité sans coût en performance - Des confettis pour les accomplissements, des états vides ludiques et des textes bien trouvés créent du plaisir sans ajouter de latence
  5. Les écosystèmes d'extensions nécessitent un langage de design - Les extensions tierces semblent natives parce qu'elles utilisent les mêmes composants de formulaire, panneaux d'actions et schémas de navigation

Principes fondamentaux de design

1. Réponse instantanée

Raycast donne l'impression d'être une extension de vos pensées. Aucune latence. Aucune attente.

Comment ils y parviennent : - Implémentation native en Swift (pas Electron) - Index d'extensions préchargé - Mise en cache agressive - Pipeline de rendu optimisé

La règle des 50ms : Si quelque chose prend plus de 50ms, les utilisateurs le remarquent. Raycast traite cela comme une contrainte absolue.

Implications pour le design : - Afficher l'interface immédiatement, charger les données de manière asynchrone - États squelettes pour les opérations lourdes - Ne jamais bloquer le thread principal - Privilégier le traitement local aux appels réseau

// Raycast-style instant response pattern
struct SearchView: View {
    @State private var results: [Result] = []
    @State private var isLoading = false

    var body: some View {
        VStack {
            // Show immediately with cached data
            ForEach(cachedResults) { result in
                ResultRow(result)
            }

            if isLoading {
                // Unobtrusive loading indicator
                ProgressView()
                    .scaleEffect(0.5)
            }
        }
        .task(id: query) {
            isLoading = true
            results = await search(query)
            isLoading = false
        }
    }
}

2. Intégration profonde à macOS

Raycast donne le sentiment d'appartenir à macOS. Il respecte les conventions de la plateforme tout en repoussant les limites.

Comportements natifs : - Vibrancy et flou (NSVisualEffectView) - Couleurs d'accentuation système - SF Symbols omniprésents - Raccourcis clavier natifs - Respect du mode sombre/clair du système

Implémentation :

// macOS vibrancy
struct RaycastWindow: View {
    var body: some View {
        VStack {
            // Content
        }
        .background(.ultraThinMaterial)  // Native blur
        .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
    }
}

// System accent color
Text("Selected")
    .foregroundStyle(.tint)  // Follows system preference

// SF Symbols with semantic colors
Image(systemName: "checkmark.circle.fill")
    .foregroundStyle(.green)

Design de la fenêtre :

┌────────────────────────────────────────────────────────────┐
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░                                                      ░░ │
│ ░░  > Search Raycast...                                 ░░ │
│ ░░                                                      ░░ │
│ ░░  ┌────────────────────────────────────────────────┐  ░░ │
│ ░░  │ [A]  Applications                      Cmd+1   │  ░░ │
│ ░░  │ [F]  File Search                       Cmd+2   │  ░░ │
│ ░░  │ [C]  Clipboard History                 Cmd+3   │  ░░ │
│ ░░  │ [S]  System Commands                   Cmd+4   │  ░░ │
│ ░░  └────────────────────────────────────────────────┘  ░░ │
│ ░░                                                      ░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
└────────────────────────────────────────────────────────────┘
                    ↑ La vibrancy laisse voir le bureau à travers la fenêtre

3. Excellence clavier avec retour visuel

Chaque action possède un raccourci clavier. Chaque raccourci offre une confirmation visuelle.

Schémas d'affichage des raccourcis :

RESULTS LIST:
┌────────────────────────────────────────────────────────────┐
│ Recent Applications                                        │
│                                                            │
│  (*)  Visual Studio Code                         Cmd+1     │
│       ~/Projects/my-app                                    │
│                                                            │
│  ( )  Figma                                      Cmd+2     │
│       ~/Design/project.fig                                 │
│                                                            │
│  ( )  Terminal                                   Cmd+3     │
│                                                            │
│ ───────────────────────────────────────────────────────────│
│  Actions                            Cmd+K  or  ->  to see  │
└────────────────────────────────────────────────────────────┘

Panneau d'actions :

┌────────────────────────────────────────────────────────────┐
│ Actions for "Visual Studio Code"                  esc <-   │
│                                                            │
│  Open                                             Enter    │
│  Open in New Window                           Cmd+Enter    │
│  ──────────────────────────────────────────────────────── │
│  Show in Finder                             Cmd+Shift+F    │
│  Copy Path                                  Cmd+Shift+C    │
│  ──────────────────────────────────────────────────────── │
│  Move to Trash                           Cmd+Backspace     │
└────────────────────────────────────────────────────────────┘

Principes de design : - Afficher les raccourcis en ligne (pas dans des tooltips) - Regrouper les raccourcis par touche de modification - Utiliser les raccourcis macOS standards quand c'est attendu - Schémas mnémotechniques (⌘⇧F = Finder)


4. La personnalité dans les détails

Raycast est efficace sans être austère. De petites touches de plaisir le rendent mémorable.

Exemples : - Des confettis pour les accomplissements - Des sons subtils pour les actions - Des états vides ludiques - Des easter eggs pour les utilisateurs avancés

Exemple d'état vide :

┌────────────────────────────────────────────────────────────┐
│                                                            │
│                        [?]                                 │
│                                                            │
│               No results for "asdfgh"                      │
│                                                            │
│          Try searching for something else,                 │
│          or check out the Extension Store                  │
│                                                            │
│              [Browse Extensions]                           │
│                                                            │
└────────────────────────────────────────────────────────────┘

Schéma de confettis (pour les accomplissements) :

// After completing onboarding, earning badge, etc.
ConfettiView()
    .transition(.opacity)
    .animation(.spring(), value: showConfetti)

Lignes directrices sur la personnalité : - Le plaisir ne doit pas ralentir - Les célébrations sont méritées (pas aléatoires) - De la personnalité dans les textes (« No results for… » plutôt que « Error: 0 results ») - Le son est optionnel et discret


5. Design de l'écosystème d'extensions

Le store d'extensions de Raycast est remarquablement bien conçu.

Carte d'extension :

┌────────────────────────────────────────────────────────────┐
│  ┌──────┐                                                  │
│  │ [+]  │  GitHub                                          │
│  │      │  Search repos, PRs, and issues                   │
│  └──────┘                                                  │
│           ★★★★★  1.2k ratings  •  By Raycast               │
│                                                            │
│           [Install]                                        │
└────────────────────────────────────────────────────────────┘

Vue détaillée de l'extension :

┌────────────────────────────────────────────────────────────┐
│                                                            │
│  ← GitHub                                     [Uninstall]  │
│                                                            │
│  ┌──────────────────────────────────────────────────────┐ │
│  │                                                       │ │
│  │           [Screenshot of extension in use]           │ │
│  │                                                       │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│  Commands                                                  │
│  ├─ Search Repositories                                    │
│  ├─ My Pull Requests                                       │
│  ├─ Search Issues                                          │
│  └─ Create Issue                                           │
│                                                            │
│  Changelog                                                 │
│  ├─ v2.1.0  Added organization filtering                   │
│  └─ v2.0.0  Complete rewrite with new API                  │
│                                                            │
└────────────────────────────────────────────────────────────┘

6. Design de formulaires pour les extensions

Les extensions utilisent un système de formulaires cohérent.

Modèles de formulaires :

┌────────────────────────────────────────────────────────────┐
│ Create GitHub Issue                                   esc  │
│                                                            │
│  Repository                                                │
│  ┌──────────────────────────────────────────────────────┐ │
│  │ raycast/extensions                               ▾   │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│  Title                                                     │
│  ┌──────────────────────────────────────────────────────┐ │
│  │ Bug: Search not working                              │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│  Description                                               │
│  ┌──────────────────────────────────────────────────────┐ │
│  │ When I search for...                                 │ │
│  │                                                       │ │
│  │                                                       │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│  Labels                                    (optional)      │
│  ┌──────────────────────────────────────────────────────┐ │
│  │ [bug] [needs-triage]                             +   │ │
│  └──────────────────────────────────────────────────────┘ │
│                                                            │
│           [Create Issue ⌘↵]    [Cancel esc]                │
│                                                            │
└────────────────────────────────────────────────────────────┘

Style des composants de formulaire :

// Raycast-style form in SwiftUI
Form {
    Section("Repository") {
        Picker("", selection: $repo) {
            ForEach(repos) { repo in
                Text(repo.name).tag(repo)
            }
        }
        .labelsHidden()
    }

    Section("Title") {
        TextField("Bug: ...", text: $title)
    }

    Section("Description") {
        TextEditor(text: $description)
            .frame(minHeight: 100)
    }
}
.formStyle(.grouped)

Modèles de design dont s'inspirer

Le modèle « recherche d'abord »

Tout commence par la recherche.

┌────────────────────────────────────────────────────────────┐
│  > |                                                       │
│    ^ Curseur positionné ici immédiatement au lancement     │
│                                                            │
│  Tapez pour rechercher des commandes, apps, fichiers, etc. │
└────────────────────────────────────────────────────────────┘

Implémentation : - Focus automatique sur la recherche au lancement - Correspondance floue avec mise en surbrillance - Classement intelligent (récent + fréquent + pertinent) - Les résultats apparaissent au fur et à mesure de la saisie

Navigation hiérarchique

Des fonctionnalités profondes sans complexité.

Niveau 1 : Recherche principale
    ↓ Entrée
Niveau 2 : Commandes d'extension
    ↓ Entrée
Niveau 3 : Résultats d'action
    ↓ ⌘K
Niveau 4 : Panneau d'actions

Toujours : esc revient d'un niveau

Confirmations HUD

Un retour rapide sans interruption.

Après l'action :
┌────────────────────────────┐
│  ✓ Copié dans le presse-papiers │
└────────────────────────────┘
    ↑ Apparaît brièvement, puis disparaît
      Ne nécessite aucune validation
// HUD pattern
struct HUDView: View {
    @State private var show = false

    var body: some View {
        if show {
            Text("✓ Copied")
                .padding(.horizontal, 16)
                .padding(.vertical, 8)
                .background(.regularMaterial)
                .cornerRadius(8)
                .transition(.opacity.combined(with: .scale))
                .onAppear {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
                        withAnimation { show = false }
                    }
                }
        }
    }
}

Ce qu'il faut emprunter à Raycast

Pour une interface de lanceur/recherche

  1. 50 ms ou rien - La rapidité est non négociable
  2. Raccourcis clavier partout - Découvrables, pas cachés
  3. Recherche floue avec mise en surbrillance - Montrer pourquoi les résultats correspondent
  4. Panneaux d'actions (⌘K) - Actions contextuelles
  5. Confirmations HUD - Retour rapide et non bloquant

Pour les applications macOS

  1. Vibrancy native - Utiliser NSVisualEffectView/.material
  2. SF Symbols - Cohérent avec le système
  3. Couleurs système - Respecter la préférence de couleur d'accentuation
  4. Coins continus - .cornerRadius(style: .continuous)
  5. Raccourcis standards - Ne pas réinventer ⌘C, ⌘V, etc.

Techniques spécifiques

Technique Comment l'appliquer
Lancement instantané Préchauffer la fenêtre, charger le contenu de manière différée
Recherche floue Utiliser Fuse.js ou une bibliothèque similaire
Indicateurs de raccourcis Afficher ⌘1, ⌘2, etc. directement dans les résultats
Panneau d'actions Actions secondaires via ⌘K ou →
Retour HUD Style toast, disparition automatique
API d'extension Contrats clairs, interface cohérente

Système de couleurs

Raycast utilise des couleurs sémantiques liées au système.

// Raycast-inspired semantic colors
extension Color {
    static let rayBackground = Color(nsColor: .windowBackgroundColor)
    static let raySecondary = Color.secondary
    static let rayTertiary = Color(nsColor: .tertiaryLabelColor)

    // Status colors
    static let raySuccess = Color.green
    static let rayWarning = Color.orange
    static let rayError = Color.red

    // Accent follows system
    static let rayAccent = Color.accentColor
}

// Dark mode example
struct ResultRow: View {
    var body: some View {
        HStack {
            Image(systemName: "app.fill")
                .foregroundStyle(.secondary)

            Text("Application Name")
                .foregroundStyle(.primary)

            Spacer()

            Text("⌘ 1")
                .font(.caption)
                .foregroundStyle(.tertiary)
                .padding(.horizontal, 6)
                .padding(.vertical, 2)
                .background(Color.secondary.opacity(0.2))
                .cornerRadius(4)
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 8)
    }
}

Points clés

“Chaque milliseconde compte. Les utilisateurs perçoivent la différence entre 50 ms et 100 ms.”

“Les raccourcis clavier doivent être découvrables, pas mémorisés à partir de la documentation.”

“La personnalité rend un logiciel mémorable. L'efficacité le rend indispensable.”

“Les extensions doivent sembler natives, pas greffées. Même langage visuel, mêmes interactions.”


Questions fréquentes

Comment Raycast atteint-il des temps de réponse inférieurs à 50 ms ?

Raycast utilise une implémentation native en Swift (pas Electron), précharge l'index des extensions au lancement, met agressivement en cache les résultats de recherche et optimise le pipeline de rendu. L'interface apparaît immédiatement tandis que les données se chargent de manière asynchrone. Le seuil de 50 ms est traité comme une contrainte stricte, pas comme un objectif.

Pourquoi Raycast a-t-il un aspect si natif sur macOS ?

Raycast utilise NSVisualEffectView pour la vibrance et le flou, SF Symbols pour toutes les icônes, les couleurs d'accentuation système qui respectent les préférences de l'utilisateur, ainsi que les raccourcis clavier standard de macOS. La fenêtre possède un rayon de coin continu et suit automatiquement le mode sombre/clair du système.

Quelle est l'approche de Raycast en matière de raccourcis clavier ?

Chaque action dispose d'un raccourci clavier affiché directement dans les résultats (⌘1, ⌘2, etc.), et non caché dans des infobulles. Les raccourcis utilisent des schémas mnémotechniques (⌘⇧F pour Finder, ⌘⇧C pour Copy Path). Le panneau d'actions (⌘K) propose des actions secondaires avec leurs propres raccourcis.

Comment Raycast ajoute-t-il de la personnalité sans ralentir l'expérience ?

Les célébrations sont méritées et brèves — des confettis apparaissent après des accomplissements, pas de manière aléatoire. Les états vides utilisent un ton ludique (“Aucun résultat pour…” au lieu de “Erreur : 0 résultats”). Les sons sont optionnels et discrets. Le plaisir ne bloque jamais l'utilisateur et n'ajoute aucune latence.

Comment le système d'extensions de Raycast maintient-il la cohérence ?

Toutes les extensions utilisent les mêmes composants d'interface (formulaires, listes, panneaux d'actions), suivent les mêmes schémas de navigation (Entrée pour approfondir, Échap pour revenir en arrière) et héritent du style système. L'API impose la cohérence de sorte que les extensions tierces soient indiscernables des fonctionnalités intégrées.


Ressources

  • Site web : raycast.com
  • Store : raycast.com/store - Étudier le design des extensions
  • Documentation : Directives de développement d'extensions
  • Blog : Articles d'ingénierie sur la performance
  • GitHub : github.com/raycast - Extensions open source