이 글은 Claude Opus 4.5 을 이용해 초안이 작성되었으며, 이후 퇴고를 거쳤습니다.


State Diagram이란?#

상태 다이어그램(State Diagram)은 시스템이나 객체가 가질 수 있는 상태(State)와 상태 간의 전이(Transition)를 시각화합니다. 주문 처리, 사용자 인증, TCP 연결 등 유한 상태 기계(Finite State Machine)를 표현할 때 필수적인 도구입니다.

기본 문법#

stateDiagram-v2
    [*] --> Idle
    Idle --> Processing
    Processing --> Completed
    Completed --> [*]

stateDiagram-v2를 사용하면 최신 렌더러로 그려집니다. 구버전 stateDiagram도 여전히 사용 가능합니다.

상태(State) 정의#

기본 상태#

가장 단순한 형태로 상태 이름만 지정합니다.

stateDiagram-v2
    Idle
    Running
    Stopped

설명이 있는 상태#

state 키워드로 ID와 표시 텍스트를 분리할 수 있습니다.

stateDiagram-v2
    state "대기 상태" as Idle
    state "실행 중" as Running
    state "정지됨" as Stopped

    Idle --> Running
    Running --> Stopped

콜론을 사용한 설명#

stateDiagram-v2
    Idle: 대기 상태
    Running: 실행 중
    Stopped: 정지됨

    Idle --> Running
    Running --> Stopped

전이(Transition)#

기본 전이#

stateDiagram-v2
    StateA --> StateB

전이 설명(Transition Label)#

상태 전이의 조건이나 이벤트를 설명합니다.

stateDiagram-v2
    Idle --> Running: start()
    Running --> Paused: pause()
    Paused --> Running: resume()
    Running --> Stopped: stop()
    Paused --> Stopped: stop()

시작과 종료 상태#

[*]는 시작점 또는 종료점을 나타냅니다. 전이 방향에 따라 의미가 결정됩니다.

stateDiagram-v2
    [*] --> Created: 생성
    Created --> Active: 활성화
    Active --> Inactive: 비활성화
    Inactive --> Active: 재활성화
    Active --> Deleted: 삭제
    Inactive --> Deleted: 삭제
    Deleted --> [*]

복합 상태(Composite State)#

상태 안에 하위 상태를 포함할 수 있습니다. 복잡한 상태를 계층적으로 표현할 때 유용합니다.

기본 복합 상태#

stateDiagram-v2
    [*] --> Active

    state Active {
        [*] --> Idle
        Idle --> Processing
        Processing --> Idle
    }

    Active --> Inactive
    Inactive --> Active
    Inactive --> [*]

중첩 복합 상태#

복합 상태는 여러 레벨로 중첩할 수 있습니다.

stateDiagram-v2
    [*] --> Application

    state Application {
        [*] --> Running

        state Running {
            [*] --> Foreground
            Foreground --> Background: minimize
            Background --> Foreground: restore
        }

        Running --> Paused: pause
        Paused --> Running: resume
    }

    Application --> Terminated
    Terminated --> [*]

복합 상태 간 전이#

stateDiagram-v2
    state "주문 처리" as OrderProcess {
        [*] --> 결제대기
        결제대기 --> 결제완료
    }

    state "배송 처리" as ShippingProcess {
        [*] --> 배송준비
        배송준비 --> 배송중
        배송중 --> 배송완료
    }

    [*] --> OrderProcess
    OrderProcess --> ShippingProcess
    ShippingProcess --> [*]

분기(Choice)#

조건에 따른 분기를 표현합니다.

stateDiagram-v2
    state check_stock <<choice>>

    [*] --> Ordered
    Ordered --> check_stock
    check_stock --> InStock: 재고 있음
    check_stock --> OutOfStock: 재고 없음
    InStock --> Shipped
    OutOfStock --> Backordered
    Shipped --> [*]
    Backordered --> Ordered: 재입고

Fork와 Join#

병렬 처리의 시작(Fork)과 합류(Join)를 표현합니다.

stateDiagram-v2
    state fork_state <<fork>>
    state join_state <<join>>

    [*] --> fork_state
    fork_state --> Task1
    fork_state --> Task2
    fork_state --> Task3

    Task1 --> join_state
    Task2 --> join_state
    Task3 --> join_state

    join_state --> Completed
    Completed --> [*]

병행 상태(Concurrency)#

-- 구분자로 동시에 존재하는 병렬 상태를 표현합니다.

stateDiagram-v2
    [*] --> Active

    state Active {
        [*] --> NetworkState
        [*] --> UIState
        --
        state NetworkState {
            [*] --> Connected
            Connected --> Disconnected
            Disconnected --> Connected
        }
        --
        state UIState {
            [*] --> Visible
            Visible --> Hidden
            Hidden --> Visible
        }
    }

    Active --> [*]

노트(Notes)#

상태에 대한 추가 설명을 붙일 수 있습니다.

