Skip to content

Releases: foo-stack/usemotif

v1.0.1 — RTL, reduced motion, and six more fixes

18 May 08:22
0ba96a4

Choose a tag to compare

A patch release: eight fixes across the renderers, the token presets, the headless layer, and the docs. Every package ships at 1.0.1.

Merged via #19.

Added

  • RTL / bidirectional layout. A <Direction> provider and useDirection() hook on both renderers. New logical style props — ps / pe / ms / me, the start / end insets, and the paddingInline* / marginInline* / insetInline* long forms. px / mx resolve to the logical paddingInline / marginInline, so they adapt to writing direction. (#11, #16)
  • useReducedMotion(). A cross-platform hook in @usemotif/headlessmatchMedia on web, AccessibilityInfo on native. Headless components skip their enter/exit animation when the user prefers reduced motion. (#12)
  • Default borderWidths and letterSpacings token scales. The default light and dark themes ship both scales, so $borderWidths.* / $letterSpacings.* references resolve out of the box. (#13)
  • @usemotif/react/svg entry. A dedicated, tree-shakeable export for the Icon and Svg primitives. (#10)

Changed

  • Smaller icon imports. @usemotif/icons glyphs import through @usemotif/react/svg — a single-icon import drops from ~6.2 KB to ~0.6 KB gzip. No API change. (#10)
  • @usemotif/compiler-swc package description. Corrected to describe the package as it is — a universal unplugin running the Babel-based transform, not an SWC plugin. (#14)

Fixed

  • Invisible native <Heading> / <Paragraph> text. A unitless lineHeight was read as absolute pixels by React Native and clipped glyphs to nothing; it is now resolved against the font size. (#17)
  • Next.js setup docs. The bundler guide now documents the transpilePackages configuration the official example app relies on. (#15)

v1.0.0 — the @usemotif/* graduation

15 May 17:19
1f7b72b

Choose a tag to compare

motif graduates to a deliberate v1.0.0 — the full library, consolidated under
a single @usemotif/* scope.

motif spent its pre-1.0 life under the @motif-js/* scope — v0.1.0 through
an unintended early 1.0.0, then two namespace renames the migration guides
call v2 and v3. 1.0.0 is the deliberate v1, with the meta package as the
unscoped usemotif. The legacy @motif-js/* packages stay on npm, frozen,
with deprecation notices pointing at the migration guides.

The runtime, the token model, and the component API are unchanged from the
final @motif-js/* releases — 1.0.0 is a packaging and stability milestone,
not a behaviour change.

Install

yarn add usemotif @usemotif/tokens

Added

  • Styling core — style-prop API and styled() factory; two-layer token
    system (primitive palette + semantic intent); nestable <Theme> sub-themes.
  • Responsive system — container and media queries through three syntaxes
    (object, array, string DSL), with a native container-query polyfill.
  • ~50 primitives — layout, typography, media, forms, scroll, and a11y,
    cross-platform.
  • ~38 headless behaviour components — Dialog, Popover, Menu, Combobox,
    Tabs, Tooltip, ColorPicker, CommandPalette, MultiSelect, TreeView, and the
    rest — unstyled, WAI-ARIA correct, keyboard + screen-reader complete on both
    platforms.
  • Animation — mount/unmount transitions via enterStyle/exitStyle/
    transition; native timing driver + optional Reanimated spring driver.
  • Progressive compiler@usemotif/compiler-core, -babel, -swc,
    -metro. The runtime path works unchanged with no plugin installed.
  • @usemotif/icons — generator-driven, lucide-backed icon set.
  • @usemotif/reset — opt-in CSS reset that does not fight the runtime.
  • @usemotif/test-utils — cross-renderer conformance suite + Vitest matchers.
  • SSRSSRStyleCollector and a streaming style registry for Next.js.

Changed

  • Namespace consolidated to @usemotif/* — all thirteen scoped packages
    moved from @motif-js/*; the meta package stays unscoped as usemotif.
    Every package ships a fresh 1.0.0 on the new scope.

Deprecated

  • The @motif-js/* scope — existing installs keep working; new installs
    see npm deprecation notices. Run npx @usemotif/migrate rename-v3 to migrate.

Fixed

  • SWC compiler CSS delivery — emits aggregated CSS through a virtual module.
  • Workspace dependency publishingworkspace:* ranges rewrite correctly.

Docs: https://usemotif.dev · Full changelog: CHANGELOG.md

v0.3.0 — Phase D: Compiler

28 Apr 11:35
217a2bb

Choose a tag to compare

motif-js's progressive compiler ships. The runtime keeps working as before; opt-in compile-time
extraction folds static motif call sites into baked style + className + at-rule CSS, and the runtime
fast-paths the result. Compiled output is byte-identical to runtime output — half-compiled
half-runtime apps dedupe to one set of m- classes, not two.

Highlights

🔧 Four new @motif-js/compiler-* packages

  • @motif-js/compiler-core — renderer-agnostic Babel-AST classifier. Splits each motif JSX call site
    into static / partial-static / dynamic. Reuses @motif-js/core's resolver so compiler and runtime
    always agree.
  • @motif-js/compiler-babel — the canonical Babel plugin (164 LOC). Drops consumed style props, merges
    baked attrs with user-supplied ones (user values win), aggregates per-file CSS via onCss.
  • @motif-js/compiler-swc — universal unplugin@3 shim (107 LOC). One source, six bundlers: vite /
    rollup / webpack / rspack / esbuild / farm. Layers BEFORE the host's SWC pass on Next /
    @vitejs/plugin-react-swc.
  • @motif-js/compiler-metro — Metro/Expo Babel-tuple wrapper (41 LOC). Drops into babel.config.js's
    plugins array.

⚡ 1.73× faster on render-heavy paths (200-Box bench, server-side render with cold style cache):

┌─────────────────────────────────────────────────┬───────┬─────────┬──────────────┐
│ variant │ hz │ mean │ speedup │
├─────────────────────────────────────────────────┼───────┼─────────┼──────────────┤
│ runtime — │ 1,096 │ 0.91 ms │ 1.00× │
├─────────────────────────────────────────────────┼───────┼─────────┼──────────────┤
│ compiled — post-plugin shape │ 1,895 │ 0.53 ms │ 1.73× faster │
├─────────────────────────────────────────────────┼───────┼─────────┼──────────────┤
│ vanilla

(floor) │ 2,303 │ 0.43 ms │ 2.10× faster │
└─────────────────────────────────────────────────┴───────┴─────────┴──────────────┘

Compiled closes 80% of the runtime → vanilla gap. The original 5–10× target retires — actual
measurement is the source of truth.

🚀 Box runtime fast-path. After the compiler strips static style props, early-returns a plain

Try it

yarn add @motif-js/compiler-swc -D

// vite.config.ts
import motif from '@motif-js/compiler-swc';
import react from '@vitejs/plugin-react-swc';

export default {
plugins: [motif.vite(), react()],
};

That's it — every whose props are compile-time literals turns
into pre-baked style + className. Dynamic props stay at runtime untouched.

What's not in this release

  • Wrapper-stripping for fully-static cases (replacing with
    in compiled output) — open
    lever to push perf higher in a later release.
  • Pseudo-state extraction (_hover / _focus / _active) on Pressable — 3 differential cases skip these
    today.
  • Native StyleSheet.create({...}) hoisting in compiler-metro — the native target is currently a
    Babel-side no-op while the runtime keeps resolving. Future minor.
  • Cross-library bench comparisons (Tamagui, NativeWind, Stitches) — legitimacy data, not a release
    gate.

What's next

Phase E: primitives buildout. Filling out the components roster (forms, layout primitives, surfaces)
on the foundation Phases A–D laid down.

Full changelog

v0.2.0...v0.3.0

v0.2.0 — Phase C native parity

28 Apr 08:13
915fe51

Choose a tag to compare

Phase C — Native parity

@motif-js/react-native reaches feature parity with the web renderer. Same prop schema, same theming
model, same responsive shapes, same container-query semantics — running on RN's StyleSheet, with
theming via JS context, and container queries polyfilled via View.onLayout.

The cross-renderer conformance suite (@motif-js/test-utils's standardCases) passes 18/18
against both renderers' adapters. "Same input → same resolved values" holds across the two trees.

Install

yarn add @motif-js/react-native @motif-js/tokens
# also works:                                                                                        
# npm install @motif-js/react-native @motif-js/tokens
# pnpm add @motif-js/react-native @motif-js/tokens                                                   

What's in

  • Native primitivesBox, Stack / HStack / VStack, Text, Pressable, Image,
    Container. Same prop schema as @motif-js/react-web; literal-mode style resolution (no CSS
    variables on RN).
  • ThemingThemeProvider, <Theme name> boundary, useTheme / useThemeName hooks.
    JS-context based — theme switches re-render consumers.
  • Viewport-driven responsive resolution — every responsive shape (object / array / DSL) resolves
    against the current viewport width via Dimensions.addEventListener('change', …). Re-renders on
    rotation / split-screen / window resize.
  • Container-query polyfill<Container name?> measures itself via View.onLayout, exposes
    width via React context. @<bp> / @<name>.<bp> keys resolve against the matching container's
    width. rateCapMs prop tunes re-measure throttle (default 16ms = 1 frame at 60fps; opt out with
    0).
  • Cross-renderer conformance — native ships its own RendererAdapter; the same standardCases
    from @motif-js/test-utils run against both adapters. Web 18/18, native 18/18.
  • Expo demo appapps/playground-native (in the repo, not published) exercises the full
    surface end-to-end.

What's not in

  • Visual regression (Detox + Playwright) — deferred to v0.8+.
  • Bare RN demo app — Expo Router demo covers the same surface.
  • Compiler (Phase D) — still placeholder stubs.

Workspace stats

  • 341 vitest tests pass (103 core + 99 react-web + 88 react-native + 20 tokens + 31 utils)
  • 19/19 packages build clean
  • 23/23 typecheck clean
  • 0 lint errors
  • All 16 publishable packages bumped from 0.1.00.2.0

Phase C ROADMAP at release

  • ✅ All @motif-js/react-native engineering boxes
  • ✅ Container query polyfill (onLayout + context + rate cap)
  • ✅ Conformance suite running both renderers (zero divergences)
  • ✅ Snapshot tests across primitives (web + native)
  • ✅ Expo Router demo (typechecks + bundles cleanly via Metro; runs on iOS / Android / web)
  • 🟦 Visual regression / on-device benchmarks — deferred to v0.8+

Full changelog: v0.1.0...v0.2.0