Skip to content

Anti-pattern Avoidance Checklist

Use this checklist to ensure your RxJS code does not fall into any anti-patterns. Click on each item to see detailed explanations and code examples.

Checklist Items

🔴 Avoid Critical Problems

CheckItemKey Points
Publish Subject with asObservable()Do not export Subject directly, publish it as an Observable with asObservable()
Allow state changes only through dedicated methods
Avoid nested subscribeDo not call another subscribe within subscribe
Flatten with switchMap, mergeMap, concatMap, etc.
Always unsubscribe from infinite streamsAlways unsubscribe from infinite streams like event listeners
takeUntil pattern or Subscription management
Explicitly configure shareReplayUse the form shareReplay({ bufferSize: 1, refCount: true })
Enable reference counting to prevent memory leaks
Avoid nested if statements within subscribeAvoid complex conditional branching (3 or more nested levels) within subscribe
Write declaratively with operators like filter, iif, partition

🟡 Avoid Problems Requiring Attention

CheckItemKey Points
map is pure function, side effects in tapDo not change state or output logs within map
Explicitly separate side effects with tap operator
Use Cold/Hot appropriatelyConvert HTTP requests to Hot with shareReplay
Determine whether execution should happen per subscription or be shared
Convert Promise with fromDo not mix Promise and Observable
Convert to Observable with from() for unified processing
Control high-frequency eventsControl search input with debounceTime, scrolling with throttleTime
Exclude duplicates with distinctUntilChanged

🔵 Improve Code Quality

CheckItemKey Points
Handle errors appropriatelyCatch errors with catchError and handle appropriately
Display user-friendly error messages
Retry with retry / retryWhen as needed
Properly release DOM eventsAlways unsubscribe from fromEvent subscriptions
Automatically unsubscribe with takeUntil when component is destroyed
Ensure type safetyDefine interfaces and type aliases
Explicitly specify Observable<T> type parameters
Leverage TypeScript type inference
Choose appropriate operatorsSearch: switchMap, parallel: mergeMap
Sequential: concatMap, prevent double-click: exhaustMap
Simple processing doesn't need RxJSRegular JavaScript is sufficient for array processing, etc.
Use RxJS for asynchronous processing and event streams
Manage state reactivelyManage state with BehaviorSubject or scan
Use subscribe as final trigger
Write testsImplement marble testing with TestScheduler
Make asynchronous processing testable synchronously

How to Use

1. During Code Review

After writing new code, conduct a self-review using this checklist.

2. During Pull Requests

Include this checklist in your pull request template so reviewers can verify with common criteria.

3. Regular Reviews

Use this checklist regularly against your existing codebase to check for anti-patterns.

4. Share Within Team

Share with team members to unify RxJS best practices.

Tips for Using the Checklist

  1. Don't try to perfect all items at once

    • First, prioritize critical problems (🔴)
    • Improve step by step
  2. Set priorities within the team

    • Adjust importance according to project characteristics
    • Create customized checklists
  3. Consider automation

    • Automate checks with static analysis tools like ESLint
    • Integrate into CI/CD pipeline
  4. Regular updates

    • Update according to RxJS version upgrades
    • Reflect insights from team experience

Important: This checklist is not for writing perfect code, but a guide to avoid common problems. Use it flexibly according to your project context.

Released under the CC-BY-4.0 license.