stateDiagram-v2
    [*] --> Pending
    Pending --> Processing
    Processing --> Completed
    Processing --> Failed
    Completed --> [*]
    Failed --> [*]

    note right of Pending: 요청이 대기열에 추가됨
    note left of Processing
        비동기 작업 수행 중
        타임아웃: 30초
    end note
    note right of Failed: 3회 재시도 후 실패 처리

방향 설정#

direction 키워드로 다이어그램의 방향을 설정합니다.

stateDiagram-v2
    direction LR

    [*] --> A
    A --> B
    B --> C
    C --> [*]
방향 설명
TB 위에서 아래로 (기본값)
LR 왼쪽에서 오른쪽으로
BT 아래에서 위로
RL 오른쪽에서 왼쪽으로

스타일링 (classDef)#

상태에 스타일을 적용할 수 있습니다.

stateDiagram-v2
    classDef success fill:#10B981,color:white
    classDef error fill:#EF4444,color:white
    classDef pending fill:#F59E0B,color:black

    [*] --> Pending
    Pending --> Processing
    Processing --> Completed
    Processing --> Failed
    Completed --> [*]
    Failed --> [*]

    class Pending pending
    class Completed success
    class Failed error

인라인 스타일 적용#

stateDiagram-v2
    [*] --> Active
    Active --> Inactive
    Inactive --> [*]

    Active:::activeStyle
    Inactive:::inactiveStyle

    classDef activeStyle fill:#22C55E,color:white
    classDef inactiveStyle fill:#6B7280,color:white

주석#

%%로 주석을 작성할 수 있습니다.

stateDiagram-v2
    %% 이것은 주석입니다
    [*] --> State1
    State1 --> State2
    %% State2에서 State3로의 전이
    State2 --> State3
    State3 --> [*]

실전 예제: 주문 상태 관리#

stateDiagram-v2
    classDef success fill:#10B981,color:white
    classDef error fill:#EF4444,color:white
    classDef warning fill:#F59E0B,color:black
    classDef info fill:#3B82F6,color:white

    [*] --> Created: 주문 생성

    state "결제 처리" as PaymentProcess {
        [*] --> PaymentPending
        PaymentPending --> PaymentProcessing: 결제 시도
        PaymentProcessing --> PaymentCompleted: 승인
        PaymentProcessing --> PaymentFailed: 거절
        PaymentFailed --> PaymentPending: 재시도
    }

    Created --> PaymentProcess: 결제 요청

    state payment_check <<choice>>
    PaymentProcess --> payment_check
    payment_check --> Confirmed: 결제 성공
    payment_check --> Cancelled: 결제 실패 (3회)

    state "배송 처리" as ShippingProcess {
        [*] --> Preparing
        Preparing --> ReadyToShip: 포장 완료
        ReadyToShip --> InTransit: 발송
        InTransit --> OutForDelivery: 배송 중
        OutForDelivery --> Delivered: 배송 완료
    }

    Confirmed --> ShippingProcess
    ShippingProcess --> Completed: 수령 확인

    Completed --> [*]
    Cancelled --> [*]

    note right of Created: 고객이 주문 생성
    note right of Confirmed: 재고 확보됨
    note left of Completed: 반품 가능 (7일)

    class PaymentCompleted,Confirmed,Delivered,Completed success
    class PaymentFailed,Cancelled error
    class PaymentPending,Preparing warning
    class PaymentProcessing,InTransit info

실전 예제: TCP 연결 상태#

stateDiagram-v2
    direction LR

    [*] --> CLOSED

    CLOSED --> LISTEN: passive open
    CLOSED --> SYN_SENT: active open / SYN

    LISTEN --> SYN_RCVD: SYN / SYN+ACK
    LISTEN --> CLOSED: close

    SYN_SENT --> ESTABLISHED: SYN+ACK / ACK
    SYN_SENT --> CLOSED: timeout / RST

    SYN_RCVD --> ESTABLISHED: ACK
    SYN_RCVD --> CLOSED: timeout / RST

    ESTABLISHED --> FIN_WAIT_1: close / FIN
    ESTABLISHED --> CLOSE_WAIT: FIN / ACK

    FIN_WAIT_1 --> FIN_WAIT_2: ACK
    FIN_WAIT_1 --> CLOSING: FIN / ACK
    FIN_WAIT_1 --> TIME_WAIT: FIN+ACK / ACK

    FIN_WAIT_2 --> TIME_WAIT: FIN / ACK

    CLOSING --> TIME_WAIT: ACK

    CLOSE_WAIT --> LAST_ACK: close / FIN

    LAST_ACK --> CLOSED: ACK

    TIME_WAIT --> CLOSED: 2MSL timeout

실전 예제: 사용자 인증 상태#

