Amazon Developer

as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support
Skip to main content
React Native 0.83 on Vega renders in density-independent pixels (dp) by default. This page explains the unit change and how to update layout values, input handling, custom native interfaces, and images in your app. It expands on Step 4.9 of the code migration. In RN 0.83, layout values, component dimensions, transforms, scroll offsets, and pointer coordinates are all logical dp. Vega converts those logical values to physical pixels once, at the rendering boundary. If your app was tuned against the physical output of RN 0.72, review every numeric layout value before you ship.

About density-independent pixels

A dp is a logical UI unit. Vega maps it to physical pixels using the display scale factor:
Before migration, an app with dp rendering disabled drew width: 100 as 100 physical pixels. After migration, the same value means 100 dp. Vega draws it as 200 physical pixels at a scale factor of 2, or 266 physical pixels at a scale factor of 2.66. This is the main layout impact to evaluate. The Vega canvas reference size is 960x540 dp, which is a scale factor of 2 on a 1080p display.

What the unit change covers

RN 0.83 applies the dp mapping across the full UI path:
  • Vega scales the final drawing canvas and the damage regions.
  • Window sizes and positions cross the graphics boundary in physical pixels, but stay in dp in your app code.
  • Pointer, touch, resize, window-position, and occlusion events arrive back in React Native as dp.
  • Child windows, pop-ups, modals, texture-cached layers, and virtual surfaces use the same scale.
  • Dimensions and useWindowDimensions() report logical dimensions. PixelRatio.get() reports the ratio of physical pixels to dp.

What the unit change doesn’t cover

Two things keep their existing behavior:
  • Bitmap data. dp rendering doesn’t scale bitmap data or change image metadata. Image decoders, bitmaps, pixmaps, and textures continue to use physical pixel dimensions.
  • Font scaling. dp rendering doesn’t replace accessibility font scaling. Keep using React Native text APIs and fontScale for user-selected text size.

PixelRatio and the DeviceInfo TurboModule

PixelRatio is a React Native JavaScript utility, not a standalone TurboModule. PixelRatio.get() reads Dimensions.get('window').scale. The native DeviceInfo TurboModule supplies width, height, scale, and fontScale to Dimensions. In RN 0.83, DeviceInfo reports logical window dimensions along with the active physical-pixel-to-dp scale. It also publishes per-surface dimension updates through didUpdateDimensions.

Why Vega uses density-independent pixels

React Native on Android and iOS uses logical units by default. Vega adopts the same default coordinate model for RN 0.83 apps, so geometry behaves the same way on all three targets. One unit contract now covers standard React Native components, custom native components, TurboModules, third-party libraries, window APIs, rendering, and input events. Your app describes UI geometry in logical units, and Vega converts that geometry at the graphics boundary. UI proportions stay stable across devices with different canvas resolutions, and Scalable UI can select a higher-resolution canvas without a separate pixel layout.

Changes in your app

The following table maps common RN 0.72 patterns to their RN 0.83 behavior.

Convert pixel-tuned values

Numeric length values are dp in RN 0.83. Convert the values you tuned as physical pixels, using the scale factor of your pre-migration baseline:
For an app previously tuned for a scale factor of 2:
Apply the same conversion to margins, padding, borders, transforms, shadows, animation distances, SVG dimensions, and custom canvas coordinates that you calibrated as physical pixels. Leave a value unchanged when it already came from a density-independent UX specification.

Replace fixed screen dimensions

Hardcoded screen constants no longer describe the logical viewport. Read the dimensions at runtime instead.
useWindowDimensions() returns logical dimensions. Don’t convert them to physical pixels before you assign React Native styles.

Use logical input coordinates

RN 0.83 reports pointer and touch coordinates in dp:
Pass these values directly to your layout, gesture, focus, hit-testing, scroll, and animation code. If your app converts a coordinate that already arrives in dp, remove that conversion — otherwise the value is scaled twice.

Keep custom native interfaces in dp

Define custom component and TurboModule geometry as dp at the React Native boundary.
Forward these values unchanged when the native implementation calls Vega window, view, layer, or canvas APIs. Convert with the active scale factor only when you call an API documented in physical pixels, such as a bitmap decoder or a lower-level graphics API. When both units appear in one module, put the unit in the name, for example widthDp and targetWidthPx.

Handle images

Image layout and image data use different units:
  • <Image style={{width, height}}> uses dp.
  • Source bitmap dimensions, decoded image dimensions, row bytes, and texture dimensions use physical pixels.
  • When React Native supplies a preferred logical decode size, the Vega image pipeline multiplies it by the active scale factor before decoding. Don’t multiply the <Image> style or the preferred layout size in your own code.
  • A source needs enough physical pixels for its rendered dp size. An image rendered at 320x180 dp at a scale factor of 2 needs at least 640x360 source pixels to avoid upscaling.

Local assets

Provide density variants in the same directory. Metro and React Native select the asset that matches the active density.
For a fractional density such as 2.66, provide @3x data. React Native selects the next higher-resolution asset instead of upscaling a lower-resolution source. For icons and other non-photographic artwork, prefer SVG.

Migration checklist

To complete the dp migration, work through the following steps:
  1. Upgrade the app to RN 0.83 and remove any RN 0.72 dp experiment flags that duplicate the new default behavior.
  2. Inventory numeric length values, fixed canvas constants such as 1920 and 1080, and any coordinate conversion helpers in your app.
  3. Convert values tuned as physical pixels with logicalValue = legacyPixelValue ÷ baselineScaleFactor, and leave values from a density-independent UX specification unchanged.
  4. Treat pointer, gesture, scroll, resize, and window coordinates reported by RN 0.83 as dp.
  5. Change custom React-Native-to-native geometry contracts to dp, and keep pixel conversion only at documented pixel APIs.
  6. Replace fixed screen dimensions with Flexbox, percentages, Dimensions, or useWindowDimensions().
  7. Add local raster density variants and confirm each image has enough physical pixels for its rendered logical size.
  8. Test the main window, modals, pop-ups, alerts, child windows, scrolling, gestures, focus, accessibility, localization, and right-to-left layouts at each supported density.

External resources

Last modified on August 19, 2026