Core
Configuration, initialization, and shared utilities for the Vitus Labs UI System.
@vitus-labs/core is the foundational package that bridges all other packages with a pluggable CSS-in-JS engine. It provides the init() function for engine configuration, a singleton config object with lazy delegation, a dual-layer Provider, utility functions, and TypeScript types used across the ecosystem.
Installation
npm install @vitus-labs/corePeer dependencies: react >= 19, react-dom >= 19
Initialization
The init() function connects a CSS-in-JS engine to the entire UI system. Call it once at your app entry point before any component renders.
import { init } from '@vitus-labs/core'
import connector from '@vitus-labs/connector-styler'
init({
...connector,
component: 'div', // default HTML element for elements/rocketstyle
textComponent: 'span', // default text element
})init() Signature
init(props: InitConfig): voidWhere InitConfig is:
type InitConfig = Partial<CSSEngineConnector & {
component: ComponentType | HTMLTags
textComponent: ComponentType | HTMLTags
}>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
css | (strings: TemplateStringsArray, ...values: any[]) => any | Yes | Tagged template for CSS fragments |
styled | (tag: any, options?: any) => (strings: TemplateStringsArray, ...values: any[]) => any | Yes | Component factory for styled elements |
provider | FC<{ theme: any; children: ReactNode }> | Yes | ThemeProvider component |
keyframes | (strings: TemplateStringsArray, ...values: any[]) => any | No | @keyframes animation factory |
createGlobalStyle | (strings: TemplateStringsArray, ...values: any[]) => any | No | Global CSS injection factory |
useTheme | () => any | No | Hook to read the current theme |
component | ComponentType | HTMLTags | No | Default component type (default: 'div') |
textComponent | ComponentType | HTMLTags | No | Default text element type (default: 'span') |
Behavior
- Only updates provided fields — omitted fields remain unchanged
- Safe to call multiple times — useful for engine swapping or updating platform defaults
- Synchronous and immediate — all updates take effect before the function returns
- Stable delegates — the
config.cssandconfig.styledfunctions remain the same reference afterinit(). Only their internal engine references are updated.
Error Handling
If css() or styled() are called before an engine is set, they throw:
[@vitus-labs/core] CSS engine not configured. Call init() with a connector before rendering.
import { init } from '@vitus-labs/core'
import * as connector from '@vitus-labs/connector-styler'
init(connector)This error only occurs at render time, not at module load time, because the delegates use lazy resolution.
Config Singleton
The config object uses a lazy delegate pattern that allows safe destructuring at module level, even before init() is called:
import { config } from '@vitus-labs/core'
// Safe — delegates resolve lazily at render time
const { css, styled } = config
const highlight = css`
color: red;
font-weight: bold;
`
const Box = styled.div`
padding: 16px;
${highlight}
`How Lazy Delegation Works
config.css — Stable Delegate with Thunk Pattern
The css property is a stable function reference that behaves differently depending on whether the engine has been initialized:
- Engine available (after
init()): Delegates immediately to the engine'scss()function and returns the result. - Engine not available (before
init()): Returns a thunk (zero-argument function) that resolves the CSS at render time.
// Before init() — returns a thunk
const styles = css`color: red;`
// typeof styles === 'function'
// All CSS-in-JS engines treat functions as interpolations,
// so the thunk is transparently resolved when used:
const Box = styled.div`
${styles} // thunk is called during render, engine resolves CSS
`This is why module-level css calls work before init() — the thunk defers engine invocation until render time, when the engine is guaranteed to be available.
config.styled — Lazy Proxy Factory
The styled property uses a Proxy to support both call syntax and property access:
// Both syntaxes supported:
const Box = styled('div')`padding: 16px;`
const Box = styled.div`padding: 16px;`Dual-path architecture:
- Fast path (engine already initialized): Creates the styled component immediately at definition time.
- Lazy path (engine not yet initialized): Returns a
forwardRefwrapper that defers component creation to first render.
// Lazy component lifecycle:
const Box = styled.div`padding: 16px;`
// → Box is a forwardRef wrapper (engine not available yet)
init(connector)
// → Engine is now set
<Box />
// → First render: creates real styled component from engine
// → Subsequent renders: reuses cached real componentThe lazy components properly forward refs and preserve all props.
Properties
| Property | Type | Description |
|---|---|---|
css | Stable delegate | Tagged template for CSS. Returns a thunk if engine not yet initialized. |
styled | Proxy delegate | Component factory. Supports styled('div') and styled.div syntax. |
component | string | ComponentType | Default component type ('div' unless changed via init()) |
textComponent | string | ComponentType | Default text element type ('span' unless changed) |
ExternalProvider | FC | null | Read-only getter. The engine's ThemeProvider. |
keyframes | Function | null | Read-only getter. @keyframes factory. |
createGlobalStyle | Function | null | Read-only getter. Global CSS factory. |
useTheme | Function | null | Read-only getter. Theme hook. |
Provider
A dual-layer theme provider that wraps children with both the internal Vitus Labs context and the external CSS-in-JS engine's ThemeProvider.
import { Provider } from '@vitus-labs/core'
<Provider
theme={{
rootSize: 16,
breakpoints: { xs: 0, sm: 640, md: 1024, lg: 1280 },
colors: { primary: '#0d6efd' },
}}
>
<App />
</Provider>Props
| Prop | Type | Description |
|---|---|---|
theme | { rootSize?: number; breakpoints?: Record<string, number>; [key: string]: any } | Theme object passed to both contexts |
children | ReactNode | Child elements |
...props | Record<string, any> | Extra props merged into the internal context value |
Conditional Rendering
The Provider optimizes rendering based on what's configured:
| Theme | ExternalProvider | Result |
|---|---|---|
| Empty/null/undefined | — | Children rendered directly, no wrapper |
| Present | Configured | Children wrapped with both internal context + engine ThemeProvider |
| Present | Not configured | Children wrapped with internal context only |
Stability
The Provider uses useStableValue() internally to memoize the context value { theme, ...props }. This prevents unnecessary re-renders in consumers when the theme object has the same content but a different reference (e.g., from parent re-renders with inline objects).
The ExternalProvider reference is cached via useMemo(() => config.ExternalProvider, []) — looked up once on mount.
Context
The internal React context is exported for advanced use cases:
import { context } from '@vitus-labs/core'
// Read the current context value
const value = useContext(context)
// → { theme: { rootSize: 16, ... }, ...extraProviderProps }The context is created with createContext<any>({}) — its initial value is an empty object. The shape of the context value is { theme, ...extraProps } where extraProps are any additional props passed to the Provider.
CSSEngineConnector Interface
Every connector package must satisfy this interface:
interface CSSEngineConnector {
// Required
css: (strings: TemplateStringsArray, ...values: any[]) => any
styled: ((tag: any, options?: any) => (strings: TemplateStringsArray, ...values: any[]) => any)
& Record<string, any>
provider: FC<{ theme: any; children: ReactNode }>
// Optional
keyframes?: (strings: TemplateStringsArray, ...values: any[]) => any
createGlobalStyle?: (strings: TemplateStringsArray, ...values: any[]) => any
useTheme?: () => any
}Three official connectors are available:
| Connector | Package | Size | Notes |
|---|---|---|---|
| Styler | @vitus-labs/connector-styler | ~3KB gzip | Custom lightweight engine, recommended |
| Emotion | @vitus-labs/connector-emotion | Wraps @emotion | Adapter matching styled-components composition |
| styled-components | @vitus-labs/connector-styled-components | Wraps SC | Direct pass-through |
Only CSS-in-JS libraries supporting styled-components-style composition (CSS-in-CSS nesting via css tagged templates) are fully compatible.
HTML Utilities
import { HTML_TAGS, HTML_TEXT_TAGS } from '@vitus-labs/core'HTML_TAGS
An array of 102 standard HTML tag names as a const tuple:
const HTML_TAGS = ['a', 'abbr', 'address', ..., 'video', 'wbr'] as const
type HTMLTags = (typeof HTML_TAGS)[number]
// → 'a' | 'abbr' | 'address' | ... | 'video' | 'wbr'HTML_TEXT_TAGS
A subset of 37 text-level semantic tags for elements that semantically contain text:
const HTML_TEXT_TAGS = ['abbr', 'b', 'bdi', 'bdo', 'big', 'blockquote', 'cite', 'code',
'del', 'div', 'dl', 'dt', 'em', 'figcaption', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
'i', 'ins', 'kbd', 'label', 'legend', 'li', 'p', 'pre', 'q', 'rp', 'rt', 's',
'small', 'span', 'strong', 'sub', 'summary', 'sup', 'time', 'u'] as const
type HTMLTextTags = (typeof HTML_TEXT_TAGS)[number]HTMLElementAttrs
Maps each HTML tag name to its full React props type:
type HTMLTagAttrsByTag<T extends HTMLTags> = HTMLElementAttrs[T]
// Usage:
type DivProps = HTMLTagAttrsByTag<'div'>
// → React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
type InputProps = HTMLTagAttrsByTag<'input'>
// → React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
type SVGProps = HTMLTagAttrsByTag<'svg'>
// → React.SVGProps<SVGSVGElement>This mapping covers all 102 tags with proper element-specific attribute types (e.g., input gets InputHTMLAttributes, form gets FormHTMLAttributes, svg gets SVGProps).
All Exports
Values
| Export | Type | Description |
|---|---|---|
init | Function | Initialize CSS-in-JS engine |
config | Configuration | Singleton with css, styled, etc. |
Provider | Component | Dual-layer theme provider |
context | React Context | Internal context object |
omit | Function | Exclude keys from object |
pick | Function | Include only specified keys |
get | Function | Get nested value by path |
set | Function | Set nested value by path (mutates) |
merge | Function | Deep merge objects (mutates target) |
throttle | Function | Limit function execution rate |
compose | Function | Right-to-left function composition |
isEmpty | Function | Type-safe emptiness check |
isEqual | Function | Deep equality check |
render | Function | Flexible React element renderer |
useStableValue | Hook | Stabilize value reference via deep equality |
hoistNonReactStatics | Function | Copy static properties between components |
HTML_TAGS | string[] | All 102 HTML tag names |
HTML_TEXT_TAGS | string[] | 37 text-level semantic tags |
Types
| Export | Description |
|---|---|
CSSEngineConnector | Interface for CSS-in-JS engine connectors |
Breakpoints | Record<string, number> — breakpoint name → pixel value |
BreakpointKeys | keyof Breakpoints — union of breakpoint names |
HTMLTags | Union of all 102 HTML tag names |
HTMLTextTags | Union of 37 text semantic tags |
HTMLElementAttrs | Maps tag names to React prop types |
HTMLTagAttrsByTag<T> | Generic helper to look up attrs for a tag |
IsEmpty | Return type of isEmpty() with conditional narrowing |
Render | Type of render() function |
API Reference
CSSEngineConnector
Prop
Type