Introduction
Cycle.js treats your application as a pure function that receives input event streams (from the DOM, HTTP, etc.) and returns output streams (DOM updates, HTTP requests, etc.). Side effects are isolated into drivers, making the core logic easy to test and reason about.
What Cycle.js Does
- Models apps as pure functions from source streams to sink streams
- Isolates all side effects (DOM, HTTP, WebSocket) into pluggable drivers
- Uses reactive streams (xstream or RxJS) as the data flow primitive
- Provides component isolation via the
isolate()helper - Supports server-side rendering through the HTML driver
Architecture Overview
A Cycle.js app consists of a main function and a set of drivers. The main function receives observable sources (DOM events, HTTP responses) and returns observable sinks (virtual DOM trees, HTTP requests). The run() function wires sources to sinks in a feedback loop. This architecture enforces unidirectional data flow and makes every component a testable pure function.
Self-Hosting & Configuration
- Install core packages:
@cycle/runand one or more drivers - Use
@cycle/domfor DOM rendering via Snabbdom virtual DOM - Add
@cycle/httpfor HTTP request/response cycles - Bundle with any standard tool (webpack, Vite, Rollup)
- Configure TypeScript via standard
tsconfig.json; types are included
Key Features
- Pure functional architecture eliminates hidden state mutations
- Drivers are reusable and swappable, enabling easy testing with mock drivers
- Component isolation prevents CSS and event leaking between components
- Works with xstream (lightweight) or RxJS (full-featured) for stream processing
- DevTool browser extension visualizes the dataflow graph in real time
Comparison with Similar Tools
- React — component-based with hooks for side effects; Cycle.js separates all side effects into drivers
- RxJS + Angular — Angular uses RxJS internally; Cycle.js makes streams the primary programming model
- Elm — similar functional purity but uses its own language; Cycle.js uses plain JavaScript or TypeScript
- Svelte — compiler-based reactivity; Cycle.js uses explicit observable streams
- MobX — observable state management; Cycle.js applies observables to the entire app architecture
FAQ
Q: Is Cycle.js suitable for large applications? A: Yes. The driver-based architecture scales well because each component is an isolated pure function with explicit inputs and outputs.
Q: What is the learning curve like? A: Developers familiar with reactive programming (RxJS, observables) will adapt quickly. Those new to streams should expect an initial ramp-up period.
Q: Can I use Cycle.js with TypeScript? A: Yes. All Cycle.js packages include TypeScript type definitions.
Q: How does testing work? A: Because components are pure functions, you test them by feeding mock source streams and asserting on the output sink streams, with no DOM or browser needed.