Skip to main content

Overview

This quickstart guide will walk you through creating a simple mobile app that demonstrates NativePHP’s core capabilities. You’ll build an app that:
  • Displays a welcome screen
  • Captures photos using the device camera
  • Shows device information
  • Provides haptic feedback
This guide assumes you’ve already installed NativePHP Mobile. If not, complete the installation first.

Build your first app

1

Create or prepare your Laravel app

Start with a fresh Laravel application or use an existing one:
# Create a new Laravel app
composer create-project laravel/laravel my-mobile-app
cd my-mobile-app

# Install NativePHP Mobile
composer require nativephp/mobile

# Set up mobile platforms
php artisan native:install
When prompted, enter your app bundle ID (e.g., com.yourname.myfirstapp).
2

Create a simple mobile route

Open routes/web.php and replace the default route:
routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use Native\Mobile\Facades\Camera;
use Native\Mobile\Facades\Device;
use Native\Mobile\Facades\Haptics;

Route::get('/', function () {
    return view('welcome', [
        'deviceInfo' => Device::getInfo(),
    ]);
});

Route::post('/take-photo', function (Request $request) {
    // Capture a photo from the camera
    $photo = Camera::getPhoto([
        'quality' => 80,
        'allowEditing' => false,
        'resultType' => 'base64',
    ]);
    
    // Provide haptic feedback
    Haptics::vibrate();
    
    // Store the photo (optional)
    if ($photo && isset($photo['base64'])) {
        $filename = 'photo_' . time() . '.jpg';
        Storage::put('photos/' . $filename, base64_decode($photo['base64']));
        
        return response()->json([
            'success' => true,
            'message' => 'Photo captured!',
            'filename' => $filename,
        ]);
    }
    
    return response()->json([
        'success' => false,
        'message' => 'Failed to capture photo',
    ], 400);
});
3

Create a mobile-friendly view

Create or update resources/views/welcome.blade.php:
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My First NativePHP App</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100">
    <div class="min-h-screen flex flex-col items-center justify-center p-6">
        @mobile
            <div class="max-w-md w-full bg-white rounded-lg shadow-lg p-6">
                <h1 class="text-3xl font-bold text-gray-800 mb-4">
                    Welcome to NativePHP Mobile!
                </h1>
                
                <p class="text-gray-600 mb-6">
                    This app is built with PHP and Laravel, running natively on your device.
                </p>
                
                <div class="bg-blue-50 rounded-lg p-4 mb-6">
                    <h2 class="font-semibold text-blue-900 mb-2">Device Info</h2>
                    @if($deviceInfo)
                        <pre class="text-sm text-blue-800 overflow-auto">{{ json_encode($deviceInfo, JSON_PRETTY_PRINT) }}</pre>
                    @else
                        <p class="text-blue-700 text-sm">Device information not available</p>
                    @endif
                </div>
                
                <button 
                    onclick="takePhoto()"
                    class="w-full bg-blue-500 hover:bg-blue-600 text-white font-semibold py-3 px-6 rounded-lg transition duration-200"
                >
                    📸 Take a Photo
                </button>
                
                <div id="result" class="mt-4 text-center text-sm"></div>
            </div>
        @endmobile
        
        @web
            <div class="max-w-md w-full bg-white rounded-lg shadow-lg p-6 text-center">
                <h1 class="text-2xl font-bold text-gray-800 mb-4">
                    Mobile App Only
                </h1>
                <p class="text-gray-600">
                    This application is designed for mobile devices.
                    Please build and run it using:
                </p>
                <code class="block mt-4 bg-gray-100 p-3 rounded text-sm">
                    php artisan native:run
                </code>
            </div>
        @endweb
    </div>
    
    <script>
        async function takePhoto() {
            const resultDiv = document.getElementById('result');
            resultDiv.textContent = 'Opening camera...';
            resultDiv.className = 'mt-4 text-center text-sm text-gray-600';
            
            try {
                const response = await fetch('/take-photo', {
                    method: 'POST',
                    headers: {
                        'X-CSRF-TOKEN': '{{ csrf_token() }}',
                        'Accept': 'application/json',
                    },
                });
                
                const data = await response.json();
                
                if (data.success) {
                    resultDiv.textContent = '✅ ' + data.message;
                    resultDiv.className = 'mt-4 text-center text-sm text-green-600';
                } else {
                    resultDiv.textContent = '❌ ' + data.message;
                    resultDiv.className = 'mt-4 text-center text-sm text-red-600';
                }
            } catch (error) {
                resultDiv.textContent = '❌ Error: ' + error.message;
                resultDiv.className = 'mt-4 text-center text-sm text-red-600';
            }
        }
    </script>
</body>
</html>
4

