Skip to contentAsheeUIAsheeUI

The latest release

The versions in the current release, what changed in the newest one, and what upgrading costs.

Package Version Install
asheeui 2.4.0 pnpm add asheeui
@asheeui/web 2.5.0 pnpm add @asheeui/web
@asheeui/core 2.4.0 pnpm add @asheeui/core
@asheeui/native 2.6.0 pnpm add @asheeui/native
@asheeui/puck 2.3.0 pnpm add @asheeui/puck
@asheeui/cli 1.0.0 pnpm dlx @asheeui/cli

The packages version independently, so the umbrella package can trail the renderers. Take the version you need from this table rather than assuming one number covers the set. asheeui states its renderer dependencies as ranges, so it usually resolves to the versions above without a release of its own; this release is the exception, because the umbrella publishes a new subpath.

What changed in this release

A native screen is styled again

A screen built from @asheeui/native rendered with no style whatsoever in a correctly configured application: the right copy, the right structure, no page padding, no card surface, no border, no type scale, and the status bar over the first heading. Nothing threw, and nothing warned.

The cause was the published artifact rather than the application. dist was compiled with TypeScript's default JSX runtime, react/jsx-runtime, and NativeWind does not read className at runtime: its Babel transform rewrites JSX, and a compiled module contains neither JSX nor React.createElement, so there was nothing left for a consumer's Babel to rewrite. The className stayed a plain prop on a View and React Native ignored it. The build states jsxImportSource: "nativewind" now, so a component's class reaches the runtime that turns it into a style, and pnpm check:native-artifact fails the build if the artifact ever emits through React's runtime again. The native test suite cannot make that assertion — it compiles the package's sources, which contain JSX — which is why nothing caught this before 2.5.0 shipped.

The build also cleans dist before it compiles. The published 2.5.0 tarball carried 176 stale modules from the pre-2.3.1 folder layout, a second copy of every component, 62 of them emitting through React's runtime as well. See React Native.

The renderer ships its Tailwind preset

The native setup used to ask for three things by hand, and two of them could not be written correctly without knowing how your package manager lays out node_modules. @asheeui/native/tailwind-preset states them once: NativeWind's own preset, the eight colour roles at the framework's light palette — yours win where theme.extend.colors states them — and the framework's own compiled modules as absolute globs, so the classes compile wherever the package was installed. The preset's content is exported as well as declared, because Tailwind v3 does not merge a preset's content into a configuration that states its own.

asheeui/tailwind-preset re-exports it for an application that installed the umbrella, and @asheeui/native/package.json is exported for the tooling that reads a manifest to discover a version. The published entry points are the root, ./section-kit and ./tailwind-preset; there are no per-component subpaths. See Setup.

The device paints the configuration's palette

The native provider accepted the configuration's axes and component sections but not its palette, so one configuration object could not describe both renderers: the web host stated color and defaultTheme, and the device had to copy the eight roles into its Tailwind configuration, where the copy could drift. That is closed. AsheeUIProvider accepts color and defaultTheme, and paints them.

The mechanism is the one the web already uses, in the platform's own vocabulary. Each role compiles to rgb(var(--ashee-<role>) / <alpha-value>) — the class names the theme, not a colour — and the provider resolves the palettes with @asheeui/core (which now exports resolveColorConfig beside PALETTE_ROLES, colorChannels, paletteVariables and selectTheme) and applies the eight properties with NativeWind's vars(). defaultTheme: "system" follows the device's colour scheme, so a phone in dark mode paints the dark palette; a custom theme declared under color works on both renderers.

