FlutterFlutter
KotlinKotlin
SwiftSwift

Comprehensive comparison for Mobile Development technology in applications

Trusted by 500+ Engineering Teams
Hero Background
Trusted by leading companies
Omio
Vodafone
Startx
Venly
Alchemist
Stuart
Quick Comparison

See how they stack up across critical metrics

Best For
Building Complexity
Community Size
-Specific Adoption
Pricing Model
Performance Score
Flutter
Cross-platform apps with native performance, beautiful UIs, and single codebase for iOS, Android, and web
Very Large & Active
Rapidly Increasing
Open Source
8
Kotlin
Native Android development with modern language features and Java interoperability
Very Large & Active
Extremely High
Open Source
9
Swift
Native iOS app development with optimal performance and seamless Apple ecosystem integration
Large & Growing
Extremely High
Open Source
9
Technology Overview

Deep dive into each technology

Flutter is Google's open-source UI framework for building natively compiled mobile applications from a single codebase, enabling companies to deploy to iOS and Android simultaneously. It matters for mobile development because it dramatically reduces development time and costs while maintaining native performance and pixel-perfect UI consistency. Major companies like Alibaba, BMW, eBay Motors, and Google Pay use Flutter for production apps. The framework's hot reload feature accelerates iteration cycles, while its widget-based architecture ensures brand consistency across platforms, making it ideal for customer-facing mobile applications requiring rapid deployment and seamless user experiences.

Pros & Cons

Strengths & Weaknesses

Pros

  • Single codebase for iOS and Android reduces development time by 30-40%, allowing mobile development companies to deliver projects faster and take on more clients simultaneously.
  • Hot reload feature enables developers to see changes instantly without recompiling, significantly accelerating iteration cycles and reducing debugging time for mobile development teams.
  • Flutter's widget-based architecture provides pixel-perfect UI consistency across platforms, reducing QA testing effort and client revisions for design discrepancies between iOS and Android.
  • Strong performance with native compilation to ARM code ensures smooth 60fps animations, meeting enterprise client expectations for professional-grade mobile applications without performance compromises.
  • Growing demand from clients specifically requesting Flutter creates new business opportunities, with companies able to position themselves as specialists in modern cross-platform development.
  • Lower maintenance overhead with unified codebase means reduced long-term support costs, enabling mobile development companies to offer competitive maintenance contracts while maintaining healthy profit margins.
  • Rich ecosystem of pre-built packages and widgets accelerates feature implementation, allowing development teams to reduce project timelines by 20-30% compared to native development approaches.

Cons

  • Larger app size compared to native applications (typically 4-6MB overhead) can be a dealbreaker for clients targeting emerging markets with limited storage and bandwidth constraints.
  • Limited access to newest platform-specific APIs requires waiting for Flutter plugin updates, potentially delaying projects when clients need cutting-edge iOS or Android features immediately after release.
  • Smaller talent pool compared to native developers increases recruitment costs and timeline risks, with companies facing 2-3x longer hiring cycles for experienced Flutter developers in competitive markets.
  • Complex native integrations require platform-specific code and expertise in iOS/Android, negating cost savings for projects heavily dependent on device-specific features or existing native codebases.
  • Enterprise client hesitation due to perceived Google dependency creates sales friction, requiring additional effort to convince stakeholders concerned about long-term framework viability and support commitments.
Use Cases

Real-World Applications

Cross-Platform Apps with Single Codebase

Flutter is ideal when you need to build apps for iOS, Android, web, and desktop from one codebase. This significantly reduces development time and maintenance costs while ensuring consistent UI/UX across all platforms.

MVP Development with Fast Time-to-Market

Choose Flutter for rapid prototyping and minimum viable products when speed is critical. Hot reload enables instant UI updates during development, and the rich widget library accelerates the creation of polished interfaces quickly.

Visually Rich Custom UI Applications

Flutter excels for apps requiring highly customized, animated, and visually complex interfaces. Its rendering engine provides pixel-perfect control and smooth 60fps animations, making it perfect for creative or brand-focused applications.

