Skip to content

bodenberg/appdimens

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

246 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
AppDimens — responsive sizing across phones, foldables, tablets, TVs, and the web

AppDimens — Smart Responsive Dimensions for Any Screen

A family of responsive sizing libraries that replaces fragile dp / sp / pt / px with explicit, perceptual scaling kernels — same vocabulary, same math, across Android, Apple, KMP, Flutter, React Native and the Web.

Repo License Platforms Scaling modes Contributions welcome

Read the docs Practical guide Examples

Platform repositories (quick reference)

Each implementation lives in its own GitHub repository (not only the submodules in this hub). Status reflects the current product line described in that repo’s README.

Repository Platform Status
appdimens-dynamic Android — Jetpack Compose, Kotlin Views, Java Views Production
appdimens-sdps Android — XML @dimen SDP-style resources (+ Compose tokens) Production
appdimens-ssps Android — XML SSP-style text resources (+ Compose tokens) Production
appdimens-games Android — game / NDK sizing helpers Work in progress
appdimens-ios Apple — iOS / iPadOS / macOS (UIKit, SwiftUI, Metal) Work in progress
appdimens-dynamic-kmp Kotlin Multiplatform Work in progress
appdimens-flutter Flutter — Android, iOS, Web, desktop Work in progress
appdimens-react-native React Native — iOS & Android Work in progress
appdimens-web Web — vanilla JS, React, Vue, Svelte, Angular Work in progress

Details, coordinates, and semver: see Platform matrix below.

Tip

TL;DR — Plain dp / sp / pt / px factor out density but not canvas extent or aspect ratio. AppDimens models token sizing as a family of one-dimensional maps with explicit kernels (linear, hybrid linear–logarithmic, Weber–Fechner, Stevens, fluid clamp, geometric, letterbox/fill, density buckets, constraint-based resize) and gives you the same vocabulary on every platform so a 16.sdp on Android Compose, a balanced(16) on iOS / Flutter / React Native, and a webdimens.balanced(16) on the Web all describe the same idea.

This repository is the documentation hub. Each platform library ships from its own submodule with its own semver, install line, and changelog. The hub never pins versions — always confirm the install line in the submodule README you depend on.


Table of contents

  1. Platform repositories (quick reference)
  2. What is AppDimens?
  3. The problem it solves
  4. How AppDimens solves it
  5. Why AppDimens (advantages)
  6. When to use AppDimens (scenarios)
  7. The 14 scaling kernels at a glance
  8. Quick start (multi-stack)
  9. Platform matrix
  10. Hub vs submodules — who owns what
  11. Documentation map (DOCS/)
  12. Performance snapshot
  13. Comparison with alternatives
  14. FAQ
  15. Roadmap & status
  16. Contributing, security, license
  17. Author

What is AppDimens?

AppDimens is a multi-platform family of responsive sizing libraries. You write a single base value at the call-site — 16.sdp, balanced(16), webdimens.balanced(16) — and the library transforms it through an explicit, named kernel that reflects the current screen Configuration (width, height, aspect ratio, density, orientation, multi-window flags, fold state).

The hub publishes the shared vocabulary (BALANCED, DEFAULT, PERCENTAGE, …) and the mathematical reference for every kernel. Each platform repository (appdimens-dynamic, appdimens-sdps, appdimens-ssps, appdimens-ios, appdimens-dynamic-kmp, appdimens-flutter, appdimens-react-native, appdimens-web, appdimens-games) implements that vocabulary natively, so design tokens travel across stacks without translation.

Two operating tracks coexist:

  • Runtime computation (appdimens-dynamic, iOS, Flutter, RN, Web, KMP): a tiny kernel runs at call time, reading the live Configuration and producing a Dp / point / px value through the chosen strategy. Lock-free padded cache keeps hot-path cost at roughly 5 ns per hit on a Snapdragon 888, ~1 ns on JVM (see Performance snapshot).
  • Pre-computed resources (appdimens-sdps, appdimens-ssps): thousands of pre-calculated @dimen/_*sdp, @dimen/_*ssp, _*hdp, _*wdp resources, ready to drop into XML — zero-runtime sizing for view systems and Compose alike.

You can — and many teams do — combine both.


The problem it solves

Modern UIs ship on a moving target. The same code base must look right on:

