Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pocket-stack/pocketjs/llms.txt

Use this file to discover all available pages before exploring further.

PocketJS styles come from a build-time Tailwind subset. There is no runtime Tailwind, no CSS, and no arbitrary-utility escape hatch: a fixed set of utilities is parsed at build time by compiler/tailwind.ts and baked into styles.bin, which the Rust core reads directly. This page is the exhaustive reference for exactly which utilities exist and what values they accept.
import { View, Text } from "@pocketjs/framework/components";

function Card() {
  return (
    <View class="flex flex-col gap-2 p-4 bg-slate-800 rounded-lg">
      <Text class="text-lg font-bold text-slate-50">Hello PSP</Text>
    </View>
  );
}
For how styling fits into the build pipeline, see the Styling guide.

How a Class Literal Compiles

A candidate string is split on whitespace into tokens. Every token must parse as a supported utility for the string to become a style record.
  • If all tokens parse, the literal compiles to a styleId stored in styles.bin. The class attribute resolves to that id natively.
  • If any token is not a supported utility, the whole literal is silently ignored — it is assumed to be ordinary text. One unknown token drops the entire literal.
  • Token order does not matter. Records are canonicalized and deduped, so "p-4 flex" and "flex p-4" share one styleId.
When any single token in a class literal is unrecognized, the entire literal is silently dropped — not just the bad token. One unknown token disqualifies the whole string. Double-check spelling and consult this reference if a style is not applying.

The Spacing Scale

Most sizing and offset utilities take a value on Tailwind’s spacing scale, where N maps to N * 4 pixels. Decimals are allowed.
TokenPixels
00
14
28
312
416
624
832
1248
2.510
Arbitrary pixel values are supported for every spacing-scale utility using bracket syntax — the value is taken as literal pixels (the px suffix is optional):
<View class="w-[123] h-[123px] p-[10] gap-[6px]" />
A second group of utilities (z, opacity, scale, scale-x, scale-y, rotate, duration, delay) take a plain number instead. Those do not accept bracket syntax — only bare digits. Negative values are not supported. Any token beginning with - fails to parse.

Color Palette

Colors come from the Tailwind v3 default palette: {family}-{shade}, plus the keywords white, black, and transparent. Families: slate, gray, zinc, red, orange, amber, yellow, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose. Shades: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950.
PrefixApplies toExample
bg-{color}Background fillbg-slate-800
text-{color}Text colortext-emerald-400
border-{color}Border color (also sets a 1px border)border-slate-600
from-{color}Gradient start stopfrom-sky-500
to-{color}Gradient end stopto-blue-700
An unrecognized family or shade (e.g. bg-slate-999, text-brand-500) causes the entire literal to be ignored.

Flex

UtilityEffect
flexdisplay: flex
flex-rowMain axis = row
flex-colMain axis = column
flex-wrapAllow wrapping
flex-1grow: 1, shrink: 1, basis: 0
growflex-grow: 1
grow-0flex-grow: 0
shrink-0flex-shrink: 0
basis-NFlex basis (spacing scale)
gap-NGap between children (spacing scale or arbitrary px)
justify-start | justify-center | justify-end | justify-between | justify-aroundMain-axis distribution
items-start | items-center | items-end | items-stretchCross-axis alignment
Only the five justify-* and four items-* values above exist. justify-evenly and items-baseline are not supported.

Box & Position

UtilityEffect
w-N | w-full | w-[px]Width (spacing scale, full parent, or arbitrary px)
h-N | h-full | h-[px]Height
min-w-N, min-h-N, max-w-N, max-h-NMin/max size (spacing scale or arbitrary px)
p-N, px-N, py-N, pt-N, pr-N, pb-N, pl-NPadding (all sides, axes, or individual)
m-N, mx-N, my-N, mt-N, mr-N, mb-N, ml-NMargin
absoluteposition: absolute
relativeposition: relative
inset-N, top-N, right-N, bottom-N, left-NPosition offsets (spacing scale or arbitrary px)
hiddendisplay: none
overflow-hiddenClip children (native scissor)
z-NZ-index (plain integer)
w-full / h-full are the only percentage-style sizes — they map to the SIZE_FULL sentinel in the spec. min-* / max-* do not accept -full.

Visual

UtilityEffect
bg-{color}Background color
bg-gradient-to-t | -b | -l | -rGradient direction (top / bottom / left / right)
from-{color}Gradient start color
to-{color}Gradient end color
rounded4px corner radius
rounded-sm2px
rounded-md6px
rounded-lg8px
rounded-xl12px
rounded-fullPill/circle — build-time size required (see below)
opacity-NOpacity, N/100 (0–100)
shadowSmall shadow
shadow-mdMedium shadow
shadow-lgLarge shadow
border1px border (width only)
border-{color}Border color and a 1px border
Gradients only run along the four cardinal directions — no diagonals. Set a direction with bg-gradient-to-* and stops with from-* / to-*:
<View class="bg-gradient-to-b from-sky-500 to-blue-700 w-full h-16" />
Border width is fixed at 1px. border-2, border-4, etc. do not exist — only bare border and border-{color}.

