React adapter for ETL CoreStream Core
Build fully reactive ETL interfaces in React using composable hooks, compound components, render props, context orchestration, and headless UI patterns.
@etl-corestream/react transforms the CoreStream orchestration engine into a complete React-first developer experience.
It provides:
- Reactive ETL hooks
- Compound context architecture
- Fully customizable UI components
- Headless render-prop APIs
- Context-driven orchestration
- Slot/asChild composition support
- Pagination-aware data views
- Editable ETL tables
- Recovery workflows
- Mapping interfaces
- Import/export triggers
- Metrics & progress subscriptions
The adapter is designed to work seamlessly with the reactive architecture exposed by @etl-corestream/core.
@etl-corestream/react is currently under heavy development and is not stable yet.
Until version 1.0.0, APIs, component contracts, behaviors, and internal architecture may change without notice.
Expect breaking changes while the ecosystem evolves.
- Features
- Philosophy
- Installation
- Quick Start
- Architecture Overview
- Compound Component Architecture
- Context System
- Render Props
- asChild / Slot Support
- Hooks
- Components
- DataView System
- Editable Tables
- Mapping System
- Recovery Workflows
- Reactive State Integration
- Headless UI Philosophy
- Advanced Composition
- Example Workflow
- Why This Architecture?
- Design Goals
- Official Packages
- License
- React-first ETL architecture
- Headless & composable APIs
- Compound component system
- Render prop support
- Slot/asChild composition
- Context-driven orchestration
- Reactive ETL state
- Pagination-aware data views
- Editable datasets
- Built-in mapping UI helpers
- Recovery flow helpers
- Reactive metrics & progress
- Framework-style component API
- Tailwind-friendly
- Fully customizable rendering
- Hooks + components interoperability
- RxJS + Signals integration
- Zero imposed styling
- Massive dataset visualization support
@etl-corestream/react is not a styled UI kit.
It is a headless orchestration layer for React applications built on top of ETL CoreStream.
The adapter focuses on:
- Composition over rigid components
- Context over prop drilling
- Headless APIs over opinionated UI
- Reactive state over imperative synchronization
- Reusable orchestration primitives
- Massive-scale workflows
You can:
- Use the included components directly
- Build your own UI entirely from hooks
- Mix both approaches freely
- Replace rendering at any level
Install the React adapter:
npm install @etl-corestream/reactimport { Etl } from "@etl-corestream/react";
export const App = () => {
return (
<Etl.Root>
<Etl.Layout.Root layouts={layouts}>
<Etl.Layout.Selector />
<Etl.Layout.Trigger>
Select Layout
</Etl.Layout.Trigger>
</Etl.Layout.Root>
<Etl.Importer.Root>
<Etl.Importer.Input />
<Etl.Importer.Trigger>
Select File
</Etl.Importer.Trigger>
</Etl.Importer.Root>
<Etl.Progress>
{({ totalProgress }) => (
<progress value={totalProgress} max={100} />
)}
</Etl.Progress>
<Etl.DataView.Root>
<Etl.DataView.Table.Root>
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
</Etl.DataView.Table.Root>
</Etl.DataView.Root>
</Etl.Root>
);
};The React adapter wraps the ETL CoreStream orchestrator with layered React contexts and composable hooks.
ETL CoreStream Orchestrator
β
Reactive Hooks
β
Context Providers
β
Compound Components
β
Custom UI RenderingThe system allows:
- Shared orchestration state
- Nested contextual behavior
- Localized state composition
- Headless rendering control
- Massive UI flexibility
The adapter uses a compound component architecture inspired by systems like:
- Radix UI
- Headless UI
- React Aria
Example:
<Etl.DataView.Root>
<Etl.DataView.Table.Root>
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
</Etl.DataView.Table.Root>
<Etl.DataView.Pagination.Root>
<Etl.DataView.Pagination.PagePreviousButton />
<Etl.DataView.Pagination.PageNextButton />
</Etl.DataView.Pagination.Root>
</Etl.DataView.Root>Contexts automatically coordinate:
- Pagination
- Current rows
- Filtering
- Editing
- Metrics
- Viewer state
The adapter exposes multiple contextual layers.
<Etl.Root> creates and exposes the orchestrator instance to all descendants.
<Etl.Root>
<MyETLInterface />
</Etl.Root>Internally:
<EtlContext.Provider value={orchestrator}>This provides:
- State
- Metrics
- Logs
- Progress
- Steps
- Recovery state
- Viewer state
- Reactive signals
Certain systems create localized contextual state.
Example:
<Etl.DataView.Root>Provides:
- Pagination coordination
- Filtering state
- Current rows
- Editing state
- Data navigation helpers
This enables deeply nested composition without prop drilling.
Most components support render props for full rendering control.
Example:
<Etl.Progress>
{({ totalProgress }) => (
<progress value={totalProgress} max={100} />
)}
</Etl.Progress>Example:
<Etl.DataView.Table.Cell>
{({ isError }) => (
<div>
{isError && <span>Error</span>}
</div>
)}
</Etl.DataView.Table.Cell>Render props expose internal contextual values while preserving orchestration behavior.
Below are short examples (and references to the Storybook viewer) showing common render-prop patterns used across the library.
See the concrete implementation in the Storybook viewer:
For a full Storybook example, see: src/components/etl/storybook on GitHub
<Etl.DataView.Edit.Root className="fixed top-0 left-0 w-full h-full bg-white/50 backdrop-blur-sm z-50 flex items-center justify-center">
{
({ currentEditRow }) => {
if (!currentEditRow)
return null;
return <>
<div className="flex flex-col gap-2 p-4 bg-white rounded-md border border-gray-300">
<span className="text-lg font-semibold">Edit Cell</span>
<div className="flex gap-5 ">
<div className="flex flex-col gap-1">
<span className="text-gray-400 text-xs">Previous Value:</span>
<Etl.DataView.Edit.PreviusInput className="border border-gray-300 w-min text-nowrap bg-gray-100 text-gray-800 p-2 px-4 rounded-md hover:bg-gray-200 transition-colors duration-300 cursor-pointer" >
{
({ previusValue }) =>
previusValue
}
</Etl.DataView.Edit.PreviusInput>
</div>And a cell-level render-prop used for per-cell rendering/validation UI:
Object.keys(row.value).map((key) =>
<Etl.DataView.Table.Cell key={key} row={row} column={key} className="border-r border-gray-300 data-[is-error]:bg-red-200">
{
({ isError }) =>
<div className="flex items-center">
<div className="flex flex-col items-center gap-0 w-full px-1">
{isError ?
<span className="bottom-0 order-2 text-xs font-semibold text-red-500">
{ErrorDicc[isError] || isError}
</span> : nullMinimal usage examples:
// Progress (simple)
<Etl.Progress>
{({ totalProgress }) => <progress value={totalProgress} max={100} />}
</Etl.Progress>
// Edit overlay (previous / new value)
<Etl.DataView.Edit.Root>
{({ currentEditRow }) =>
currentEditRow ? (
<div>
<Etl.DataView.Edit.PreviusInput>
{({ previusValue }) => previusValue}
</Etl.DataView.Edit.PreviusInput>
<Etl.DataView.Edit.NewInput />
</div>
) : null
}
</Etl.DataView.Edit.Root>
// Table body + cell render-props
<Etl.DataView.Table.TBody>
{({ currentRows, setCurrentEditRow }) =>
currentRows.value?.map(row => (
<Etl.DataView.Table.Row key={row.__rowId} rowObject={row}>
{({ row }) => (
<>
<Etl.DataView.Table.Cell row={row} column="index">
{() => <span>{row.__rowId}</span>}
</Etl.DataView.Table.Cell>
<Etl.DataView.Table.Cell row={row} column="name">
{({ isError }) => <span className={isError ? 'text-red-500' : ''}>{row.value.name}</span>}
</Etl.DataView.Table.Cell>
</>
)}
</Etl.DataView.Table.Row>
))
}
</Etl.DataView.Table.TBody>These patterns let you access contextual state (current rows, edit state, validation flags, header helpers, etc.) while keeping the UI fully custom and headless.
All major interactive components support asChild.
This enables integration with:
- Radix UI Slot
- Custom buttons
- Design systems
- Tailwind components
- External UI libraries
Example:
<Etl.ResetButton asChild>
<button className="custom-button">
Reset
</button>
</Etl.ResetButton>The ETL behavior is preserved while rendering your own component.
The adapter exposes hooks for building completely custom interfaces.
Creates and exposes the orchestrator instance.
const orchestrator = useEtlOrchestrator();Access the global ETL context.
const { metrics, progress } = useEtlContext();Provides:
- Current rows
- Pagination
- Filtering
- Editing helpers
- Metrics
- View navigation
Importer helpers and state.
Export helpers and exporter triggers.
Header mapping orchestration.
Recovery workflow helpers.
Layout selection orchestration.
Abort current workflow actions.
Reset ETL sessions.
useEtlState()useMetrics()useProgress()useLogs()useStepFlags()
<Etl.Root />
<Etl.Importer />
<Etl.StateView />
<Etl.Layout />
<Etl.LogView />
<Etl.DataView />
<Etl.ResetButton />
<Etl.Exporter />
<Etl.Mapper />
<Etl.Progress />
<Etl.Recover />
<Etl.AbortButton />The DataView system centralizes:
- Table rendering
- Pagination
- Editing
- Filtering
- Row removal
- Reactive dataset visualization
<Etl.DataView.Table.Root />
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
<Etl.DataView.Table.Row />
<Etl.DataView.Table.Cell />
<Etl.DataView.Table.HeaderCell /><Etl.DataView.Pagination.Root />
<Etl.DataView.Pagination.PageNextButton />
<Etl.DataView.Pagination.PagePreviousButton />
<Etl.DataView.Pagination.PageFirstButton />
<Etl.DataView.Pagination.PageLastButton />The adapter includes contextual editing workflows.
<Etl.DataView.Edit.Root>
<Etl.DataView.Edit.PreviusInput />
<Etl.DataView.Edit.NewInput />
<Etl.DataView.Edit.TriggerCancel />
<Etl.DataView.Edit.TriggerSubmit />
</Etl.DataView.Edit.Root>Rows can be edited while ETL processing continues in the background.
The mapping system helps users map incoming headers dynamically.
Example:
<Etl.Mapper.Root>
<Etl.Mapper.HeadersView />
<Etl.Mapper.TriggerConfirm>
Confirm
</Etl.Mapper.TriggerConfirm>
<Etl.Mapper.TriggerCancel>
Cancel
</Etl.Mapper.TriggerCancel>
</Etl.Mapper.Root>Useful for:
- CSV imports
- Alias mapping
- Flexible schemas
- User-driven remapping
The adapter exposes recovery flows directly to React interfaces.
Example:
const { recoveryPoint } = useRecoveryView();Recovery UI can be fully customized while maintaining orchestration behavior.
The adapter integrates with the reactive CoreStream architecture.
Supported internally:
- RxJS
- Preact Signals
React components automatically react to:
- Progress updates
- Metrics changes
- Validation updates
- Dataset changes
- Recovery state
- Viewer state
The adapter intentionally avoids imposing:
- Styling systems
- CSS frameworks
- Component themes
- Layout opinions
You fully control:
- Rendering
- Styling
- Accessibility
- Animations
- Design systems
Tailwind, CSS Modules, Styled Components, Emotion, or custom systems all work naturally.
A complete workflow may include:
Select Layout
β
Select File
β
Map Headers
β
Process Stream
β
Validate Rows
β
Edit Invalid Data
β
Filter Results
β
Export DatasetAll while remaining:
- Reactive
- Recoverable
- Non-blocking
- Editable
Massive ETL interfaces are difficult to build traditionally.
Most solutions suffer from:
- Prop drilling
- Tight coupling
- Non-reactive orchestration
- Inflexible rendering
- UI blocking
- Poor scalability
@etl-corestream/react solves this with:
- Layered contexts
- Reactive orchestration
- Compound composition
- Render-prop extensibility
- Hook-driven APIs
The adapter was designed around a few core principles:
- Composition over monolithic widgets
- Headless APIs over rigid UI
- Reactive orchestration over imperative sync
- Context coordination over prop drilling
- Massive dataset support
- Incremental rendering
- Flexible integration
GitHub:
GitHub:
The project is fully open source.
Contributions are welcome:
- Issues
- Discussions
- Documentation
- Adapters
- Custom modules
- Examples
- Performance improvements
MIT License.