Quick start with effector
Effector is a powerful state manager that offers a different perspective on handling application data. Instead of mutating state directly in actions, effector relies on a reactive, declarative model that keeps data flow explicit and predictable.
How to use the documentation
Before diving in, note that we provide llms.txt so AI assistants such as ChatGPT, Claude, Gemini, and others can read the docs. Share a link in chat or upload the docs into an IDE like Cursor. Right now you can use:
- https://effector.dev/ru/llms-full.txt
- https://effector.dev/docs/llms.txt
- https://effector.dev/docs/llms-full.txt
We also maintain a ChatGPT effector assistant, keep a DeepWiki, and have the docs uploaded to Context7 for quick AI references.
Effector features
- Reactive: effector tracks dependencies automatically and updates every connected piece for you.
- Declarative: describe how data relates and transforms; effector decides when to run the logic.
- SSR and tests out of the box: scopes make server rendering and testing straightforward.
- Flexible architecture: scales from tiny widgets to enterprise systems.
- Universal: integrates with popular frameworks but can run in any JavaScript environment.
Read more about the key ideas here.
Install effector
Install effector via your preferred package manager:
npm install effectoryarn install effectorpnpm install effectorCreate your first store
A store represents part of your application state:
import { createStore } from "effector";
const $counter = createStore(0);Add events
Next, add events that will update the store when they fire:
import { createEvent } from "effector";
const incremented = createEvent();const decremented = createEvent();Connect events to the store
Link the events and the store together:
import { createEvent, createStore } from "effector";
const $counter = createStore(0);
const incremented = createEvent();const decremented = createEvent();
$counter.on(incremented, (counter) => counter + 1);$counter.on(decremented, (counter) => counter - 1);
// call the events anywhere in your appincremented();// counter is increased by 1decremented();// counter is decreased by 1decremented();// counter is decreased by 1Framework integration
Installation
To use effector with a framework install the matching integration:
npm install effector effector-reactnpm install effector effector-vuenpm install effector effector-solidUsage examples
And wire everything up:
import { useUnit } from "effector-react";import { createEvent, createStore } from "effector";import { $counter, incremented, decremented } from "./counter.js";
export const Counter = () => { const [counter, onIncremented, onDecremented] = useUnit([$counter, incremented, decremented]); // or const { counter, onIncremented, onDecremented } = useUnit({ $counter, incremented, decremented }); // or const counter = useUnit($counter); const onIncremented = useUnit(incremented); const onDecremented = useUnit(decremented);
return ( <div> <h1>Count: {counter}</h1> <button onClick={onIncremented}>Increment</button> <button onClick={onDecremented}>Decrement</button> </div> );};<script setup> import { useUnit } from "@effector-vue/composition"; import { $counter, incremented, decremented } from "./counter.js"; const [counter, onIncremented, onDecremented] = useUnit([$counter, incremented, decremented]); // or const { counter, onIncremented, onDecremented } = useUnit({ $counter, incremented, decremented }); // or const counter = useUnit($counter); const onIncremented = useUnit(incremented); const onDecremented = useUnit(decremented);</script>
<template> <div> <h1>Count: {{ counter }}</h1> <button @click="onIncremented">Increment</button> <button @click="onDecremented">Decrement</button> </div></template>import { createEvent, createStore } from "effector";import { useUnit } from "effector-solid";import { $counter, incremented, decremented } from "./counter.js";
const Counter = () => { const [counter, onIncremented, onDecremented] = useUnit([$counter, incremented, decremented]); // or const { counter, onIncremented, onDecremented } = useUnit({ $counter, incremented, decremented }); // or const counter = useUnit($counter); const onIncremented = useUnit(incremented); const onDecremented = useUnit(decremented);
return ( <div> <h1>Count: {counter()}</h1> <button onClick={onIncremented}>Increment</button> <button onClick={onDecremented}>Decrement</button> </div> );};
export default Counter;Svelte works with the base effector package, so no additional integration is required.
Additional installation options
Older browsers
For legacy browsers down to IE11 or Chrome 47 (often shipped with Smart TVs) import from the compat builds: effector/compat, effector-react/compat, and effector-vue/compat.
You can update imports manually:
import { createStore } from "effector";import { createStore } from "effector/compat";Or use babel-plugin-module-resolver. Example .babelrc configuration:
{ "plugins": [ [ "babel-plugin-module-resolver", { "alias": { "^effector$": "effector/compat", "^effector-react$": "effector-react/compat" } } ] ]}Other runtimes
You can also run effector in environments like deno. Import effector.mjs directly from a CDN:
import { createStore } from "https://cdn.jsdelivr.net/npm/effector/effector.mjs";CDN references:
- https://www.jsdelivr.com/package/npm/effector
- https://cdn.jsdelivr.net/npm/effector/effector.cjs.js
- https://cdn.jsdelivr.net/npm/effector/effector.mjs
- https://cdn.jsdelivr.net/npm/effector-react/effector-react.cjs.js
- https://cdn.jsdelivr.net/npm/effector-vue/effector-vue.cjs.js
Playgrounds
All examples in this documentation run inside our online playground. It lets you prototype, test, and share ideas for free, with React and TypeScript support ready to go. The project lives in this repository. For TypeScript-specific experiments, feel free to try the official TS playground.