Startups with Limited Development Resources

Flutter is perfect for teams with budget constraints or limited mobile developers. A single Flutter developer can build and maintain apps for multiple platforms, reducing hiring needs and streamlining the development workflow.

Technical Analysis

Performance Benchmarks

Build Time
Runtime Performance
Bundle Size
Memory Usage
-Specific Metric
Flutter
Initial build: 45-90 seconds, Hot reload: <1 second, Hot restart: 2-5 seconds
60 FPS on most devices, Native-like performance with Skia rendering engine, ~5-10% slower than native for CPU-intensive tasks
Android: 4-8 MB (release APK), iOS: 10-15 MB (release IPA), Minimum ~4.5 MB overhead from Flutter engine
Base memory: 20-40 MB, Typical app runtime: 50-150 MB depending on complexity, ~15-25% higher than native equivalent
Frame Rendering Time
Kotlin
Clean build: 45-90 seconds for medium apps (10k-20k LOC). Incremental builds: 5-15 seconds with Gradle build cache enabled
Native performance with JIT/AOT compilation. App startup: 1.2-2.5 seconds cold start, 0.3-0.8 seconds warm start. Frame rendering: consistent 60fps for optimized code
Base APK: 3-8 MB (without ProGuard/R8). With R8 optimization: 2-5 MB. AAB format reduces download size by 15-20% on average
Baseline: 30-50 MB for simple apps, 80-150 MB for complex apps. Efficient garbage collection with ART runtime. Heap size scales with device RAM
Method count and DEX limit handling
Swift
Swift: 15-45 seconds for incremental builds, 2-5 minutes for clean builds (medium-sized app). Kotlin: 20-60 seconds incremental, 3-7 minutes clean builds. React Native: 30-90 seconds incremental, 5-10 minutes clean builds. Flutter: 10-30 seconds incremental (hot reload 1-3s), 2-4 minutes clean builds.
Swift (iOS native): 60 FPS UI rendering, ~0.5ms average frame time. Kotlin (Android native): 60 FPS, ~0.8ms frame time. React Native: 50-60 FPS with optimization, ~2-5ms JavaScript bridge overhead. Flutter: 60 FPS (120 FPS capable), ~1ms frame time, compiled to native ARM code.
Swift: 15-30 MB base IPA (iOS). Kotlin: 8-20 MB base APK (Android). React Native: 25-40 MB (includes JS bundle + native modules). Flutter: 15-25 MB (includes Flutter engine ~4MB, compiled Dart code).
Swift: 30-80 MB baseline for simple apps, efficient ARC memory management. Kotlin: 40-100 MB baseline (includes JVM/ART overhead). React Native: 80-150 MB baseline (JavaScript VM + native bridge). Flutter: 50-100 MB baseline (Dart VM + Skia rendering engine).
App Startup Time (Cold Start)

Benchmark Context

Flutter excels in cross-platform development with a single codebase achieving 60-80% code reuse and near-native performance through its compiled Dart code and Skia rendering engine. Swift delivers optimal performance for iOS applications with direct access to Apple frameworks and typically 10-15% better runtime efficiency than cross-platform alternatives. Kotlin offers the best Android-native experience with seamless Java interoperability and modern language features, outperforming Flutter by 5-10% in Android-specific benchmarks. For pure performance on respective platforms, Swift (iOS) and Kotlin (Android) lead, but Flutter provides the fastest time-to-market for teams targeting both platforms with acceptable performance trade-offs of 10-20% compared to native strategies.


FlutterFlutter

Measures UI smoothness and responsiveness. Flutter typically achieves 16.67ms per frame (60 FPS) with jank <1% on modern devices, comparable to native performance for most UI operations

KotlinKotlin

Kotlin compiles to efficient bytecode with inline functions reducing method count. R8/ProGuard shrinking keeps apps under 64k method limit. Coroutines provide lightweight concurrency with minimal overhead compared to threads

SwiftSwift