Form factor Typical width (dp / pt) What "48 looks like" with raw dp/sp/pt
Watches < 240 48 covers ~20% of the screen — too dominant
Small phones 320–360 ~14–15% — the calibrated baseline
Phablets / regular phones 360–480 10–13% — already drifting
Small tablets 600–720 6.7% — visibly cramped
Large tablets / foldables (open) 720–960 5–6% — clearly undersized
TVs 960–1920+ 2.5–5% — practically invisible
Web / desktop viewports 1024–3840+ < 2% — broken

dp / sp factor out physical density but not canvas extent, and they are blind to aspect ratio (a 4:3 tablet and a 21:9 phone receive the same number). Naïve linear scalers like SDP fix the smallness on tablets only to produce oversized UI on the same TVs.

Concretely, for a 48 dp button:

Approach Phone (360 dp) Tablet (720 dp) TV (1080 dp) Verdict
Raw dp / sp 48 dp (13%) ✅ 48 dp (6.7%) ❌ tiny 48 dp (4.4%) ❌ invisible Density-only
Linear SDP / SSP 58 dp (16%) ✅ 115 dp (16%) ❌ huge 173 dp (16%) ❌ enormous Over-scales
AppDimens auto (BALANCED) 58 dp (16%) ✅ ~70 dp (10%) ✅ ~85 dp (8%) ✅ Calibrated everywhere

The 720 dp / 1080 dp rows above are reproducible from DimenAutoDp (auto.md, hinge at 480 dp, ln gain 0.4).


How AppDimens solves it

flowchart LR
  concept["Hub concept<br/>(BALANCED · DEFAULT · PERCENTAGE · …)"] --> submodule["Submodule kernel<br/>(scaled · auto · percent · …)"]
  submodule --> token["Stack token<br/>(16.sdp · 16.asdp · balanced(16) · …)"]
  token --> output["Output Dp / Pt / Px<br/>(Configuration-aware)"]
Loading

Token sizing is modeled as a family of one-dimensional maps

f_S : (b, c) ↦ f_S(b, c)

where b is the design-time base (a dp / sp) and c is a snapshot of the runtime Configuration (post orientation/multi-window plumbing). S selects a kernelscaled, auto, percent, power, logarithmic, fluid, interpolated, diagonal, perimeter, fit, fill, density, resize, or NONE.

Every kernel obeys four invariants (THEORY.md §1.2):

  1. Reference fixed point. f_S(b, c₀) = b on the calibrated reference canvas — your design comp size is preserved on the reference device.
  2. Monotone in canvas extent. Bigger canvas ⇒ never smaller output.
  3. Bounded growth. Output is sandwiched between linear and logarithmic envelopes — no runaway tablets/TVs.
  4. Aspect-ratio aware (opt-in). The optional a suffix folds in an AR multiplier referenced to 16:9.

The verified constants (cross-checked against DesignScaleConstants.kt):

Constant Value Meaning
BASE_WIDTH_DP 300f Reference width denominator (matches the 300 dp design-comp tradition)
BASE_HEIGHT_DP 533f Companion height baseline
REFERENCE_ASPECT_RATIO 1.78f Neutral AR (16:9) — multiplier is 1 here
Diagonal baseline √(300² + 533²) ≈ 611.63 dp For diagonal kernel
Perimeter baseline 833 dp For perimeter kernel
auto hinge measured axis 480 dp BALANCED switches from linear to log here
auto ln gain 0.4f Log damping coefficient

For the full math, see DOCS/THEORY.md and the canonical MATHEMATICS-AND-CALCULUS.md inside appdimens-dynamic.


Why AppDimens (advantages)

Each bullet below either points to a verifiable file in this repository or a measurable constant.