Two consequences are stated rather than discovered. A role is opaque and must be readable as channels (hex, #rgb/#rgba or rgb()/rgba()), so an unreadable colour is an error naming the role rather than a surface that paints nothing; and a role stated as a colour in tailwind.config.js replaces the preset's expression, which fixes it at build time and stops it following the theme.

One root, one configuration type

@asheeui/native exports AsheeUIProvider, useAsheeConfig and AsheeUIProviderProps beside its platform names, and the device's configuration is the web renderer's own: NativeExternalConfig extends ExternalConfig — the type @asheeui/web takes — and adds only what this platform owns, defaultSize and the component sections the web package declares in its own files (card, typography, container, the field family and the layout ones). A configuration object typed ExternalConfig is therefore accepted unchanged, and asheeui exports AsheeConfig from each branch for a file that names the routed type instead.

The sections both renderers read keep one type in @asheeui/core; a section is declared by each renderer only where the platforms differ (Calendar floats a panel on the web and shows one surface on a device), which is why the device's package adds those sections to the shared type rather than the core declaring them.

Platform questions answer on both renderers

A shared component sometimes has to choose between two arrangements rather than style one, and a media query cannot make that choice: it decides which elements exist. useBreakpoint() is the value that can, and both renderers now export it under one name with one shape — width, breakpoint (the largest name reached, or base) and isAtLeast — over @asheeui/core's breakpoints, so md is 768 on both. The platform reads its window; the web measures after mount, which keeps server-rendered markup and hydration in agreement. resolveBreakpoint and BreakpointState are exported from the core for a component that measures its own container, and useReduceMotion() is the reader's motion preference under the same one-name rule.

A broken styling pipeline says so

Every failure in this area looks the same from the inside, which is what made it expensive to diagnose. The provider now checks once in development: the interop runtime is probed with its own handshake, and then NativeWind's verifyInstallation() is asked whether the Babel transform, the compiled stylesheet data and its preset are in place. A broken pipeline produces one warning naming the cause it found; a working one produces nothing. verifyNativeWind() returns the same diagnosis as data, for a test or a script.

The setup page now lists the five causes in the order they are worth checking — an unimported stylesheet, missing framework globs, a react-native-css-interop pin that disagrees with the copy NativeWind brings, a role stated as a colour where the theme should be, and the runtime above — and records the rule that made the last one invisible.

The package's own toolchain compiles what your application compiles

The native package's tailwindcss devDependency was v4, which NativeWind v4 cannot compile with: the preset could not even be loaded in this repository, so the setup the documentation described was unstateable here. It is v3.4 now, the line the documentation and a consumer install.

Upgrading

No breaking change. @asheeui/native 2.6.0 is additive apart from the fix.

  • If you worked around the defect with a Metro resolver alias for react/jsx-runtime, delete the alias. The artifact imports nativewind/jsx-runtime itself now, so the alias has nothing left to redirect.
  • If you hand-wrote the eight roles and the framework's globs into tailwind.config.js, replace the roles with the configuration's color: the preset states them as the properties the provider paints, so a hex there is a build-time palette that no longer follows defaultTheme. The content array still needs ...asheeui.content, because Tailwind v3 takes the application's list rather than the preset's.
  • If you pinned react-native-css-interop yourself, match the version NativeWind ships. A mismatch compiles, bundles and silently applies nothing.
  • The provider now claims the height it is given, so it belongs at the root of the tree — where the documentation already put it. AsheeNativeProvider keeps working; AsheeUIProvider is the same component under the umbrella's name.

asheeui 2.4.0 adds asheeui/tailwind-preset, asheeui/package.json and AsheeConfig; @asheeui/core 2.4.0 publishes the palette reader the device now uses. @asheeui/web, @asheeui/puck and @asheeui/cli are unchanged by this release. The migration guide records every breaking change the 2.x line has had.

What is not in this release

  • Per-component subpaths. A consumer wanting one component still imports the root, and a bundle shrinks by tree shaking rather than by an import path. The published entry points are documented rather than expanded.
  • The interop pairing is documented rather than enforced. react-native-css-interop is not declared as an optional peer, because package managers do not reliably report an optional peer range and the package never imports it. The runtime check reports the symptom, and the setup page names the rule.
  • The native suite still cannot see the artifact. The guard is a script that reads dist, run in CI, the distribution workflow and the release path, rather than a test in the suite.

The 2.6.0 release is recorded as it shipped below, with the 2.5.0 notes after it, and the older ones as 2.0.0, 1.1.0 and 1.0.0.

Previous release: 2.5.0

  • Sidebar publishes its collapse state through useSidebarCollapse() and no longer draws a collapse control of its own. showCollapseButton is gone from the contract, which is a breaking change; the footer slot renders in both states, so a control in it stays reachable.
  • href and link make a Button an anchor, and no-underline is part of the button's base classes, so a page that styles its links no longer draws a rule through the label.
  • Dropdown is exported beside Dropmenu: one component, one set of props, one components.dropmenu configuration section.
  • The README, the contributing guide and the published @see links name www.asheeui.com rather than docs.asheeui.com, a host that never resolved.

Previous release: 2.4.0

  • Link accepts to alongside href, so a substituted router component receives the destination naming it uses; without a component, to becomes the anchor's href.
  • The scrollbar gutter is reserved on html rather than on *, so an overflow: hidden box such as an Avatar's circle is no longer clipped by it.
  • Solid fills use the on-solid ink token instead of text-white, which was white on white for the background and secondary fills.
  • Every band states the heading level it renders, and the configuration types admit only the values each band accepts. @asheeui/native carries the same correction with its keyboard, overlay and tooltip fixes.
  • Overlays are dismissible by design: Escape, a backdrop press and a close control are part of the overlay, and one overlay no longer closes another.
  • The on-screen keyboard's row starts are bounded, and the styling conventions are checked by a test rather than left to review.
  • The web renderer's behaviour matches its documentation, accessibility included.
  • @asheeui/web compiles under exactOptionalPropertyTypes and noUncheckedIndexedAccess. This changes the published declarations: an optional prop accepts an explicit undefined, and an indexed read is typed as possibly missing.
  • @asheeui/cli 1.0.0 removes the playground command; everything else the CLI does is unchanged.

Previous release: 2.3.1

  • The component folders are grouped under category folders in @asheeui/core, @asheeui/web and @asheeui/native. The public export surface is unchanged, and @asheeui/web/section-kit keeps its path. asheeui list follows the new arrangement.
  • A provider mounted below the application's own no longer breaks its themes: the available list only grows, and the theme stylesheet is built from the union of every registration rather than written once by whichever provider mounted first.
  • The stylesheet generates the classes the components use, including the ones that live only in the style maps under @asheeui/core.