Measures time from app launch to first interactive frame. Swift/Kotlin native: 400-800ms. React Native: 1.5-3 seconds (JS bundle load + initialization). Flutter: 800-1500ms (Dart VM initialization + first frame render). Critical for user experience and app store rankings.

Community & Long-term Support

Community Size
GitHub Stars
NPM Downloads
Stack Overflow Questions
Job Postings
Major Companies Using It
Active Maintainers
Release Frequency
Flutter
Over 5 million Flutter developers globally as of 2025
5.0
N/A - Flutter uses pub.dev package manager with over 50 billion total package downloads cumulative
Over 250,000 questions tagged with Flutter on Stack Overflow
Approximately 15,000-20,000 Flutter developer job openings globally across major job platforms
Google (Google Pay, Google Ads), Alibaba (Xianyu app), BMW (My BMW app), eBay (eBay Motors), Nubank (banking app), ByteDance (multiple apps), Grab (superapp), Philips Hue (smart home), Toyota (connected services), Betterment (investment app)
Maintained by Google with significant contributions from the open-source community. Core team of 50+ Google engineers plus hundreds of community contributors. Flutter is part of Google's open-source initiatives
Quarterly stable releases (4 major releases per year) with beta and dev channel updates weekly. Latest stable version follows a predictable schedule with LTS support for enterprise users
Kotlin
Approximately 6-7 million developers globally use Kotlin
5.0
Not applicable - Kotlin uses Maven Central and Gradle Plugin Portal. Maven Central shows 15-20 million monthly downloads of kotlin-stdlib
Over 160,000 questions tagged with 'kotlin' on Stack Overflow
Approximately 25,000-30,000 active Kotlin job postings globally across major job platforms
Google (Android development - Kotlin-first since 2019), Netflix (backend services), Uber (internal tools and services), Pinterest (Android app), Trello (Android app), Airbnb (Android app), Amazon (various services), Square/Block (Android and backend), Coursera (Android app), Evernote (Android app)
Primarily maintained by JetBrains with the Kotlin Foundation (established 2022) providing governance. Google is a major contributor, especially for Android-related features. Strong community contributions through GitHub
Major releases approximately annually (Kotlin 2.0 released May 2024), with minor releases every 2-3 months and patch releases as needed. Follows semantic versioning
Swift
Approximately 5-6 million Swift developers globally
5.0
Not applicable - Swift uses Swift Package Manager. Swift Package Index tracks 6000+ packages with millions of monthly downloads across the ecosystem
Over 290,000 questions tagged with Swift on Stack Overflow
Approximately 25,000-30,000 Swift developer job openings globally, concentrated in iOS/macOS development roles
Apple (iOS, macOS, watchOS ecosystem), Airbnb (mobile apps), LinkedIn (mobile), Uber (iOS app), Lyft (iOS app), Slack (iOS app), IBM (server-side Swift), Kickstarter (iOS app), Twitter/X (iOS app)
Maintained by Apple with open-source contributions. Swift Core Team oversees evolution. Active community through Swift.org, Swift Server Work Group, and multiple platform working groups
Annual major releases (Swift 6.0 in 2024, Swift 6.1 and point releases throughout 2024-2025). Regular minor updates and patches every 2-3 months

Community Insights

Flutter has experienced explosive growth since Google's 2018 stable release, now boasting over 150,000 stars on GitHub and adoption by companies like Alibaba and BMW. Swift maintains strong momentum within the Apple ecosystem with consistent updates and 65,000+ GitHub stars, backed by Apple's ongoing investment and a mature package ecosystem. Kotlin has become the preferred language for Android development since Google's 2019 endorsement, with 47,000+ GitHub stars and widespread enterprise adoption. All three technologies show healthy community engagement, though Flutter's cross-platform appeal has driven the fastest community growth rate at 40% year-over-year. The outlook remains strong for all three, with Flutter gaining in enterprise adoption, Swift evolving with Apple's platforms, and Kotlin expanding beyond Android into multiplatform development.

Pricing & Licensing