rounded-full Requires Build-Time Size

rounded-full bakes an exact radius at build time, so it needs the node’s width and height to be build-time known in the same literal via w-N/h-N (or arbitrary-px forms). The radius becomes min(w, h) / 2:
{/* ✅ OK — radius baked to 24px */}
<View class="w-12 h-12 rounded-full bg-rose-500" />

{/* ❌ Compile error — w-full is not a build-time pixel size */}
<View class="w-full h-12 rounded-full" />
Using rounded-full without a concrete w-N and h-N is a hard compile error, not a silent drop. This is used extensively in the settings demo for the toggle knobs:
{/* From demos/settings/app.tsx — knob with build-time known size */}
<View class="w-4 h-4 rounded-full bg-white border-indigo-200 shadow-md m-[2] translate-x-[0.5]" />

Text

UtilityEffect
text-{color}Text color
text-xs12px
text-sm14px
text-base16px (default)
text-lg18px
text-xl20px
text-2xl24px
text-4xl36px
font-boldBold weight (baked bold atlas)
text-left | text-center | text-rightHorizontal alignment
leading-NLine height (spacing scale or arbitrary px)
tracking-wideLetter spacing = 0.025 × font-size
Font sizes are baked into atlases at build time — only the seven sizes above exist (12 / 14 / 16 / 18 / 20 / 24 / 36 px). There is no text-3xl, text-5xl, etc. Each size ships in two weights (regular and bold when font-bold is used). Text with no size or weight utility uses the 16px regular default. Only font-bold exists for weight — no font-normal or font-semibold. Only tracking-wide exists for letter spacing.

Transform

Transforms are animatable and do not trigger relayout — always prefer them for motion.
UtilityEffect
translate-x-NTranslate X (spacing scale or arbitrary px)
translate-y-NTranslate Y (spacing scale or arbitrary px)
scale-NUniform scale, N/100 (e.g. scale-105 → 1.05)
scale-x-NX scale, N/100
scale-y-NY scale, N/100
rotate-NRotation in degrees (e.g. rotate-45)
scale-* and rotate-* take plain numbers only (no bracket syntax, no negatives).

Motion / Transition

Adding any motion token to a literal attaches a transition block to that style record. Transitions fire when the style is swapped — for example on focus: / active: variant changes — and interpolate the animatable properties in the mask.
UtilityAnimates
transitionTransforms + colors + opacity (the default property set)
transition-allEvery animatable prop (including layout — can trigger relayout)
transition-colorsbgColor, gradFrom, gradTo, borderColor, textColor
transition-opacityopacity
transition-transformtranslateX/Y, scale, scaleX/Y, rotate
duration-NDuration in milliseconds (0–65535)
delay-NDelay in milliseconds (0–65535)
ease-linear | ease-in | ease-out | ease-in-out | ease-spring | ease-out-backEasing curve
Defaults. When a literal contains any motion token, unspecified fields fall back to: duration 150ms, delay 0ms, easing ease-in-out. A literal with duration/ease/delay but no transition-* utility behaves like transition-all. spring and out-back are PocketJS additions beyond standard Tailwind easings. spring-bouncy is imperative-only — use spring() from @pocketjs/framework/animation instead.
{/* Background fades natively on focus — Rust ticks it, zero JS per frame */}
<View class="bg-slate-700 focus:bg-slate-500 transition-colors duration-200 ease-out" />

Variants

Two state variants are supported. They compile into separate blocks of the same style record and are switched natively — no JS runs on focus or press state change.
VariantApplies when
focus:The node is the focused node
active:The node is pressed/active
<View
  class="bg-slate-700 border-slate-600
         focus:bg-slate-600 focus:border-blue-500
         active:scale-95 transition"
  focusable
/>
Any base utility can be prefixed with focus: or active:. Motion tokens (transition*, duration, delay, ease) apply to the whole record and are only recognized on the base variant — not behind focus: / active:.

Not Supported — Loud Errors

These are rejected at build/dev time rather than silently dropped:
ConstructWhy
classList={{ … }}Dynamic class objects are not supported; the renderer raises a dev error.
Template-interpolated class fragments (class={`p-${n}`})Classes must be static literals to be collected and baked at build time.
hover:The PSP has no pointer — hover: in an otherwise valid literal is a hard compile error. Use focus: / active:.
rounded-full without build-time w-N/h-NThe radius must be bakeable at build time.
For dynamic styling, use one of:
  • Ternaries of complete literalsclass={ok() ? "bg-green-600" : "bg-red-600"}.
  • style={{ … }} objects — per-key dynamic props applied at runtime.
  • animate() — imperative property animation (see Animation).

See Also

  • Styling — the styling model overview, dynamic styling patterns, and pipeline details
  • Animationtransition-*, animate(), springs, and easing names
  • ComponentsView, Text, Image, and which accept class

Build docs developers (and LLMs) love