Engineering

  • Explicit kernels per call-site. No surprise behaviour — 16.sdp is always the scaled kernel and 16.asdp is always the auto kernel. The Kotlin extension you write is the formula you read. (COMPOSE-API-CONVENTIONS.md)
  • Zero-XML option. Pure code-driven sizing via appdimens-dynamic. Or pre-baked @dimen resources via appdimens-sdps / appdimens-ssps when you want XML tooling and zero-runtime cost.
  • Sub-microsecond hot path. Padded, sharded, lock-free cache. ~5 ns cache hit, ~2 ns raw multiply (Snapdragon 888 hardware capture, see appdimens-dynamic/PERFORMANCE.md).
  • Foldable & multi-window aware. Effective-axis selection consults WindowManager fold state and isInMultiWindowMode. Both behaviours are opt-out per call via the i / ia suffixes (THEORY.md §3).
  • R8 / ProGuard ready. AARs ship consumer-rules.pro and res/raw/keep.xml so apps can use minifyEnabled, R8 full mode (android.enableR8.fullMode=true), and shrinkResources without extra rules. See appdimens-dynamic/R8-PROGUARD.md.
  • Test- and preview-friendly. Kernels are pure functions of (base, Configuration) — works identically inside @Preview, unit tests, and BoxWithConstraints.

Design

  • Perceptual scaling. Not just proportional — kernels like auto, logarithmic, power damp growth on large canvases the way human visual perception expects (Weber–Fechner, Stevens). (THEORY.md §5)
  • Aspect-ratio compensation, opt-in. The a suffix folds an AR multiplier referenced to 16:9. Elongated phones / foldables / wide TVs keep their visual weight without bespoke remember blocks.
  • Orientation inverters. Authored portrait but the device rotates? The *Ph, *Lw, *Lh token families switch the driving axis automatically. (DOCS/ORIENTATION.md)
  • Physical units (mm / cm / inch). Real-world measurements where they matter (kiosks, AR, accessibility hit targets). (physical-units.md)

Ecosystem

  • Six platform tracks under one vocabulary — see Platform matrix. Android Compose + XML, Apple (UIKit + SwiftUI), Kotlin Multiplatform, Flutter, React Native, Web (vanilla / React / Vue / Svelte / Angular), and a games surface with Android NDK + iOS Metal.
  • Compose 3.x package split. Each kernel is its own Gradle source package (compose.scaled, compose.auto, compose.percent, …). You import what you use and nothing else — the binary footprint stays small.

Maintenance & honesty

  • Every kernel is cited to a Kotlin file under appdimens-dynamic/DOCUMENTATION/ and a regression test under appdimens-dynamic/library/.
  • Hub theory is reproducible. Numerical comparisons in DOCS/THEORY.md §8 come from the same kernels you ship.
  • No marketing-rank claims. The hub does not pretend a single global "best library" ranking. Categorical trade-offs vs other tools are discussed honestly in Comparison with alternatives.

When to use AppDimens (scenarios)

Scenario Why AppDimens helps Suggested entry point
Multi-form-factor product (phones + tablets + foldables in one binary) auto (BALANCED) keeps the same UI calibrated on a 360 dp phone and a 720 dp tablet, without the SDP overshoot appdimens-dynamic quick start → tokens asdp / assp
TV / large-screen companion app logarithmic and auto damp growth on canvases beyond 480 dp instead of inflating linearly logarithmic.md · auto.md
Cross-platform design system Same vocabulary on Android / iOS / KMP / Flutter / RN / Web — design tokens travel verbatim DOCS/PLATFORMS.md
XML view system with breakpoint resources @dimen/_16sdp, _18ssp, _300wdp, … shipped pre-computed; no runtime cost appdimens-sdps · appdimens-ssps
Typography with hard min/max bounds fluid clamps a typographic band (e.g. 16–24 sp between 320–768 dp) the same way CSS clamp() would, with optional AR fluid.md
Game UI / HUD on arbitrary viewports fit (letterbox) and fill (cover) keep the HUD intact across aspect ratios fit.md · fill.md
Native game rendering (NDK / Metal) Specialized modules with C++/NDK on Android (appdimens-games) and Metal on iOS appdimens-games/
Real-world physical sizing (kiosks, AR, accessibility targets) mm / cm / inch helpers on every stack physical-units.md
Rotation- / foldable-sensitive layouts Base-orientation + *Ph / *Lw / *Lh inverters DOCS/ORIENTATION.md
Container-fit titles / square widgets resize builders (autoResizeTextSp, autoResizeSquareSize) pick the largest size in a min..max range that still fits resize.md

The 14 scaling kernels at a glance

