Migrating Aura Component to Lightning Web Component

A few months has passed since the announcement of Lightning Web Components (LWC), however, it seems as if I only just got started with Lightning Aura Components. Nevertheless, I decided it would be prudent to start looking into how I can start building with LWC. What better way than to migrate existing Aura components!

Note that this blog posts assumes you have a basic understanding of Lightning web components. If you want a quick guide please check out this article. The basic file structure of a web components consists of a html file, a Javascript file, and a component configuration (xml) file.


I have a number of custom aura components built to be used with visual workflows. I decided to attempt to migrate one those components. One slight obstacle I encountered is that web components currently does not support flow screens. I decided to move forward anyway since it does not impede my efforts to migrate the actual functionality of the component. I will be starting with the custom FlowRecordEditCmp as it is the most straightforward component I have built for flow screens thus far.

Migrating Attributes

Here are the attributes of the original Aura component. The component has an option to display either a force:recordEdit or a lightning:recordEditForm. In the web component version I am only including the lighting-record-edit-form instead as it provides more control on the fields that can be included in the form. With that change the editFormType and numOfCols attributes are no longer needed as they are related to the force:recordEdit component.

<aura:attribute name="recId" type="String" />
<aura:attribute name="recId" type="String" />
<aura:attribute name="editFormType" type="String" default="recordEdit" description="recordEdit or recordForm"/>
<aura:attribute name="fieldList" type="String" />
<aura:attribute name="fieldListArr" type="String[]" />
<aura:attribute name="objApiName" type="String" />
<aura:attribute name="numOfCols" type="Integer" default="2" />

view raw


hosted with ❤ by GitHub

What was defined as attributes in Aura are now javascript properties in web components.

