nocss-react
v0.1.1
Published
React components for building type-safe layouts without CSS
Maintainers
Readme
@no-css/react
React bindings for the @no-css/core runtime. The adapter turns Elm UI layout trees
into idiomatic React components so product teams can adopt the TypeScript port without
rebuilding design tokens or runtime guarantees.
Quick Start
Install the pre-release packages alongside React 18:
npm install @no-css/core@beta @no-css/react@beta react@^18.2.0 react-dom@^18.2.0Build an Element tree and render it through the adapter:
import { createElementTree } from '@no-css/core'; import { ElementProvider, ElementTree, Row, Column, Text } from '@no-css/react'; const tree = createElementTree('column', {}, [ createElementTree('text', { textContent: 'Hello from core' }), ]); export function App() { return ( <ElementProvider tree={tree}> <ElementTree /> </ElementProvider> ); }For component-first usage, compose directly with the layout primitives:
import { Row, Column, Text } from '@no-css/react'; export function LayoutExample() { return ( <Row left spacing={[12, 8]} padding={[8, 12]}> <Column top> <Text>Actual text</Text> </Column> <Column> <Text>Another column</Text> </Column> </Row> ); }
Rendering Environments
Client-Side Rendering (CSR)
The adapter works out-of-the-box in any browser environment. Simply import and use the components:
import { createRoot } from 'react-dom/client';
import { Row, Column, Text } from '@no-css/react';
function App() {
return (
<Row left spacing={[12, 8]} padding={[8, 12]}>
<Column top>
<Text>Client-side rendered content</Text>
</Column>
</Row>
);
}
const container = document.getElementById('root');
createRoot(container).render(<App />);CSR Features:
- Dynamic style injection into
<head>via the Style Bundle Manager - Automatic class name generation matching Elm semantics
- Full React hooks support (
useElementTree,useStyleSheetBundle) - Hot module replacement during development
Server-Side Rendering (SSR)
For SSR environments (Next.js, Remix, etc.), use the provided SSR utilities to extract styles:
import { renderToString } from 'react-dom/server';
import { extractStyles } from '@no-css/react/ssr';
import { Row, Column, Text } from '@no-css/react';
function App() {
return (
<Row left spacing={[12, 8]}>
<Column><Text>Server-rendered content</Text></Column>
</Row>
);
}
// Server-side: Extract critical CSS
const { html, styles } = extractStyles(<App />);
// Inject into HTML response
const fullHtml = `
<!DOCTYPE html>
<html>
<head>
<style>${styles}</style>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;SSR Features:
- Critical CSS extraction for optimal initial page load
- Hydration-safe class name generation (matches server and client)
- Compatible with React 18
renderToPipeableStreamand streaming SSR - No client-side flash of unstyled content (FOUC)
SSR Requirements:
- Node.js 18+
- React 18.0.0+
- react-dom 18.0.0+
Framework-Specific Notes:
- Next.js: Use
extractStylesingetServerSidePropsor App Router Server Components - Remix: Call
extractStylesin your loader and inject styles in root route - Vite SSR: Integrate in your server entry point before
renderToString
API Reference
Row
- Align with shorthand props:
left,centerX,right,stretchXplus the vertical variants (top,centerY,bottom,stretchY). - Accepts layout attributes (
spacing,padding,width,height,dataset,pseudoStates, etc.) from@no-css/core. - Renders a
<div>with the generated Elm-compatible class names and dataset attributes.
<Row left>
<Column>
<Text>Actual text</Text>
</Column>
</Row>Column
- Shares the same props as
Row; the only difference is the underlying orientation passed to the Elm layout engine. - Great for stacking content vertically while keeping the Elm semantics.
Text
- Supports children as strings, numbers, or React nodes. Strings/numbers are normalised into
textContentto preserve Elm parity. - Accepts the same layout attributes (
spacing,padding,width,height,dataset, etc.). - Renders a
<span>with the appropriate style class name and dataset attributes.
Bundles & Type Declarations
- ESM entry:
dist/index.js - CJS entry:
dist/index.cjs - Type declarations:
dist/index.d.ts(plus per-module.d.tsfiles for editor tooling) - Package exports are tree-shakeable; unused components drop out of modern bundlers automatically.
Peer Dependencies
react:^18.0.0react-dom:^18.0.0
Both peer dependencies are required at runtime. Documented versions are the adapter's supported range; test and CI coverage target React 18 on Node.js 18 and 20.
Publishing
Changesets powers semantic versioning and changelog generation. Once changes land on master,
release the prerelease build with:
npm run publish:tsThe script verifies builds/tests, bumps versions, and publishes under the beta npm dist-tag so
pilot consumers can opt-in safely.
