Skip to main content
Firstlight

For NativePHP and Laravel Boost

The app-shell layer for NativePHP.

composer require firstlightui/nativephp and Laravel Boost give you, or your coding agent, what a standard forms app needs: lists and detail, search, forms with Laravel validation, settings, sheets and dialogs, and feedback.

Every control is genuine SwiftUI on iOS and Jetpack Compose on Android. It runs on the SuperNative foundation created by Shane Rosenthal and Simon Hamp.

iOS
SwiftUI
Android
Compose M3
For agents
Boost + llms.txt
Status
1.0.0

Built for coding agents

Your agent already knows the recipes.

Firstlight ships a Laravel Boost guideline and two skills. Install Boost and your agent learns the rules every Firstlight screen follows, which recipe fits the screen you ask for, and which control fits each value.

Boost guideline
Always in your agent’s instructions: native chrome, Laravel validation, confirmed deletion, theme colours, and a tested example.
firstlight-init
Interviews you, checks the install, sets the theme and the native-chrome layout, and scaffolds your chosen recipes with tests.
building-firstlight-screens
Picks the recipe and the controls for each new screen, and lists what never to do.
llms.txt and llms-full.txt
Every documentation page in one request, recipes first. The package ships llms-full.txt too, matching the installed version.
Build with a coding agent →

Terminal

$ composer require firstlightui/nativephp
$ composer require laravel/boost --dev
$ php artisan boost:install
Then ask for the app
“Set up this app with Firstlight. The main record is a job. I want a searchable list of jobs, a form to create one, and a settings screen.”

An agent writes the screens and runs their Pest tests. Both skills end by asking you to check the app on an iOS simulator and an Android emulator.

Genuine native controls

One API, the right pattern on each platform.

Every Firstlight control is a real SwiftUI control on iOS and a Jetpack Compose Material 3 control on Android. Nothing is drawn to imitate a platform control, and there is no WebView. You write one Blade tag; each platform shows its own pattern.

Tabs
iOS: Segmented control
Android: Material 3 tabs
Confirmation Dialog
iOS: SwiftUI confirmationDialog
Android: Material 3 AlertDialog
Date Picker
iOS: Graphical SwiftUI DatePicker
Android: Material 3 DatePickerDialog
Field error
iOS: Error text under the field
Android: Material 3 supporting text in the error state

What Firstlight is not

Not navigation chrome
Stacks, title bars, back navigation, and tab bars come from NativePHP’s native chrome, usesNativeChrome(). Firstlight works inside it and does not replace it.
Not a design system
Controls take colours and fonts from the NativePHP theme and keep each platform’s own geometry, motion, and materials.
Not a catalogue of everything
No charts, no carousels, nothing custom-drawn. A control is added only when it has an equal native contract on iOS and Android.

Feels like Laravel

Form Requests, Gates, and Pest on native screens.

NativePHP EDGE has no screen-level validate(). Without it, errors appear as sibling @nativeError text or the generic error overlay. Firstlight adds ValidatesFields, SubmitsForms, AuthorizesActions, and list pagination and deletion as concerns on NativeComponent, so each message lands in the field’s native error slot.

Validate with a Form Request
Use $rules or a Form Request. Each field shows its first message natively, and <firstlight:callout error-for="form" /> shows errors that belong to the whole form.
$this->validate(
    StorePostRequest::class,
);
Submit once, authorize with Gates
submit() validates, runs the action once, and sends success Feedback. authorize() hides, disables, or guards actions with your Policies instead of the error overlay.
$this->submit(
    action: fn () => $post->save(),
    successMessage: 'Saved',
);
Test with Pest
ScreenAssertions adds field-error, list, dialog, and Feedback checks to NativePHP’s Native::test(). make:firstlight-screen --test scaffolds a screen and its test.
Native::visit('/posts/create')
    ->set('title', 'Hi')
    ->call('save')
    ->assertFieldError('title');

Accessible by default

Real native controls, so assistive technology just works.

Firstlight never draws its own controls. VoiceOver, TalkBack, Dynamic Type, font scaling, dark mode, Increased Contrast, Reduce Motion, and right-to-left layout reach every control the way they reach the platform’s own apps. Firstlight adds the decisions a native control can’t make on its own.

