Allow an object to alter its behavior when its internal state changes
When to Use
An object's behavior depends on its current state and must change at runtime
You have complex conditional logic based on state (long if/else or switch chains)
Implementing workflows, UI state machines, or protocol handlers
Instructions
Define a state interface with the actions the context can perform.
Implement one concrete state class per state.
The context delegates behavior to the current state object.
States transition the context by calling context.setState(newState).
class TrafficLight {
constructor() {
this.state = new RedState(this);
}
setState(state) {
this.state = state;
}
signal() {
this.state.signal();
}
}
class RedState {
constructor(light) {
this.light = light;
}
signal() {
console.log('Red — stop');
this.light.setState(new GreenState(this.light));
}
}
class GreenState {
constructor(light) {
this.light = light;
}
signal() {
console.log('Green — go');
this.light.setState(new RedState(this.light));
}
}
const light = new TrafficLight();
light.signal(); // Red — stop
light.signal(); // Green — go
Details
The State pattern encapsulates state-dependent behavior into separate classes. The context object delegates to the current state, and states handle transitions. This eliminates complex conditionals and makes adding new states straightforward.
Trade-offs:
More classes — each state is its own class, which can feel heavy for simple state machines
Transitions are distributed across state classes — harder to see the full state diagram at a glance
For simple boolean flags, the pattern is overkill
When NOT to use:
When there are only 2-3 states with simple logic — a flag or enum is clearer
When state transitions are rare and the behavior difference is minimal
For UI component state — use framework state management (useState, reactive) instead
Read the instructions and examples in this document.
Apply the patterns to your implementation, adapting to your specific context.
Verify your implementation against the details and edge cases listed above.
Harness Integration
Type: knowledge — this skill is a reference document, not a procedural workflow.
No tools or state — consumed as context by other skills and agents.
Success Criteria
The patterns described in this document are applied correctly in the implementation.
Edge cases and anti-patterns listed in this document are avoided.
1---2name: js-state-pattern3description: JS State Pattern4---5# JS State Pattern67> Allow an object to alter its behavior when its internal state changes89## When to Use1011- An object's behavior depends on its current state and must change at runtime12- You have complex conditional logic based on state (long if/else or switch chains)13- Implementing workflows, UI state machines, or protocol handlers1415## Instructions16171. Define a state interface with the actions the context can perform.182. Implement one concrete state class per state.193. The context delegates behavior to the current state object.204. States transition the context by calling `context.setState(newState)`.2122```javascript23class TrafficLight {24 constructor() {25 this.state = new RedState(this);26 }27 setState(state) {28 this.state = state;29 }30 signal() {31 this.state.signal();32 }33}3435class RedState {36 constructor(light) {37 this.light = light;38 }39 signal() {40 console.log('Red — stop');41 this.light.setState(new GreenState(this.light));42 }43}4445class GreenState {46 constructor(light) {47 this.light = light;48 }49 signal() {50 console.log('Green — go');51 this.light.setState(new RedState(this.light));52 }53}5455const light = new TrafficLight();56light.signal(); // Red — stop57light.signal(); // Green — go58```5960## Details6162The State pattern encapsulates state-dependent behavior into separate classes. The context object delegates to the current state, and states handle transitions. This eliminates complex conditionals and makes adding new states straightforward.6364**Trade-offs:**6566- More classes — each state is its own class, which can feel heavy for simple state machines67- Transitions are distributed across state classes — harder to see the full state diagram at a glance68- For simple boolean flags, the pattern is overkill6970**When NOT to use:**7172- When there are only 2-3 states with simple logic — a flag or enum is clearer73- When state transitions are rare and the behavior difference is minimal74- For UI component state — use framework state management (useState, reactive) instead7576## Source7778https://patterns.dev/javascript/state-pattern7980## Process81821. Read the instructions and examples in this document.832. Apply the patterns to your implementation, adapting to your specific context.843. Verify your implementation against the details and edge cases listed above.8586## Harness Integration8788- **Type:** knowledge — this skill is a reference document, not a procedural workflow.89- **No tools or state** — consumed as context by other skills and agents.9091## Success Criteria9293- The patterns described in this document are applied correctly in the implementation.94- Edge cases and anti-patterns listed in this document are avoided.
Run npx skillmds@latest add intense-visions/js-state-pattern in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
JS State Pattern It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. Capability flags: makes network calls. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
Intense-Visions (@intense-visions) published this skill. Their other Agent Skills are listed on their SkillMD profile.