Architecture (consumer view)

Sometic is a portable application behavior system: shared controllers for UI, forms, auth, HTTP, query (server state), and document head, with thin framework adapters and your styling system. It is not a visual component library that owns your look and feel.

Product promise: one behavior model, every supported JavaScript stack, your design system.

Mental model

Think in four layers. Dependencies flow one way only: adapters and integrations depend on features; features depend on foundation; foundation never imports frameworks or apps.

text
Consumer app


Framework adapters (react, vue, elements, …)


Feature packages (forms, auth, http, query, theme, dom, …)


Foundation (core, events, store, styling, accessibility, date-core)

Optional peers (auth providers, date libraries, Immer) sit beside features. They never become hard dependencies of foundation packages.

What ships where

LayerExamplesYou install when…
Foundation@sometic/core, events, store, styling, accessibilityYou need shared contracts, state, or styling hooks
Featurestheme, validation, forms, auth, http, query, head, domYou need product behavior (forms, sessions, fetches, SEO)
Integrationselements, auth-local, date-native, …You want custom elements or a concrete provider
Adaptersreact, vue, Wave B/C packagesYou bind engines to a UI framework
Toolingcli, registryYou scaffold or add templates

Prefer subpath imports (@sometic/react/button) so unused surfaces stay out of the bundle. See Tree shaking.

Component pattern

Every interactive family follows the same shape:

  1. Behavior engine (framework-independent): state, events, a11y attributes, slots contract.
  2. Styling resolution: classes, styles, CSS variables, stable data-* state attributes.
  3. Framework adapter: thin props, refs, slots, and lifecycle binding.
  4. Optional theme: tokens and CSS variables when you opt in; never required.

Adapters must not reimplement business logic. If React and Vue diverge in behavior, that is a bug.

Runtime guarantees

SSR-safe imports: packages do not read window, document, localStorage, matchMedia, or customElements at import time. Create controllers and register elements in browser or effect code.

Explicit state: no hidden module-level singletons for app state. You create stores, forms, and auth clients; you dispose them when done.

Native semantics first: real <button>, <input>, <form>, focus, keyboard, autofill, and labels stay primary. High-level events exist only where native events are insufficient.

Multi-root safe: multiple app roots on one page can each own their own store, theme controller, and auth client.

Auth, HTTP, and Query

text
UI / route guards (UX only)

auth core (session, refresh coordination, capabilities)

http client (interceptors, queue-after-refresh)

query client (keys, cache, invalidate / optimistic mutate)

UI adapters (React / Vue / Vanilla observers)

Transport and 401 refresh live on HTTP + auth. Provider adapters (auth-local, Firebase, Supabase, OIDC) plug into auth core — they never become HTTP or query dependencies. Server data stays in @sometic/query, not @sometic/store. After re-auth, invalidate or refetch active queries. Your backend remains the authorization enforcement boundary. See Authentication, HTTP, and Query.

Delivery surfaces

SurfaceRole
npm packages (@sometic/*)Maintained logic, types, updates
CLI + registryExplicit init / add (no interactive postinstall)
Docs siteConsumer guides and maturity labels

Stability honesty

Public beta labels live on Beta maturity. In short:

  • Beta: Wave A foundations, forms, auth, HTTP, query, React, Vue, Elements, CLI.
  • Experimental: Wave B (Angular, Svelte, Solid, Preact) and Wave C (Alpine, jQuery, HTMX) contracts.
  • Deferred: later-phase catalogs such as multi-select polish, date/time picker UI, command palette, and data tables. Menu, Combobox, Drawer, Tabs, and related launch surfaces ship in this beta — see What’s included.

When to use Sometic

Use when you want one behavior model across React, Vue, and vanilla/custom elements, with your own CSS system and optional tokens.

Do not use when you need a full design-system skin out of the box, or when you only need a single framework-specific widget with no shared engine.

FAQ

Why engines separate from adapters? So behavior is tested once and frameworks stay thin. Fixing a focus-trap or validation race in the engine benefits every adapter.

Why not ship Tailwind or Bootstrap inside cores? Styling must stay consumer-owned. Pass class names; optionally supply a merge function. See Styling slots.

Where do I start? Install the engine you need plus one adapter. Example path: @sometic/forms + @sometic/react/form, or @sometic/dom + @sometic/elements.

Are packages independently versioned? Yes, via Changesets. Coordinated bumps happen when cross-package APIs move together. See Releases.