Sourced from appdimens-dynamic/DOCUMENTATION/ and cross-checked in DOCS/THEORY.md §5 and DOCS/PLATFORMS.md. Tokens shown are Compose 3.x; iOS / Flutter / RN / Web use builder names — see PLATFORMS.md.

# Kernel Hub label Compose token sketch Primary use case Reference
1 scaled DEFAULT / FIXED sdp, hdp, wdp, ssp, sem, sdpa Phone-first SDP-style baseline (most common) scaled.md
2 auto BALANCED asdp, ahdp, awdp, assp Multi-device hybrid (linear under 480 dp, logarithmic above) auto.md
3 percent PERCENTAGE / DYNAMIC psdp, phdp, pwdp, plus literal space* percentages Axis-heavy / proportional containers and grids percent.md
4 power Stevens-style pwsdp, pwssp Configurable sublinear curve (exponent 0.6–0.9) power.md
5 logarithmic Weber–Fechner logsdp, logssp Maximum damping on TV / very large tablets logarithmic.md
6 fluid Clamp band fsdp, fssp Typography / spacing between explicit min/max fluid.md
7 interpolated Fixed–linear blend isdp, issp Moderate scaling (50% linear / 50% fixed) interpolated.md
8 diagonal Euclidean dsdp, dssp Scale by screen diagonal (true physical feel) diagonal.md
9 perimeter psdp (perimeter package), pssp Scale by W + H perimeter perimeter.md
10 fit Letterbox fitsdp, fitssp Game / canvas content that must not crop fit.md
11 fill Cover fillsdp, fillssp Game / canvas content that must fill fill.md
12 density DPI-bucket densdp, denssp Scale only when the dpi bucket changes density.md
13 resize Constraint geometry autoResizeTextSp, autoResizeSquareSize, ResizeBound Pick the largest size in a min..max range that fits resize.md
14 physical units Real-world 10.mm, 8.cm, 5.inch Real-world measurements (kiosks, AR, accessibility) physical-units.md

Plus a conceptual NONE (raw Dp / Sp) for surfaces that must stay constant.

Aspect-ratio suffix. Append a to scaled / auto / interpolated / logarithmic / power tokens (16.sdpa, 16.asdpa, 16.sspa, 16.assp) to fold in the AR multiplier described in THEORY.md §4. Append i / ia to opt out of the multi-window heuristic. The fluid package exposes AR as an explicit builder parameter instead.


Quick start (multi-stack)

Install lines below are illustrative. The authoritative semver line for every artifact lives in the submodule README — click through before pinning.

Android — Jetpack Compose (appdimens-dynamic, production)

import com.appdimens.dynamic.compose.*

Box(
    Modifier
        .padding(16.sdp)       // scaled — SDP-style baseline
        .width(100.wdp)        // scaled — width axis
        .height(48.hdp)        // scaled — height axis
) {
    Text("Hello", fontSize = 16.ssp)
    // For the hybrid BALANCED curve, use the `auto` tokens:
    // padding(16.asdp), fontSize = 16.assp
}

appdimens-dynamic/README.md#quick-start--scaled-compose for full install line and AppDimensProvider setup.

Android — XML resources (appdimens-sdps + appdimens-ssps, production)

<TextView
    android:layout_width="@dimen/_300sdp"
    android:layout_height="wrap_content"
    android:padding="@dimen/_16sdp"
    android:textSize="@dimen/_18ssp"
    android:text="Hello" />

appdimens-sdps/README.md · appdimens-ssps/README.md.

iOS — SwiftUI (appdimens-ios, work in progress)

Text("Hello")
    .font(.system(size: AppDimens.shared.balanced(16).toPoints()))
    .padding(AppDimens.shared.balanced(16).toPoints())
    .frame(width: AppDimens.shared.balanced(300).toPoints())

appdimens-ios/ for current install status.

Kotlin Multiplatform (appdimens-dynamic-kmp, work in progress)

KMP test line publishes under the same Maven artifact ID; do not mix blindly with Android 3.1.x. The KMP track is aiming at its first stable 1.0.0 and is documented inside appdimens-dynamic-kmp/.

Flutter (appdimens-flutter, work in progress)

Container(
  width: AppDimens.fixed(300).calculate(context),
  padding: EdgeInsets.all(AppDimens.fixed(16).calculate(context)),
  child: Text(
    'Hello',
    style: TextStyle(fontSize: AppDimens.fixed(16).calculate(context)),
  ),
)

