Hotwire Native Integration

Go Native with your Symfony app

Wrap your Symfony web application in a native mobile shell with Hotwire Native. Detect native requests, conditionally render content, and generate JSON configurations for your mobile clients.

composer require symfony/ux-native

Without UX Native

A Symfony + Bootstrap todo-list app displayed inside a mobile browser, with the browser navigation bar and the web navbar visible.

Browser navigation bar, web navbar — it feels like a website.

With UX Native

The same Symfony + Bootstrap todo-list app but with Hotwire Native: native title bar, no browser chrome, clean native experience.

Native title bar, no browser chrome — it feels like an app.

{# Navbar only visible in the web browser #}
{% if not ux_is_native() %}
    <nav class="navbar">
        <a href="/">TaskFlow</a>
    </nav>
{% endif %}

<h1>My Tasks</h1>
<!-- ... -->

One codebase, two experiences

No need to duplicate templates. The ux_is_native() Twig function lets you adapt your existing Twig templates for native clients: hide the navbar, remove the footer, or show mobile-specific content, all from the same code.

JSON configurations, the Symfony way

Use PHP attributes to declare your native configurations: path rules, settings, per-platform overrides.

UX Native serves them dynamically during development and can dump them as static JSON files for production deployment.

namespace App\Native;

use Symfony\UX\Native\Attribute\AsNativeConfiguration;
use Symfony\UX\Native\Attribute\AsNativeConfigurationProvider;
use Symfony\UX\Native\Configuration\Configuration;
use Symfony\UX\Native\Configuration\Rule;

#[AsNativeConfigurationProvider]
final class AppNativeConfiguration
{
    #[AsNativeConfiguration('/config/ios_v1.json')]
    public function iosV1(): Configuration
    {
        return new Configuration(
            rules: [
                new Rule(
                    patterns: ['.*'],
                    properties: [
                        'context' => 'default',
                        'pull_to_refresh_enabled' => true,
                    ],
                ),
                new Rule(
                    patterns: ['^/tasks/new$'],
                    properties: [
                        'context' => 'modal',
                        'pull_to_refresh_enabled' => false,
                    ],
                ),
            ],
        );
    }
}
    ```

Install It

$ composer require symfony/ux-native