Skip to main content
Parent-child communication in Lightning Web Components is achieved through public properties decorated with @api. This enables a unidirectional data flow where parents control the state and behavior of their children.

The @api Decorator

The @api decorator makes a property or method public, allowing parent components to access it. Properties marked with @api are reactive, meaning changes automatically trigger a re-render of the component.

Importing @api

import { LightningElement, api } from 'lwc';

Public Properties

Public properties allow parent components to pass data to child components.

Child Component Definition

contactTile.js
import { LightningElement, api } from 'lwc';

export default class ContactTile extends LightningElement {
    @api contact;
}
contactTile.html
<template>
    <template lwc:if={contact}>
        <lightning-layout vertical-align="center">
            <lightning-layout-item>
                <img
                    lwc:if={contact.Picture__c}
                    src={contact.Picture__c}
                    alt="Profile photo"
                />
                <lightning-icon
                    lwc:else
                    icon-name="standard:avatar"
                    alternative-text="Missing profile photo"
                ></lightning-icon>
            </lightning-layout-item>
            <lightning-layout-item padding="around-small">
                <p>{contact.Name}</p>
                <p>{contact.Title}</p>
                <p>
                    <lightning-formatted-phone
                        value={contact.Phone}
                    ></lightning-formatted-phone>
                </p>
            </lightning-layout-item>
        </lightning-layout>
    </template>
    <template lwc:else>
        <p>No contact data available.</p>
    </template>
</template>

Parent Component Usage

compositionBasics.js
import { LightningElement } from 'lwc';

export default class CompositionParent extends LightningElement {
    contact = {
        Name: 'Amy Taylor',
        Title: 'VP of Engineering',
        Phone: '6172559632',
        Picture__c:
            'https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/people/amy_taylor.jpg'
    };
}
compositionBasics.html
<template>
    <c-contact-tile contact={contact}></c-contact-tile>
</template>

Multiple Public Properties

A child component can expose multiple public properties to accept different types of data.

Example: Multiple Properties

child.js
import { LightningElement, api } from 'lwc';

export default class Child extends LightningElement {
    @api firstName;
    @api lastName;

    get fullName() {
        return `${this.firstName} ${this.lastName}`;
    }
}
child.html
<template>
    <p>Hello, {fullName}!</p>
</template>
Parent usage:
<template>
    <c-child first-name="Jennifer" last-name="Wu"></c-child>
</template>
Property names in HTML use kebab-case (first-name), but the corresponding JavaScript property uses camelCase (firstName)

Property Binding

You can bind parent component properties to child component properties using curly braces {}.

Static Values

<c-child first-name="Amy" last-name="Taylor"></c-child>

Dynamic Values

<c-contact-tile contact={contact}></c-contact-tile>

Complex Objects

You can pass entire objects, not just primitive values:
// Parent component
contact = {
    Name: 'Amy Taylor',
    Title: 'VP of Engineering',
    Phone: '6172559632',
    Picture__c: 'https://example.com/photo.jpg'
};
<c-contact-tile contact={contact}></c-contact-tile>

Best Practices

1

Use descriptive property names

Choose clear, self-documenting names for your public properties
@api contact;  // Good
@api data;     // Too generic
2

Validate input data

Check for null or undefined values in your child component
<template lwc:if={contact}>
    <!-- Render contact -->
</template>
<template lwc:else>
    <p>No contact data available.</p>
</template>
3

Keep components focused

Each component should have a single, well-defined responsibility
4

Document public APIs

Use JSDoc comments to document what each public property expects
/**
 * @api
 * @type {Object}
 * @description Contact record with Name, Title, Phone, and Picture__c fields
 */
@api contact;

Data Flow Rules

Data flows down from parent to child. Child components should not modify properties received from parents. This ensures a predictable, unidirectional data flow.
  • Parent controls the data: The parent component owns and manages the state
  • Child receives the data: The child component receives data through @api properties
  • Child displays the data: The child component renders the data but doesn’t modify it
  • Child communicates changes: If the child needs to trigger changes, it dispatches events to the parent

Common Patterns

Passing Primitive Values

// Parent
export default class Parent extends LightningElement {
    firstName = 'Amy';
    lastName = 'Taylor';
}
<!-- Parent template -->
<c-child first-name={firstName} last-name={lastName}></c-child>

Passing Objects

// Parent
export default class Parent extends LightningElement {
    contact = {
        Name: 'Amy Taylor',
        Title: 'VP of Engineering'
    };
}
<!-- Parent template -->
<c-contact-tile contact={contact}></c-contact-tile>

Passing Arrays

See the Nesting Patterns guide for examples of passing arrays and iterating over child components.

Next Steps

Nesting Patterns

Learn about iterating over arrays to create multiple child instances

Events

Discover how child components communicate back to parents

Build docs developers (and LLMs) love