appdimens-flutter/.

React Native (appdimens-react-native, work in progress)

{% raw %}

const { balanced } = useAppDimens();

return (
  <View style={{ padding: balanced(16) }}>
    <Text style={{ fontSize: balanced(16) }}>Hello</Text>
  </View>
);

{% endraw %}

appdimens-react-native/.

Web — webdimens (work in progress)

import { webdimens } from 'webdimens';

document.getElementById('title')!.style.fontSize = webdimens.balanced(24);
document.getElementById('container')!.style.padding  = webdimens.balanced(16);

appdimens-web/ for framework-specific (React / Vue / Svelte / Angular) hooks.


Platform matrix

Each folder below is its own Git submodule. Always confirm semver in the submodule README before pinning.

Submodule Platform What it ships Status Illustrative coordinate
appdimens-dynamic/ Android (Compose, Kotlin, Java) Runtime kernels — all 14 scaling modes (12 strategies + Resize + Physical units) Production io.github.bodenberg:appdimens-dynamic:3.1.5
appdimens-sdps/ Android (XML, Compose, Kotlin, Java) Pre-computed @dimen/_*sdp / _*hdp / _*wdp resources + Compose tokens Production io.github.bodenberg:appdimens-sdps:3.1.2
appdimens-ssps/ Android (XML, Compose, Kotlin, Java) Pre-computed @dimen/_*ssp text resources + Compose tokens Production io.github.bodenberg:appdimens-ssps:3.1.2
appdimens-games/ Android (Kotlin + C++/NDK + OpenGL ES) Specialized game-loop dimension types, Vector2D / Rectangle, viewport modes Work in progress io.github.bodenberg:appdimens-games:2.0.1
appdimens-ios/ iOS / macOS (UIKit + SwiftUI + Metal) AppDimens.shared.balanced(_) / defaultScaling(_) / smart(_) / fluid + Metal games Work in progress CocoaPods 2.0.0 / SPM (see submodule)
appdimens-dynamic-kmp/ Kotlin Multiplatform Same vocabulary as appdimens-dynamic, multiplatform targets Work in progress Test line …appdimens-dynamic:4.0.0 — first KMP stable aimed at 1.0.0
appdimens-flutter/ Flutter (Android / iOS / Web / desktop) AppDimens.fixed(_), .dynamic(_), .fluidTo(_), .cm / .mm extensions Work in progress appdimens: ^2.0.0
appdimens-react-native/ React Native (iOS / Android) useAppDimens() hook with balanced / defaultScaling / smart / fluid Work in progress [email protected]
appdimens-web/ Web (vanilla / React / Vue / Svelte / Angular) webdimens.balanced(_) + framework-specific hooks/services Work in progress [email protected]

GitHub mirrorsdynamic · kmp · sdps · ssps · games · ios · flutter · react-native · web.

Clone with submodules

git clone --recurse-submodules https://github.com/bodenberg/appdimens.git
cd appdimens && git submodule update --init --recursive

Only need one stack? Prefer cloning the upstream repo for that artifact from the author's repositories instead of this umbrella.


Hub vs submodules — who owns what

flowchart LR
  Hub["appdimens hub<br/>(this repo)"]
  Hub --> AndroidGroup["Android"]
  Hub --> Apple["Apple / iOS"]
  Hub --> KMP["Kotlin Multiplatform"]
  Hub --> Flutter
  Hub --> RN["React Native"]
  Hub --> Web
  AndroidGroup --> dyn["appdimens-dynamic Production"]
  AndroidGroup --> sdps["appdimens-sdps Production"]
  AndroidGroup --> ssps["appdimens-ssps Production"]
  AndroidGroup --> games["appdimens-games WIP"]
  Apple --> ios["appdimens-ios WIP"]
  KMP --> kmpArtifact["appdimens-dynamic-kmp WIP"]
  Flutter --> flu["appdimens-flutter WIP"]
  RN --> rn["appdimens-react-native WIP"]
  Web --> webdimens["webdimens WIP"]
Loading

Important

