
Product
Socket for Jira Is Now Available
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.
Build-in dependency collection, a predictable、zero-cost-use、progressive、high performance's react develop framework
English | 简体中文
⚡️ State management that tailored for react, it is simple, predictable, progressive and efficient.
Concent is an amazing state management tool, supported by a healthy middleware ecosystem and excellent devtools. It is a predictable, zero-invasive, progressive, high-performance react development framework!
Concent encourages simplicity. It saves you the hassle of creating boilerplate code and gives powerful tools with a moderate learning curve, suitable for both experienced and inexperienced developers alike.

recommend next verion lib: helux
A best practise project(git) building by concent & typescript.
$ git clone https://github.com/tnfe/concent-pro (dev with webpack)
$ git clone https://github.com/tnfe/vite-concent-pro (dev with vite)
Install by npx command
$ npx create-react-app my-app --template concent-ts
or clone its source code by git command
$ git clone https://github.com/concentjs/cra-project-concent-ts
Visit official website https://concentjs.github.io/concent-doc to learn more.
Make sure you have installed nodejs。
$ npm i --save concent
or yarn command
$ yarn add concent
See how easy it is to use concent to manage react state.
import { run, register, useConcent } from 'concent';
// 1️⃣ Configure models
run({
counter: {// declare a moudle named 'counter'
state: { num: 1, numBig: 100 }, // define state
},
// you can also put another module here.
});
// 2️⃣ Now the react component can work with concent
@register('counter') // 👈 decorate your component with register
class DemoCls extends React.Component{
// commit state to store and broadcast to other refs which also belong to counter module
inc = ()=> this.setState({num: this.state.num + 1})
render(){
// here if read num, it means current ins render dep keys is ['num']
return <button onClick={this.inc}>{this.state.num}</button>
}
}
function DemoFn(){
const { state, setState } = useConcent('counter'); // 👈 call useConcent hook in fn component
const inc = ()=> setState({num: state.num + 1});
return <button onClick={inc}>{state.num}</button>
}
Move logic to
reducerand definecomputed,watch,lifecycle
try edit this demo、 👉better js demo、👉better ts demo
import { run, register, useConcent, defWatch } from 'concent';
run({
counter: {
state: { num: 1, numBig: 100 },
computed: {
numx2: ({ num }) => num * 2, // only num changed will trigger this fn
numx2plusBig: ({ numBig }, o, f) => f.cuVal.numx2 + numBig // reuse computed reslult
},
reducer: {
initState: () => ({ num: 8, numBig: 800 }),
add: (payload, moduleState, actionCtx) => ({ num: moduleState.num + 1 }),
addBig: (p, m, ac) => ({ numBig: m.numBig + 100 }),
asyncAdd: async (p, m, ac) => {
await delay(1000);
return { num: m.num + 1 };
},
addSmallAndBig: async (p, m, ac) => {
// hate string literal? see https://codesandbox.io/s/combine-reducers-better-7u3t9
await ac.dispatch("add");
await ac.dispatch("addBig");
}
},
watch: {
numChange: defWatch(({ num }, o) => console.log(`from ${o.num} to ${num}`), {immediate:true}),
numChangeWithoutImmediate: ({ num }, o) => console.log(`from ${o.num} to ${num}`),
},
lifecycle: {
// loaded: (dispatch) => dispatch("initState"), // [optional] triggered when module loaded
// initState: async (moduleState) => {/** async logic */ return{num:666}}, // [optional] allow user load state async
// initStateDone: (dispatch) => dispatch("addSmallAndBig"), // [optional] call any reducer fn after initState done
mounted: (dispatch) => dispatch("initState"), // [optional] triggered when the first ins of counter module mounted
willUnmount: (dispatch) => dispatch("initState") // [optional] triggered when the last ins of counter module unmount
}
}
});
@register("counter")
class DemoCls extends React.Component {
render() {
// mr is short of moduleReducer, now you can call counter module's all reducer fns by mr
return <button onClick={this.ctx.mr.add}>{this.state.num}</button>;
}
}
function DemoFn() {
const { moduleComputed, mr } = useConcent("counter");
return <button onClick={mr.add}>numx2plusBig: {moduleComputed.numx2plusBig}</button>;
}
Details see here react-router-concent,expose history,you can call it anywhere in your app to enjoy the imperative navigation jump.
react-router-concent online demo
Details see here concent-plugin-redux-devtool,track your state changing history。

Details see here concent-plugin-loading,control all your reducer function's loading status easily。
concent-plugin-loading online demo
cdn.bytedance
https://cdn.bytedance.com/?query=concent
tcb-admin
|
wink |

concent is released under the MIT License. http://www.opensource.org/licenses/mit-license
FAQs
Build-in dependency collection, a predictable、zero-cost-use、progressive、high performance's react develop framework
The npm package concent receives a total of 468 weekly downloads. As such, concent popularity was classified as not popular.
We found that concent demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.