Configure camera permissions

Add camera permissions to your config/nativephp.php:
config/nativephp.php
return [
    // ... other config
    
    'permissions' => [
        'camera' => 'We need camera access to take photos',
    ],
];
After changing permissions, re-run php artisan native:install --force to update native project files.
5

Run your app

Build and launch your mobile app:
# Run on iOS Simulator
php artisan native:run ios

# Or with hot reload for development
php artisan native:run ios --watch
The app will build and launch in the iOS Simulator. If you have multiple simulators, you’ll be prompted to choose one.
The first build may take a few minutes as Gradle downloads dependencies. Subsequent builds will be much faster.
6

Test the app

Once the app launches:
  1. Check device info - You’ll see device details displayed on screen
  2. Take a photo - Tap the “Take a Photo” button
  3. Grant camera permission - Allow camera access when prompted
  4. Capture an image - Take a photo or choose from gallery
  5. Feel the haptic - Your device will vibrate when the photo is captured
Photos are saved to storage/app/photos/ in your Laravel application.

Understanding the code

Let’s break down what’s happening in this quickstart app:

Native facades

NativePHP provides simple facades to access device features:
use Native\Mobile\Facades\Camera;
use Native\Mobile\Facades\Device;
use Native\Mobile\Facades\Haptics;

// Get device information
$info = Device::getInfo();

// Capture a photo with options
$photo = Camera::getPhoto([
    'quality' => 80,              // Image quality (0-100)
    'allowEditing' => false,      // Allow user to edit before returning
    'resultType' => 'base64',     // Return as base64 string
]);

// Provide haptic feedback
Haptics::vibrate();

Platform detection

Blade directives help you write platform-specific code:
@mobile
    {{-- Only shows in the mobile app --}}
    <button onclick="takePhoto()">Take Photo</button>
@endmobile

@web
    {{-- Only shows in web browser --}}
    <p>Please use the mobile app</p>
@endweb
You can also detect specific platforms:
@ios
    <p>iOS-specific content</p>
@endios

@android
    <p>Android-specific content</p>
@endangroid

API communication

Your mobile app communicates with your Laravel backend via standard HTTP requests:
// The app makes a POST request to this route
Route::post('/take-photo', function (Request $request) {
    $photo = Camera::getPhoto();
    return response()->json(['success' => true]);
});
The camera facade triggers native code, which returns data to PHP, just like any other Laravel request.

Development with hot reload

For the best development experience, use the --watch flag:
php artisan native:run android --watch
This enables hot reloading:
  • PHP changes - Routes, controllers, and views automatically refresh
  • Asset changes - CSS and JavaScript updates appear instantly
  • No rebuilding - Changes appear without recompiling the app
Hot reload requires your development machine and mobile device/emulator to be on the same network.

Exploring more features

Now that you have a working app, try adding more features:

Geolocation

Get the user’s current position and track movement

Secure storage

Store sensitive data securely on the device

Dialogs

Show native alerts, toasts, and share sheets

QR Scanner

Scan QR codes and barcodes

Quick example: Add geolocation

Add this to your routes:
use Native\Mobile\Facades\Geolocation;

Route::get('/location', function () {
    $position = Geolocation::getCurrentPosition(fineAccuracy: true);
    
    return response()->json($position);
});
Update permissions in config/nativephp.php:
'permissions' => [
    'camera' => 'We need camera access to take photos',
    'location' => 'We need your location to show nearby places',
],
Run php artisan native:install --force and your app can now access GPS.

Building for production

When you’re ready to publish your app:
# Create a release build
php artisan native:run ios --build=release

# Or package for App Store submission
php artisan native:package ios
See the iOS deployment guide for code signing and App Store submission.

Troubleshooting

Make sure you:
  1. Added camera permission to config/nativephp.php
  2. Ran php artisan native:install --force after adding permissions
  3. Granted permission when the app prompted you
Common issues:
  • iOS: Make sure iOS Simulator is installed in Xcode
  • Android: Ensure an emulator is running or device is connected
  • Check for errors with: php artisan native:tail ios or php artisan native:tail android
Ensure:
  • Your device/emulator and computer are on the same network
  • No firewall is blocking ports 3000 and 8081
  • The development server started successfully
Try:
# Clean and reinstall
php artisan native:install --force

# Check logs
php artisan native:tail [platform]

Next steps

Congratulations! You’ve built your first NativePHP Mobile app. Here’s what to explore next:

Native features

Explore all available device features and APIs

CLI reference

Learn about all available commands and options

Configuration

Customize your app’s behavior and appearance

Deployment

Prepare your app for the App Store and Play Store
Join the NativePHP community on Discord to share your creations and get help from other developers!

Build docs developers (and LLMs) love