Components

Headless primitives and utilities you can add to a project as a dependency or copy in as source - behaviour, timing and accessibility, with no styles of their own.

Interaction logic is behaviour, and behaviour that has already been measured and tested belongs in a package, not in a snippet an agent rewrites on every screen. Two packages hold it:

  • @enigmax/primitives - interaction behaviour: timing, pointer handling, accessibility. No visual styles.
  • @enigmax/utils - what renders nothing: a short-TTL read cache, and a breached-password check.

Beside them, @enigmax/icons holds the glyphs: one module per icon, so a bundle carries only what it renders.

Both are plain npm packages. Nothing about them requires enigma - enigma add is a convenience that also lets an agent discover what exists.

marquee
Claude CodeCodexopencodeKimi CodeMCPGuardrailsRecallDashboard

Every preview on these pages is a real instance of the published package. Grab this one and throw it.

Installation

Adds the package and prints the import to use. This is the way to use them: the package keeps getting fixes, and a dependency is how they reach you.

enigma add --all

Installs with your project's own package manager - npm, pnpm, yarn or bun - read from its packageManager field or its lockfile.

--copy writes the source into your project instead. Reach for it to EDIT a component, not to use one: a copy is frozen at today's version and stops receiving fixes.

The enigma tab adds the package and prints the import to use. The copy tab writes the source into your project instead, so it is yours to edit - the same choice shadcn made, applied to behaviour rather than markup.

--dest <dir> chooses where copies land (default src/lib/enigma, or lib/enigma when the project has no src). --target overrides the detected framework. --dry-run reports without writing.

Copy mode rewrites the internal import specifiers to relative ones, so the copied files stand alone. It refuses to run when the package source is not on disk rather than inventing it.

Which framework

The core of every primitive is framework-agnostic TypeScript with no dependencies, so vanilla JS and Astro work today through the main entry - this page is Astro, and the demo above is the vanilla entry. React has a thin adapter. Vue, Svelte and TanStack adapters are not written yet; they will reuse the same core rather than reimplement it.

Target Entry Marquee export
Vanilla, Astro @enigmax/primitives createMarquee
React @enigmax/primitives/react useMarquee

Styling: Tailwind by default, CSS on request

The primitives themselves ship no styles and never will. Utility classes inside the engine would break every project without Tailwind and tie a behaviour package to a CSS framework’s major version; being styleless is what makes them work in any design.

The styling lives one layer up, in recipes - complete styled components, not fragments - that reach your project through enigma add --copy:

what --copy writes
enigma add marquee --copy --style tailwind
# lib/enigma/marquee/marquee.ts      the headless engine
# lib/enigma/marquee/use-marquee.ts  the React hook
# lib/enigma/marquee/Marquee.tsx     a styled component, utility classes, yours to edit

You do not have to pass --style. The default is read from your project: tailwindcss, @tailwindcss/vite or @tailwindcss/postcss in the manifest means Tailwind, anything else means plain CSS. Writing utility classes into a project without Tailwind would produce a component styled by nothing, which is worse than the CSS variant - so “Tailwind by default” means “where Tailwind is”.

--style none copies the headless files only. And cache has no recipe on purpose: it renders nothing, so there is nothing to style.

A Tailwind v4 trap worth knowing

Tailwind v4 writes translate-* to the CSS translate property, which composes with transform rather than replacing it. The marquee drives the track’s transform every frame, so a translate-x-* utility on that element does not override it - the two add up and the row drifts. Offset the lane or an inner element instead, never the moved one. Both marquee recipes carry that warning at the top of the file.

They ship no styles

A primitive applies only what its behaviour requires - overflow, touch-action, user-select, will-change, transform - and never anything that is a look. State is published as data attributes, so the styling stays entirely yours:

[data-enigma-marquee]                 { cursor: grab; }
[data-enigma-marquee][data-dragging]  { cursor: grabbing; }
[data-enigma-marquee][data-hovering]  { --logo-opacity: 1; }
[data-enigma-marquee-track]           { display: flex; }

Pass manageStyles: false to take even the functional styles back.

A themes package that styles these hooks for you is planned; the attributes are already stable, so anything you write against them now keeps working.

The catalogue an agent reads is the one you installed

enigma add looks for the registry inside the package installed in your project first, and only falls back to the copy bundled with the CLI. So an agent is shown the API your project actually compiles against, instead of a catalogue frozen into a skill that drifts the first time you upgrade.

In this section

  • Marquee - draggable infinite row: logo walls, testimonial strips, pill rails.
  • Cache - short-TTL read cache with in-flight deduplication.
  • Safe fetch - fetch a URL someone else chose without reaching your own network.
  • Safe upload - accept a file by its bytes, store it under a random name, serve it without running it.
  • Notifications - queue, dedupe and dismiss timers that hold when the tab is hidden.
  • Context menu - the right-click menu: submenus, shortcuts, a filter when a level is long, rows fetched on demand.
  • Image - a picture that opens into a viewer: press to enlarge, wheel to zoom, with the gallery arrows, previews, download menu and discard action off until asked for.
  • Video - a player shaped after Plyr, with the element as the source of truth and the platform’s own shortcuts.
  • Selection list - the file-manager selection model, with every shortcut rebindable or removable.
  • Icons - the icon set, searchable by name and category, one module per glyph.