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.
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
- 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
- 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
- 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
- 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
- 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
- 50 ms ou rien - La rapidité est non négociable
- Raccourcis clavier partout - Découvrables, pas cachés
- Recherche floue avec mise en surbrillance - Montrer pourquoi les résultats correspondent
- Panneaux d'actions (⌘K) - Actions contextuelles
- Confirmations HUD - Retour rapide et non bloquant
Pour les applications macOS
- Vibrancy native - Utiliser NSVisualEffectView/.material
- SF Symbols - Cohérent avec le système
- Couleurs système - Respecter la préférence de couleur d'accentuation
- Coins continus - .cornerRadius(style: .continuous)
- 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