Labels and actions for VoiceOver and TalkBack
Icon-only controls refuse to render without an accessible name, and fields warn in development without one. A row or a field is one focus stop, and every swipe and context-menu action is also a screen-reader action.
Validation errors are spoken
A failed submit reads its errors aloud once, then moves screen-reader focus to the first invalid field. A field that fails on blur reads only its own message.
Text grows, layouts flip
Dynamic Type and Android font scaling reach every control, and labels wrap instead of truncating. Right-to-left layouts mirror natively, with code kept left-to-right.
Motion and time follow the reader
Reduce Motion is honoured by the platform controls, and feedback fades instead of sliding on iOS. Feedback stays longer while a screen reader is on.
Targets you can hit
Every action Firstlight owns, from icon buttons to the search clear button, is at least 44 points on iOS and 48 dp on Android.
Status is not colour alone
Callouts name their tone in words, and status colours below 4.5:1 contrast are corrected to black or white text as they render.

Where verification stands

This behaviour is covered by contract, XCTest, and Robolectric tests, and VoiceOver was checked on a physical iPhone. Spoken TalkBack output has not yet been recorded on a physical Android device.

What’s covered and what’s tested →

Components

Every control, on both platforms.

Fields, choices, lists, dialogs, sheets, status, and feedback. Every field shares the same value, label, error, disabled, and required behaviour, so a form needs no per-control special cases. Each screenshot below comes from the iOS and Android renderers.

Component gallery 1 / 32

Button

Available
firstlight:button

Run one labelled action with a native button.

Explore Button
Native evidence
iOS Native
Firstlight Button rendered on iOS
Android Native
Firstlight Button rendered on Android

Callout

Available
firstlight:callout

Keep an important semantic message visible in the page layout with an optional labelled action.

Explore Callout
Native evidence
iOS Native
Firstlight Callout rendered on iOS
Android Native
Firstlight Callout rendered on Android

Badge

Available
firstlight:badge

Show a compact, display-only count or short marker.

Explore Badge
Native evidence
iOS Native
Firstlight Badge rendered on iOS
Android Native
Firstlight Badge rendered on Android

Checkbox

Available
firstlight:checkbox

Toggle one Boolean value in a form or checklist, with the state kept in PHP.

Explore Checkbox
Native evidence
iOS Native
Firstlight Checkbox rendered on iOS
Android Native
Firstlight Checkbox rendered on Android

Alert Dialog

Available
firstlight:alert-dialog

Present one native acknowledgement with a single action and server-controlled dismissal.

Explore Alert Dialog
Native evidence
iOS Native
Firstlight Alert Dialog rendered on iOS
Android Native
Firstlight Alert Dialog rendered on Android

Modal

Available
firstlight:modal

Present authored content in a full-screen native overlay with server-controlled dismissal.

Explore Modal
Native evidence
iOS Native
Firstlight Modal rendered on iOS
Android Native
Firstlight Modal rendered on Android

Date Picker

Available
firstlight:date-picker

Choose an optional calendar date with each platform’s native, server-authoritative picker.

Explore Date Picker
Native evidence
iOS Native
Firstlight Date Picker rendered on iOS
Android Native
Firstlight Date Picker rendered on Android

Time Picker

Available
firstlight:time-picker

Choose an optional wall-clock time while keeping the model value exact and server-authoritative.

Explore Time Picker
Native evidence
iOS Native
Firstlight Time Picker rendered on iOS
Android Native
Firstlight Time Picker rendered on Android

Icon Button

Available
firstlight:icon-button

Trigger one compact, accessible action through native SwiftUI and Material icon buttons.

Explore Icon Button
Native evidence
iOS Native
Firstlight Icon Button rendered on iOS
Android Native
Firstlight Icon Button rendered on Android

List Item

Available
firstlight:list-item

Present one tappable application row with supporting text, leading identity, and a trailing affordance.

Explore List Item
Native evidence
iOS Native
Firstlight List Item rendered on iOS
Android Native
Firstlight List Item rendered on Android

List

Available
firstlight:list

Compose finite vertical collections of List Item rows with optional grouped sections and refresh or pagination hooks.

Explore List
Native evidence
iOS Native
Firstlight List rendered on iOS
Android Native
Firstlight List rendered on Android

Pill Group

Available
firstlight:pill-group

Offer compact, individually shaped options for single or multiple selection.

Explore Pill Group
Native evidence
iOS Native
Firstlight Pill Group rendered on iOS
Android Native
Firstlight Pill Group rendered on Android

Progress

Available
firstlight:progress

Communicate determinate completion or indeterminate work with the native platform indicator.

Explore Progress
Native evidence
iOS Native
Firstlight Progress rendered on iOS
Android Native
Firstlight Progress rendered on Android

Segmented

Available
firstlight:segmented

Pick one of a few mutually exclusive choices with a native segmented control.

Explore Segmented
Native evidence
iOS Native
Firstlight Segmented rendered on iOS
Android Native
Firstlight Segmented rendered on Android

Search Field

Available
firstlight:search-field

Enter and submit one query with native search, clear, focus, keyboard, and selection behaviour.

Explore Search Field
Native evidence
iOS Native
Firstlight Search Field rendered on iOS
Android Native
Firstlight Search Field rendered on Android

Select

Available
firstlight:select

Choose one stable string or integer value from a collapsed native selection field.

Explore Select
Native evidence
iOS Native
Firstlight Select rendered on iOS
Android Native
Firstlight Select rendered on Android

Slider

Available
firstlight:slider

Select one value from an exact numeric grid using each platform’s native slider.

Explore Slider
Native evidence
iOS Native
Firstlight Slider rendered on iOS
Android Native
Firstlight Slider rendered on Android

Stepper

Available
firstlight:stepper

Move an accepted numeric value through a bounded range one exact step at a time.

Explore Stepper
Native evidence
iOS Native
Firstlight Stepper rendered on iOS
Android Native
Firstlight Stepper rendered on Android

Metric

Available
firstlight:metric

Display one labelled value with tabular figures, an optional detail, and a single accessible description.

Explore Metric
Native evidence
iOS Native
Firstlight Metric rendered on iOS
Android Native
Firstlight Metric rendered on Android

Media

Available
firstlight:media

Capture one image or document into Laravel Storage with camera, library, or file picking and optional crop.

Explore Media
Native evidence
iOS Native
Firstlight Media rendered on iOS
Android Native
Firstlight Media rendered on Android

Text Field

Available
firstlight:text-field

Edit one line of text with each platform’s native keyboard, autofill, selection, and accessibility behaviour.

Explore Text Field
Native evidence
iOS Native
Firstlight Text Field rendered on iOS
Android Native
Firstlight Text Field rendered on Android

Text Area

Available
firstlight:text-area

Edit multiline text with native selection, composition, focus, scrolling, and correction behaviour.

Explore Text Area
Native evidence
iOS Native
Firstlight Text Area rendered on iOS
Android Native
Firstlight Text Area rendered on Android

Switch

Available
firstlight:switch

Present one boolean setting through each platform’s familiar native on/off control.

Explore Switch
Native evidence
iOS Native
Firstlight Switch rendered on iOS
Android Native
Firstlight Switch rendered on Android

Tabs

Available
firstlight:tabs

Switch between sections of one object with native tabs, counts, and selection your component controls.

Explore Tabs
Native evidence
iOS Native
Firstlight Tabs rendered on iOS
Android Native
Firstlight Tabs rendered on Android

Code Editor

Available
firstlight:code-editor

Edit JSON, YAML, env, and plain text with line numbers, native indentation, a key row, and follow mode for live logs.

Explore Code Editor
Native evidence
iOS Native
Firstlight Code Editor rendered on iOS
Android Native
Firstlight Code Editor rendered on Android

How it renders

The same rendering pipeline as NativePHP.

Firstlight uses the same EDGE element tree, renderers, theme, and event lifecycle as NativePHP Mobile UI. Ordinary interaction, such as typing and scrolling, stays on the native UI thread.

01
Your Blade view compiles to Firstlight elements.
02
The shared element tree describes each control in platform-neutral terms.
03
SwiftUI on iOS and Jetpack Compose on Android draw the native control.

Quickstart

Add Firstlight to a NativePHP app.

Requires NativePHP Mobile ^4.7 and Mobile UI ^0.9.

Build your screens with FirstlightUI\NativeComponent, starting from the list and detail recipe. Add Laravel Boost so your coding agent does the same.

composer require firstlightui/nativephp
Read the installation guide →

Firstlight 1.0.0 is the first stable release. It has been tested on physical iOS and Android devices, including VoiceOver on iOS. Spoken TalkBack output and long-running performance tests have not been recorded yet. Read the compatibility notes.