C4 Level 3

C4 component diagram

The C4 component diagram zooms into a single container and reveals its internal architecture — modules, services, repositories, controllers, and their interfaces. Level 3 of the C4 model, designed for the developers who build and maintain each service.

What is a C4 component diagram?

A C4 component diagram is Level 3 of the C4 model. While the container diagram shows your system's applications and databases, the component diagram zooms into one specific container and shows what's inside: the modules, services, repositories, controllers, and middleware that compose that container.

A component in C4 is not a UI component (like a React component). It is a grouping of related functionality behind a well-defined interface — an AuthService, an OrderRepository, a PaymentProcessor, a NotificationModule. Components are the building blocks that developers work with daily inside a service.

Component diagrams are optional in C4 — you create them only for containers with significant internal complexity. A Redis cache or a PostgreSQL database does not need a component diagram. But a backend API service with twelve modules, three middleware layers, and connections to four databases absolutely benefits from one. Focus component diagrams on the containers that developers struggle to understand.

C4 component diagram elements

Level 3 introduces internal modules with technology labels and interface-level relationships.

Component

A module, service, or class grouping within a container. Controllers, services, repositories, middleware — anything with a defined interface.

Component(authSvc, "Auth Service", "TypeScript", "Handles login, registration, JWT")
Container_Boundary

Groups components that belong to the same container. This is the container you are zooming into from the Level 2 diagram.

Container_Boundary(api, "API Server") { ... }
ContainerDb

Database containers that components interact with. Shown outside the container boundary to indicate cross-container communication.

ContainerDb(db, "Database", "PostgreSQL", "Persistent storage")
Rel

Relationships between components and external containers. Label with the method call or interface name for precision.

Rel(controller, authSvc, "Authenticates requests via", "JWT middleware")

C4 component diagram example in Mermaid

Zooming into the API Server container from the e-commerce container diagram.

C4Component
    title Component Diagram — API Server

    Container_Boundary(api, "API Server (Node.js/Express)") {
        Component(router, "Router", "Express Router", "Maps HTTP routes to controllers")
        Component(authMiddleware, "Auth Middleware", "JWT", "Validates tokens, extracts user context")
        Component(orderController, "Order Controller", "TypeScript", "Handles order CRUD and checkout flow")
        Component(productController, "Product Controller", "TypeScript", "Product catalog and search")
        Component(userController, "User Controller", "TypeScript", "Registration, profile, preferences")
        Component(orderService, "Order Service", "TypeScript", "Business logic for order processing")
        Component(productService, "Product Service", "TypeScript", "Product search and filtering")
        Component(authService, "Auth Service", "TypeScript", "Login, registration, JWT generation")
        Component(orderRepo, "Order Repository", "Prisma", "Database access for orders")
        Component(productRepo, "Product Repository", "Prisma", "Database access for products")
        Component(userRepo, "User Repository", "Prisma", "Database access for users")
    }

    ContainerDb(db, "Database", "PostgreSQL", "Users, orders, products")
    ContainerDb(cache, "Cache", "Redis", "Product cache, sessions")
    System_Ext(stripe, "Stripe", "Payment processing")

    Rel(router, authMiddleware, "Passes requests through")
    Rel(authMiddleware, orderController, "Authenticated requests")
    Rel(authMiddleware, productController, "Authenticated requests")
    Rel(authMiddleware, userController, "Authenticated requests")
    Rel(orderController, orderService, "Delegates to")
    Rel(productController, productService, "Delegates to")
    Rel(userController, authService, "Delegates to")
    Rel(orderService, orderRepo, "Persists via")
    Rel(orderService, stripe, "Processes payment", "HTTPS")
    Rel(productService, productRepo, "Queries via")
    Rel(productService, cache, "Caches results", "Redis")
    Rel(authService, userRepo, "Reads/writes users")
    Rel(orderRepo, db, "SQL queries")
    Rel(productRepo, db, "SQL queries")
    Rel(userRepo, db, "SQL queries")