import {
LightningElement, track, api
from 'lwc';

export default class FlowRecordEditLWC extends LightningElement {

api recId;

track showMsg = false;

api fieldList = 'Name';

track fieldListArr = [];

api objApiName = '';

successMsg = '</pre>
<h3 style="color:green;"><b>Record Save Successful!</b></h3>

Since we need the record id, a list of comma-separated field names, and the object API name provided by a flow (or another component), those respective properties need to be decorated with @api. The properties become public with that decoration. Other properties have the @track decoration. Any properties with @api and @tracked are considered tracked properties and will result in the component to re-render if the value of the property is modified. One additional property added is a success message. This will be used to replace part of the success message that was displayed in the aura component.

Migrating Init

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

view raw


hosted with ❤ by GitHub

The aura component has a handler for the initialization of the component. At load the doInit controller function is executed.

doInit: function(component, event, helper){

let formType = component.get('v.editFormType');
let obj = component.get('v.objApiName');


if(formType === 'recordForm'){
let fields = component.get('v.fieldList');
console.log('field list: ' + fields);
let fieldsArr = fields.split(',');
component.set('v.fieldListArr', fieldsArr);

The function essentially takes a list of comma-separated field api names and converts them to an array of type String to be stored in the fieldListArr component attribute.

In the LWC version we are simply going to add the standard Javascript connectedCallback() method to replace those initialize items in the web component Javascript file.

connectedCallback() {

if (this.fieldList) {
this.fieldListArr = this.fieldList.split(',');


I removed some lines that are no longer needed since I am only using one type of record edit component, however, the lines of code have been reduced since we no longer need to get and set component attribute values. To update the fieldListArr property I simply had to directly assign the split values from the fieldList property. Don’t forget to use “this” when referencing properties within the object.

Migrating Conditionals

The aura component has a ui:message components that displays a success message if the showMsg attribute is set to a TRUE value.

<aura:if isTrue="{!v.showMsg == TRUE}">
<ui:message title="Success!" severity="confirm" closable="false">Record Save Successful!</ui:message>

view raw


hosted with ❤ by GitHub

Conditionals are handled by  div elements in LWC. By setting the “if:true” attribute of the div I can render items within the tags. The “if:true” attribute references the showMsg Javascript property. If the property is assigned a true value, the nested base formatted rich text component is rendered onto the page. The rich text component will display the default message assigned to the successMsg property. Notice that we don’t use the “{v.name}” syntax and we do not use double quotes when referencing properties for attribute values.

<div if:true={showMsg}>
<lightning-formatted-rich-text value={successMsg}></lightning-formatted-rich-text>

view raw


hosted with ❤ by GitHub

Migrating the lightning recordEditForm component

Here we have a straight map over from the Aura version to the LWC version.

Nested within the recordEditForm component is an aura:iteration where we will render the fields we want to display via fieldListArr attribute.

<aura:if isTrue="{!and(v.editFormType == 'recordForm')}" >
<lightning:recordEditForm recordId="{!v.recId}" objectApiName="{!v.objApiName}" onsuccess="{!c.saveSuccessful}">
<lightning:messages />
<aura:iteration items="{!v.fieldListArr}" var="fld">
<lightning:inputField fieldName="{!fld}" />
<div class="slds-m-top_medium">
<lightning:button variant="brand" type="submit" name="save" label="Save" />

view raw


hosted with ❤ by GitHub

In the LWC version we will be using the template tag with the foreach attribute set the value of the fieldListArr property. Within the template tag we will load the lightning input fields.

<lightning-record-edit-form record-id={recId} object-api-name={objApiName} onsuccess={handleSuccess}>
<template for:each={fieldListArr} for:item='field'>
<lightning-input-field field-name={field} key={field}>
<lightning-button class="slds-m-top_small" variant="brand" type="submit" name="update" label="Save">

view raw


hosted with ❤ by GitHub

Handling Saves

Both Aura and LWC versions of the lightning recordEditForm has a lightning button that when clicked will update the record loaded with the component. Each version has an onsuccess attribute where you have specify a function to handle a successful save.

The aura version of the function looks like this:

saveSuccessful : function(component, event, helper){
        console.log('handling successful save');
        let showMsg = component.get('v.showMsg');
        component.set('v.showMsg', true);


Where as the LWC version if the following:

handleSuccess(event) {
    this.showMsg = true;

Both functions assign a true value to showMsg.


Migrating Design Configuration

A design file is required if attributes of an aura component needs to be exposed to lightning pages or flow screens. In LWC, the component configuration file (youcomponent.js-meta.xml) serves that purpose.

Here is what the design file of the aura component looks like:

<design:component >
<design:attribute name="recId" label="Record Id" required="true"/>
<design:attribute name="editFormType" label="Edit Form Type" description="(recordEdit or recordForm)" required="true"/>
<design:attribute name="fieldList" label="Edit Field List" description="List of comma-separated field api names" />
<design:attribute name="objApiName" label="Object API Name" description="The api name of the object record to be edited" />

Here is the the LWC component configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="FlowRecordEditLWC">
<targetConfig targets="lightning__HomePage,lightning__RecordPage,lightning__AppPage">
<property name="recId" type="String" label="Record Id"/>
<property name="objApiName" type="String" label="Object API Name"/>
<property name="fieldList" type="String" label="List of comma-separated fields" />

The isExposed parameter is set to true in order to expose your component to the lightning app builder or community builder. It includes targets to specify which specific types of lighting pages the component will be made available. This also replaces the interfaces that is specified in the aura component.

It also includes targetConfigs where specific properties can be configured to be exposed to the builders.

Check out more details of the specific parameter definitions here.

Comparing Both Versions

Here is the Aura component version:


Here is the LWC Version:


The LWC version cannot be used in a flow so I loaded it has lightning record page instead.  The amount and markup and JavaScript code was reduced in the new version so that is quite beneficial to me. I  had hoped I could configure the web component to be available for flows as well. I know I can use web components within Aura components so perhaps my next experiment might be to see if migrated components can still be used in the flow if I nest it within an Aura component. If I make any progress with that I will see if I can write a post on my experience.

All code referenced in this post can be found in this Github repository.

Until next time!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.