Responsibility split

  • Hub (DOCS/ + this README) owns: shared vocabulary, mathematical theory, kernel taxonomy, cross-platform mapping, migration paths, hub-level FAQ. No pinned versions, ever.
  • Submodules own: source, semver, Gradle / npm / pod / pub install lines, R8/ProGuard rules, per-API changelogs, code-level docs, regression tests.

When prose in the hub disagrees with the submodule, the submodule is the source of truth.

Runtime dynamic vs baked sdps / ssps on Android

appdimens-dynamic appdimens-sdps / appdimens-ssps
Computation Runtime from live Configuration Pre-computed res/values-sw*/dimens.xml buckets
Flexibility All 14 kernels, per-call AR / inverter / qualifier flags One curve per artifact, @dimen friendly
Cost Tiny AAR; ~5 ns cache hit, ~2 ns no-AR multiply Larger resource tables, zero runtime
XML integration Only via Compose / code package First-class @dimen/_16sdp etc.

Many teams mix both: SDP/SSP for XML layouts, appdimens-dynamic for Compose / Kotlin-side dimensions. Full taxonomy of when to pick which: DOCS/THEORY.md and DOCS/GUIDE.md.


Documentation map (DOCS/)

The DOCS/ folder is theory-only — concepts, math, cross-platform mapping, migration. Choose your learning path:

Goal Read Then
I want to ship today DOCS/GUIDE.md — strategy decision tree, FAQs, common patterns Submodule README for your stack
I want to understand the math DOCS/THEORY.md — formal kernels, axioms, comparisons MATHEMATICS-AND-CALCULUS.md
I'm migrating from 1.x / 2.x / SDP–SSP DOCS/MIGRATION.md — legacy .fxdp / .dydp / unified DSL → Compose 3.x packages The submodule changelog you ship
I'm porting across stacks DOCS/PLATFORMS.md — concept ↔ submodule API, verified constants The matching submodule README
I rotate / foldable my UI DOCS/ORIENTATION.md — base orientation, *Ph / *Lw / *Lh inverters COMPOSE-API-CONVENTIONS.md
I want copy-paste recipes DOCS/EXAMPLES.md — long-form snippets per stack The submodule's app/ sample where available

Visual & interactive resources

Precision scaling PDF Android scaling PDF UI scaling PDF Beyond DP PDF

Scaling comparison HTML Dynamic vs fixed HTML

Image gallery


Performance snapshot

Numbers captured on Xiaomi 2107113SG (Snapdragon 888 · Android 14) physical hardware, debug build without minify. Full methodology, R8 deltas, and per-device variability discussed in appdimens-dynamic/PERFORMANCE.md.

Operation Result Notes
Raw math, no AR ~2 ns SCALED / AUTO / FLUID / PERCENT fast-bypass path (cache is intentionally skipped — a 2 ns multiply is cheaper than the ~5 ns hash)
Raw math with AR ~45 ns ln() evaluation on hardware
Cache hit (no AR) ~5 ns Lock-free padded sharded cache lookup
Cache hit (with AR) ~35 ns Zero-math path for AR kernels
Batch resolution (100 items) ~169 ns getBatch() API, SIMD-friendly loop
Persistence load (100 entries) 0.76 ms Cold start from disk-persisted cache
JVM cache hit (local) ~1 ns Linux + JVM 17
Real-world (1 000-item Compose scroll) ~996 ms total / ~996 µs per item Indistinguishable from baseline; 0% jank at 120 FPS

With R8 + minify on release builds, the dashboard-style harness drops further (~125–155 ns micro combined, ~367–380 ns per-item macro). See the Build variants & R8 note at the top of PERFORMANCE.md.


Comparison with alternatives

The hub does not publish a single global "score / 100" ranking — comparisons depend heavily on form-factor mix, design philosophy, and what you measure. Instead, here are the honest categorical trade-offs. Quantitative kernel comparisons live in DOCS/THEORY.md §8–10.

Approach What it does well What AppDimens adds
Raw dp / sp / pt / px Zero deps, predictable on the calibrated device Calibration across canvas extent and aspect ratio, not just density
Linear SDP / SSP (e.g. Intuit sdp-android) Pre-computed @dimen resources, XML-native Same baked resources (appdimens-sdps/-ssps) plus non-linear kernels (auto, logarithmic, power, fluid) — and you can mix runtime computation in Compose
CSS vw / vh / clamp() / container queries First-class in modern browsers, no JS A single vocabulary that travels off the Web (iOS / Android / Flutter / RN) — appdimens-web integrates clamp()-style behaviour as the fluid kernel
ScreenUtil / size-matters / similar libraries Single dependency, friendly API Strategy-per-call-site instead of a single global curve; foldable + multi-window heuristics; AR compensation; reproducible math doc per kernel