Paste this into Cybewave Studio to render it instantly.

How to create a C4 component diagram

01

Pick the container

Choose the container from your Level 2 diagram that has the most internal complexity. Start with your main API server or the container developers ask the most questions about.

02

Map modules and layers

Identify the controllers, services, repositories, and middleware. Follow your codebase structure — most well-organized services have a clear separation between routing, business logic, and data access.

03

Define interfaces

Show how components call each other. Controllers call services, services call repositories, middleware intercepts requests. Label relationships with method names or patterns when precision helps.

04

Connect to external containers

Show how components interact with databases, caches, queues, and external services outside the container boundary. These are the integration points developers need to understand.

When to use a C4 component diagram

Component diagrams are for specific containers — not every service needs one.

Service refactoring

Before splitting a monolithic service into smaller ones, map the component diagram to see which modules have clean boundaries and which are tightly coupled. The diagram reveals the natural seams for decomposition.

Code review orientation

When a PR touches multiple modules in a service, the component diagram shows reviewers how those modules relate. They understand the blast radius of changes without reading every file in the diff.

Design pattern documentation

Document your middleware pipeline, service layer patterns, and repository abstractions. New developers see the architecture decisions (dependency injection, CQRS, event sourcing) visually rather than inferring them from code.

Cross-team handoffs

When ownership of a service transfers between teams, the component diagram is the map. It shows where the business logic lives, how data flows through the service, and what external dependencies each module has.

Performance bottleneck analysis

When a service is slow, the component diagram helps trace the hot path. If the OrderService calls ProductRepository which calls the cache then the database, you can see exactly where to instrument and optimize.

Integration testing strategy

Component boundaries define test boundaries. The diagram shows which components need mocks (external services) vs. real implementations (internal modules), directly informing your integration test architecture.

Why C4 component diagrams matter

The gap between a container diagram (listing “API Server — Node.js”) and reading actual source code is enormous. A container with 200 files, 15,000 lines of code, and 40 modules is opaque from the outside. The component diagram bridges this gap by showing the architectural skeleton of a service — the major modules, their responsibilities, and how they connect — without requiring anyone to read code.

Component diagrams also enforce architectural discipline. When you draw a diagram showing that controllers should only call services (never repositories directly), and services should only call repositories (never controllers), you have a visual contract. When code violates this contract, the diagram makes the violation obvious. Teams that maintain component diagrams tend to have cleaner separation of concerns because the expected architecture is explicit.

For complex services, the component diagram becomes the entry point for every conversation about internal structure. Should we add caching to the product search? Check the component diagram — ProductService already connects to Redis through ProductCache. Should we add a new payment provider? The diagram shows exactly where PaymentService plugs into the order flow. Every “where does this go?” question has a visual answer.

Frequently asked questions

What is a C4 component diagram?

A C4 component diagram is Level 3 of the C4 model. It shows the internal structure of a single container — the modules, services, repositories, and controllers inside that service and how they interact with each other and external containers.

Do I need component diagrams for every container?

No. Only create component diagrams for containers with significant internal complexity — typically your main API services. Databases, caches, and queues do not need component diagrams. Focus on the 2-3 containers that developers find hardest to understand.

How granular should components be?

Components should be at the module or service level — not individual classes or functions. A good rule: each component should map to a folder or namespace in your codebase. If you have more than 15 components, you may be too granular.

Is a C4 component the same as a React component?

No. In C4, "component" means a module or service grouping with a defined interface — like an AuthService, OrderRepository, or PaymentProcessor. React components are UI building blocks at a completely different level of abstraction.

How does a component diagram relate to class diagrams?

A component diagram is one zoom level above a class diagram. Components group related classes and functions behind an interface. If you need to see individual classes and their relationships, that is C4 Level 4 (Code) — which most teams skip since it can be auto-generated from code.

Create your C4 component diagram

Free to start. 50 AI credits/month. No credit card required.

Get started for free →