Cost Analysis

License Type
Core Technology Cost
Enterprise Features
Support Options
Estimated TCO for
Flutter
BSD 3-Clause License
Free (open source)
All features are free - no separate enterprise tier exists. Flutter provides the complete SDK, tooling, widgets, and capabilities at no cost
Free: Community forums, GitHub issues, Stack Overflow, Discord, official documentation. Paid: Third-party consulting services ($100-$250/hour). Enterprise: Google Cloud support packages ($150-$12,500+/month) or dedicated Flutter consulting firms ($5,000-$20,000+/month)
$200-$800/month for infrastructure (Firebase/AWS/GCP backend services, CI/CD pipelines like Codemagic or Bitrise at $50-$200/month, app store fees $99-$299/year amortized, monitoring tools $50-$150/month). Development costs are primary expense: 2-3 developers at $60,000-$150,000/year each for medium-scale application maintenance
Kotlin
Apache 2.0
Free (open source)
All features are free. Kotlin is fully open source with no paid tiers or enterprise-only features
Free community support via Kotlin Slack, forums, and Stack Overflow. Paid support available through JetBrains or third-party consulting firms ($150-$300/hour). Enterprise support through JetBrains partnerships ($10,000-$50,000+ annually depending on organization size)
$2,000-$8,000 monthly for medium-scale mobile application (100K orders/month). Includes cloud infrastructure ($1,500-$5,000 for backend APIs, databases, CDN), CI/CD pipeline ($200-$800 for GitHub Actions/Bitrise/CircleCI), monitoring and analytics ($300-$1,200 for Firebase, Crashlytics, APM tools), and developer tooling ($0-$1,000 for optional JetBrains IDE licenses). Does not include developer salaries
Swift
Apache 2.0
Free (open source)
All features are free; no separate enterprise licensing required
Free community support via Swift Forums and Stack Overflow; Paid consulting available through third-party vendors ($150-$300/hour); Apple Developer Program membership required for App Store distribution ($99/year)
$2,000-$5,000 (includes CI/CD infrastructure $500-$1,500, app store fees $0-$1,000 depending on revenue, backend services $1,000-$2,000, developer tools and testing devices $500-$1,500)

Cost Comparison Summary

Flutter significantly reduces development costs by enabling a single development team to maintain both platforms, typically cutting personnel costs by 40-50% compared to separate native teams. However, this assumes your team can effectively learn Dart and Flutter's paradigms. Swift and Kotlin require dedicated iOS and Android developers (average salaries $120-160K USD annually), but leverage larger talent pools and reduce onboarding time for experienced mobile developers. For organizations with existing native teams, switching to Flutter introduces migration costs and potential technical debt. Flutter becomes cost-effective for projects under 12-18 months or teams smaller than 8 developers. Native approaches scale better for large organizations with multiple mobile products, as specialized teams can work more efficiently and share platform-specific knowledge across projects, ultimately reducing long-term maintenance costs despite higher initial investment.

Industry-Specific Analysis

  • Metric 1: App Launch Time

    Time from tap to interactive UI (cold start and warm start)
    Target: <2 seconds for cold start, <1 second for warm start
  • Metric 2: Frame Rate Performance

    Percentage of frames rendered at 60fps or higher during animations and scrolling
    Target: >95% of frames at 60fps to ensure smooth user experience
  • Metric 3: Memory Footprint

    Average RAM consumption during typical user sessions
    Target: <150MB for lightweight apps, <300MB for feature-rich apps to prevent OS termination
  • Metric 4: Battery Consumption Rate

    Battery drain per hour of active use and background activity
    Target: <5% battery drain per hour of active use
  • Metric 5: Crash-Free Session Rate

    Percentage of user sessions without crashes or fatal errors
    Target: >99.5% crash-free sessions for production apps
  • Metric 6: API Response Time

    Average time for network requests to complete from mobile client
    Target: <500ms for critical API calls, <2 seconds for non-critical requests
  • Metric 7: App Size (APK/IPA)

    Total download size and installed size of the application
    Target: <50MB download size to minimize user drop-off during installation