If your product already standardizes on one of the rows above, keep comparing trade-offs against your form-factor mix; the fast path in GUIDE.md summarizes kernel choice in one screen.


FAQ

Which strategy should I reach for first? auto (BALANCED) for multi-device, scaled for phone-first / SDP-style, percent for axis-heavy containers. Full decision tree: DOCS/GUIDE.md "Fast path".

Will this break my existing SDP / SSP layouts? No. appdimens-sdps / appdimens-ssps ship the canonical SDP/SSP resource tables (@dimen/_16sdp, …) so existing XML keeps working. You can adopt the runtime appdimens-dynamic kernels gradually inside Compose. Migration story: DOCS/MIGRATION.md.

Does it work in pure XML layouts? Yes — appdimens-sdps and appdimens-ssps are XML-native (@dimen/_16sdp, @dimen/_18ssp, …). For runtime kernels, appdimens-dynamic exposes a code package for Views and a compose package for Compose.

Does it work inside @Preview / unit tests? Yes. Every kernel is a pure function of (base, Configuration). Compose previews resolve as on a regular device — and you can override LocalConfiguration to simulate any canvas.

Will rotation / foldables break my proportions? By design no. Effective-axis selection consults Configuration and WindowManager fold state. For authored portrait → device landscape (or vice versa), use the *Ph / *Lw / *Lh inverter tokens. See DOCS/ORIENTATION.md.

Is the cache thread-safe? Yes. It is a lock-free padded sharded cache (128-byte shards to avoid false sharing on ARM64) with bypass for the simplest no-AR multiplies. Details in appdimens-dynamic/PERFORMANCE.md.

Can I keep some sizes truly constant? Yes — use raw Dp / Sp (or .dp / .sp Compose extensions) for icons that must stay 24 dp everywhere. The conceptual NONE kernel is exactly this.

What changed since 2.x? On Compose, the old unified DSL (.fxdp, .dydp, .balanced().dp) was split into strategy packages (compose.scaled, compose.auto, compose.percent, …). Naming rename Fixed → DEFAULT, Dynamic → PERCENTAGE is purely narrative; Gradle uses scaled and percent. iOS / Flutter / RN / Web keep their builder names. Full mapping: DOCS/MIGRATION.md.


Roadmap & status

  • Production: appdimens-dynamic, appdimens-sdps, appdimens-ssps (Android).
  • 🔄 Work in progress: appdimens-ios, appdimens-dynamic-kmp (first stable aimed at 1.0.0), appdimens-flutter, appdimens-react-native, appdimens-web, appdimens-games.
  • 🧪 Hub theory: kernel taxonomy and verified constants are stable; benchmark deltas continue to track new device classes (PERFORMANCE.md).

Issues about this hub repo (typos, dead links, missing concept docs) → Hub issues. Shipping bugs (compile errors, wrong numbers, build problems) belong in the submodule repository you depend on so they reach the maintainers and CI of that artifact.


Contributing, security, license

Contributing Security Code of Conduct Changelog License

  • CONTRIBUTING.md — how to propose hub or submodule changes, doc style, PR checklist.
  • SECURITY.md — responsible disclosure channel for vulnerabilities.
  • CODE_OF_CONDUCT.md — community expectations.
  • CHANGELOG.md — high-level coordinated-release history; each submodule maintains its own detailed changelog.
  • LICENSE — Apache 2.0.

Author

Jean Bodenberg@bodenberg · appdimens-project.web.app

If AppDimens helps your project, please ⭐ this repo and the submodules you use — visibility is what funds further work.


About

Tired of screen fragmentation? AppDimens is the unified solution for responsive, pixel-perfect UI across all platforms and devices. It offers adaptive scaling (SDP, SSP, Dynamic, Fixed) for Kotlin, Compose, XML Views, Swift, and SwiftUI, ensuring layouts and fonts scale perfectly from the smallest to the largest device.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages