In [Writing Your First App](/docs/2.0/writing-your-first-app), we created a native OS window that displays a single HTML page.

We'll now turn that window into a full desktop application by dividing the interface into multiple views, connecting native code to the page, and packaging the build for distribution.

## Lay Out the Window

You can divide a window into multiple views by arranging panels inside layout containers.

```cpp
///
/// Split the window into a fixed-width "nav" pane and a fluid "detail"
/// pane, with a draggable divider between them.
///
RefPtr<Container> body =
    window_->layout()->AddRow({ .key = "body", .resizable = true });
RefPtr<Panel> nav =
    body->AddPanel({ .key = "nav", .size = "220px", .min_size = "140px" });
RefPtr<Panel> detail = body->AddPanel({ .key = "detail" });

nav->view()->LoadURL("file:///nav.html");
detail->view()->LoadURL("file:///detail.html");
```

Each panel hosts its own `View` and manages its position automatically within the layout tree.

Setting `resizable` to `true` on a container lets the user resize adjacent panels by dragging the divider between them.

To configure sizing rules and constraints, see [Laying Out Panels](/docs/2.0/laying-out-panels). For overlays like toasts or modal dialogs that float above the layout tree, see [Floating Panels](/docs/2.0/floating-panels).

## Connect Native Code to the Page

Native code connects to the page through each panel's `View`, retrieved by calling `Panel::view()`.

Ultralight provides three ways to connect native code and the page. You can mix them freely across panels or within the same `View`.

| Approach | Description |
| :--- | :--- |
| [Data Bindings](/docs/2.0/about-data-bindings) | Bind native structs to the page so UI elements update automatically when data changes. Best for settings forms, lists, and status displays. |
| [DOM API](/docs/2.0/about-the-dom-api) | Find and modify page elements, update text and styles, and listen for events directly from C++. |
| [JavaScript API](/docs/2.0/about-javascript-interop) | Call JavaScript from C++ and vice-versa, with type-safe conversions. Best for logic that lives in the page. |

## Match Native Look and Feel

Ultralight includes APIs to help match the look and feel of the native OS.

| Guide | Description |
| :--- | :--- |
| [Native Window Styling](/docs/2.0/native-window-styling) | Window chrome, transparency, and background blur materials. |
| [Popups and Dialogs](/docs/2.0/popups-and-dialogs) | Popup windows for HTML menus and dropdowns, and native modal message boxes. |
| [Dark Mode and Color Schemes](/docs/2.0/dark-mode-and-color-schemes) | Detecting and responding to OS light and dark theme changes. |
| [Native Look and Feel](/docs/2.0/native-look-and-feel) | Walkthrough of the **10-native-look-and-feel** sample covering backdrop materials, popup menus, themes, and message boxes. |
| [Custom Window Chrome](/docs/2.0/custom-window-chrome) | Walkthrough of drawing title bars and caption buttons in HTML while keeping native dragging, resizing, and snapping. |

## Configure Application Settings

Before shipping, configure the application identity in `Settings` and pass it to `App::Create()`.

```cpp
Settings settings;
settings.developer_name = "Acme";
settings.app_name = "Starlight";

app_ = App::Create(settings);
```

Ultralight uses `Settings::developer_name` and `Settings::app_name` to create storage directories on the user's system— these directories store the log file and session data such as cookies and cache files.

To explore all configuration options and app events, see [App Lifecycle and Settings](/docs/2.0/app-lifecycle-and-settings).

## Package the Application

An installed application requires several support files beside the executable:

- The **assets** folder containing HTML, CSS, and client-side files.
- The Ultralight binaries for the target OS.
- The **resources** folder inside **assets**, containing ICU data and certificates.

For instructions on packaging these dependencies for Windows, macOS, and Linux, see [Shipping Your App](/docs/2.0/shipping-your-app).

## What's Next

From here, [Native Look and Feel](/docs/2.0/native-look-and-feel) walks through the **10-native-look-and-feel** sample to match the look and feel of the native OS.