Code Comparison

Sample Implementation

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';

// Model class for User
class User {
  final String id;
  final String email;
  final String name;
  final String? avatarUrl;

  User({
    required this.id,
    required this.email,
    required this.name,
    this.avatarUrl,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as String,
      email: json['email'] as String,
      name: json['name'] as String,
      avatarUrl: json['avatar_url'] as String?,
    );
  }
}

// Authentication Service with error handling
class AuthService {
  static const String _baseUrl = 'https://api.example.com';
  static const Duration _timeout = Duration(seconds: 30);

  Future<User> login(String email, String password) async {
    try {
      final response = await http
          .post(
            Uri.parse('$_baseUrl/auth/login'),
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode({'email': email, 'password': password}),
          )
          .timeout(_timeout);

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        return User.fromJson(data['user']);
      } else if (response.statusCode == 401) {
        throw Exception('Invalid credentials');
      } else {
        throw Exception('Login failed: ${response.statusCode}');
      }
    } on TimeoutException {
      throw Exception('Connection timeout. Please try again.');
    } catch (e) {
      throw Exception('Network error: $e');
    }
  }
}

// Login Screen Widget
class LoginScreen extends StatefulWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _authService = AuthService();
  bool _isLoading = false;
  String? _errorMessage;

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  Future<void> _handleLogin() async {
    if (!_formKey.currentState!.validate()) return;

    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final user = await _authService.login(
        _emailController.text.trim(),
        _passwordController.text,
      );

      if (mounted) {
        Navigator.pushReplacementNamed(
          context,
          '/home',
          arguments: user,
        );
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _errorMessage = e.toString().replaceAll('Exception: ', '');
        });
      }
    } finally {
      if (mounted) {
        setState(() {
          _isLoading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextFormField(
                controller: _emailController,
                decoration: const InputDecoration(
                  labelText: 'Email',
                  border: OutlineInputBorder(),
                ),
                keyboardType: TextInputType.emailAddress,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your email';
                  }
                  if (!value.contains('@')) {
                    return 'Please enter a valid email';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _passwordController,
                decoration: const InputDecoration(
                  labelText: 'Password',
                  border: OutlineInputBorder(),
                ),
                obscureText: true,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please enter your password';
                  }
                  if (value.length < 6) {
                    return 'Password must be at least 6 characters';
                  }
                  return null;
                },
              ),
              if (_errorMessage != null)
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text(
                    _errorMessage!,
                    style: const TextStyle(color: Colors.red),
                  ),
                ),
              const SizedBox(height: 24),
              SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: _isLoading ? null : _handleLogin,
                  child: _isLoading
                      ? const CircularProgressIndicator()
                      : const Text('Login'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Side-by-Side Comparison

TaskBuilding a real-time chat application with media sharing, push notifications, offline sync, and support for both iOS and Android platforms

Flutter

Building a user authentication screen with email/password input validation, login button, and navigation to home screen upon successful authentication

Kotlin

Building a user authentication screen with email/password input validation, login button, and navigation to home screen upon successful authentication

Swift

Building a user authentication screen with email/password input, form validation, and navigation to a home screen upon successful login

Analysis

For startups and small teams targeting both platforms with limited resources, Flutter is the optimal choice, enabling a single team to maintain both iOS and Android apps with 70-80% code sharing and faster iteration cycles. Companies with established native teams or platform-specific requirements should leverage Swift for iOS and Kotlin for Android to increase performance, access platform-specific APIs immediately, and deliver the most polished user experiences. For consumer-facing apps requiring bleeding-edge platform features (AR, advanced camera, widgets), native approaches with Swift/Kotlin are preferable. B2B applications with standard UI patterns and cross-platform requirements benefit most from Flutter's consistency and development velocity, reducing time-to-market by 30-40% compared to maintaining separate native codebases.

Making Your Decision

Choose Flutter If:

  • If you need true native performance for graphics-intensive apps, complex animations, or hardware-intensive features (AR/VR, advanced camera), choose Native (Swift/Kotlin) over cross-platform frameworks
  • If you want to maximize code reuse across iOS and Android with a single codebase and have limited mobile development resources, choose React Native or Flutter over native development
  • If your team already has strong web development skills (JavaScript/TypeScript) and wants faster time-to-market, choose React Native; if you prioritize consistent UI and smooth animations with better performance than React Native, choose Flutter
  • If you're building a simple content-driven app, MVP, or prototype with basic features and tight deadlines, choose Flutter or React Native; if you're building a complex enterprise app that will scale significantly, consider Native development for long-term maintainability
  • If you need access to the latest platform-specific APIs immediately after OS updates, extensive third-party native libraries, or plan to deeply integrate with platform ecosystems (Apple Watch, Widgets, HealthKit), choose Native development over cross-platform solutions

Choose Kotlin If:

  • If you need true native performance for graphics-intensive apps, complex animations, or hardware-intensive features (AR, camera processing, sensors), choose Native (Swift/Kotlin) over cross-platform frameworks
  • If you want to maximize code reuse across iOS and Android with a single codebase and have a web development team familiar with JavaScript/TypeScript, choose React Native or Flutter
  • If you're building enterprise apps with existing .NET expertise and need Windows platform support alongside mobile, choose .NET MAUI or Xamarin
  • If time-to-market is critical and you're building a content-driven app without complex native integrations, choose Flutter for its hot reload, rich widget library, and consistent UI across platforms
  • If you need access to the latest platform-specific APIs immediately upon release, extensive third-party native libraries, or platform-specific UI patterns (Material You, iOS design guidelines), choose Native development

Choose Swift If:

  • If you need truly native performance and platform-specific UI/UX (complex animations, AR/VR, heavy graphics processing), choose Native (Swift/Kotlin) over cross-platform frameworks
  • If you want to maximize code reuse across iOS and Android with a single codebase and have limited resources, choose React Native or Flutter over Native development
  • If your team already has strong web development skills (JavaScript/TypeScript) and wants faster onboarding, choose React Native; if they prefer strongly-typed languages and want better performance, choose Flutter
  • If you're building a simple content-driven app (news, e-commerce, social media) with standard UI components, cross-platform frameworks (React Native/Flutter) provide the best speed-to-market without sacrificing quality
  • If your app requires deep integration with platform-specific APIs, extensive use of native libraries, or you're building for a single platform only, invest in Native development (Swift for iOS, Kotlin for Android)

Our Recommendation for Mobile Development Projects

The decision hinges on team composition, timeline, and platform requirements. Choose Flutter when you need rapid cross-platform development with a single team, have limited mobile expertise, or require consistent UI/UX across platforms—it's particularly effective for MVPs, B2B applications, and resource-constrained teams. Select Swift and Kotlin when you have dedicated iOS and Android teams, need maximum performance, require immediate access to platform-specific features, or are building consumer apps where native polish significantly impacts user retention. Companies like Airbnb and Udacity moved away from cross-platform strategies to native for performance and platform integration reasons, while others like Alibaba and Google Ads successfully use Flutter for faster delivery. Bottom line: Flutter offers 40-60% faster development for cross-platform needs with acceptable performance trade-offs; Swift and Kotlin deliver superior platform-specific experiences at the cost of maintaining separate codebases. For most new projects targeting both platforms with small-to-medium teams, start with Flutter. For established companies with dedicated mobile teams or performance-critical applications, invest in native development with Swift and Kotlin.

Explore More Comparisons

Other Technology Comparisons

Explore comparisons between React Native vs Flutter for alternative cross-platform approaches, or dive into backend mobile technologies like Firebase vs AWS Amplify to complement your mobile development stack. Consider comparing mobile state management strategies like Redux vs BLoC vs Combine for architecture decisions.

Frequently Asked Questions

Join 10,000+ engineering leaders making better technology decisions

Get Personalized Technology Recommendations
Hero Pattern