stateDiagram-v2
    classDef authenticated fill:#22C55E,color:white
    classDef unauthenticated fill:#9CA3AF,color:white
    classDef locked fill:#EF4444,color:white

    [*] --> Anonymous

    state "로그인 시도" as LoginAttempt {
        [*] --> ValidatingCredentials
        ValidatingCredentials --> CheckingMFA: 비밀번호 일치
        ValidatingCredentials --> CredentialError: 비밀번호 불일치

        state mfa_check <<choice>>
        CheckingMFA --> mfa_check
        mfa_check --> MFAVerified: MFA 성공
        mfa_check --> MFAFailed: MFA 실패
    }

    Anonymous --> LoginAttempt: 로그인 요청

    state attempt_result <<choice>>
    LoginAttempt --> attempt_result

    attempt_result --> Authenticated: 인증 성공
    attempt_result --> Anonymous: 인증 실패 (재시도 가능)
    attempt_result --> Locked: 5회 실패

    state Authenticated {
        [*] --> Active
        Active --> Idle: 비활동 10분
        Idle --> Active: 활동 감지
        Idle --> SessionExpired: 비활동 30분
    }

    Authenticated --> Anonymous: 로그아웃
    SessionExpired --> Anonymous

    Locked --> Anonymous: 30분 후 해제
    Locked --> Anonymous: 관리자 해제

    Anonymous --> [*]

    class Authenticated,Active authenticated
    class Anonymous,Idle unauthenticated
    class Locked locked

    note right of Authenticated: 토큰 기반 세션 유지
    note left of Locked
        보안 정책에 따른
        계정 잠금
    end note

실전 예제: CI/CD 파이프라인 상태#

stateDiagram-v2
    direction LR

    classDef success fill:#22C55E,color:white
    classDef running fill:#3B82F6,color:white
    classDef failed fill:#EF4444,color:white
    classDef pending fill:#F59E0B,color:black

    [*] --> Queued: PR 생성

    state "빌드 단계" as BuildStage {
        [*] --> Checkout
        Checkout --> Dependencies: 코드 체크아웃
        Dependencies --> Compile: 의존성 설치
        Compile --> [*]: 빌드 성공
    }

    state "테스트 단계" as TestStage {
        state fork_test <<fork>>
        state join_test <<join>>

        [*] --> fork_test
        fork_test --> UnitTest
        fork_test --> IntegrationTest
        fork_test --> E2ETest

        UnitTest --> join_test
        IntegrationTest --> join_test
        E2ETest --> join_test
        join_test --> [*]
    }

    state "배포 단계" as DeployStage {
        [*] --> DeployStaging
        DeployStaging --> SmokeTest
        SmokeTest --> DeployProduction: 승인
        DeployProduction --> [*]
    }

    Queued --> BuildStage: 워커 할당

    state build_result <<choice>>
    BuildStage --> build_result
    build_result --> TestStage: 빌드 성공
    build_result --> BuildFailed: 빌드 실패

    state test_result <<choice>>
    TestStage --> test_result
    test_result --> DeployStage: 테스트 통과
    test_result --> TestFailed: 테스트 실패

    DeployStage --> Deployed: 배포 완료

    BuildFailed --> [*]
    TestFailed --> [*]
    Deployed --> [*]

    class Queued pending
    class BuildStage,TestStage,DeployStage running
    class Deployed success
    class BuildFailed,TestFailed failed

상태 다이어그램 작성 팁#

1. 명확한 상태 이름#

stateDiagram-v2
    %% 좋은 예: 명확하고 동사나 형용사 사용
    [*] --> PaymentPending
    PaymentPending --> PaymentProcessing
    PaymentProcessing --> PaymentCompleted

2. 전이 레이블 활용#

상태 전이의 트리거(이벤트)와 조건을 명시합니다.

StatA --> StateB: 이벤트 [조건] / 액션

3. 복합 상태로 복잡성 관리#

관련된 상태들을 그룹화하여 다이어그램을 읽기 쉽게 만듭니다.

4. 색상으로 상태 구분#

  • 성공/완료 상태: 초록색
  • 실패/에러 상태: 빨간색
  • 대기/진행 중: 노란색/파란색
  • 중립/비활성: 회색

시리즈 마무리#

이 4부작 시리즈를 통해 Mermaid의 핵심 다이어그램인 Flowchart, Sequence Diagram, State Diagram을 모두 다뤘습니다.

각 다이어그램 사용 시나리오#

다이어그램 사용 시나리오
Flowchart 프로세스 흐름, 알고리즘, 시스템 아키텍처, 의사결정 흐름
Sequence Diagram API 호출 흐름, 시스템 간 통신, 인증 과정, 트랜잭션 처리
State Diagram 주문/결제 상태, 워크플로우, FSM, 연결 상태, 라이프사이클

더 알아보기#

Mermaid는 이 외에도 다양한 다이어그램을 지원합니다:

  • Class Diagram (클래스 관계)
  • Entity Relationship Diagram (데이터 모델)
  • Gantt Chart (프로젝트 일정)
  • Git Graph (브랜치 전략)
  • Mindmap (마인드맵)
  • Pie Chart (파이 차트)

공식 문서: https://mermaid.js.org/

에디터 추천#

  • Mermaid Live Editor: https://mermaid.live/ (실시간 미리보기)
  • VS Code Extension: Markdown Preview Mermaid Support
  • Obsidian: 기본 지원
  • GitHub/GitLab: 마크다운에서 기본 지원