Skip to content

Add more exports#760

Merged
jfboeve merged 1 commit intolightning-js:mainfrom
guilhermesimoes:add-lightning3-exports
Mar 18, 2026
Merged

Add more exports#760
jfboeve merged 1 commit intolightning-js:mainfrom
guilhermesimoes:add-lightning3-exports

Conversation

@guilhermesimoes
Copy link
Copy Markdown
Contributor

Add type exports TextRenderer, CoreNodeProps and CoreTextNodeProps.

Also export CoreNode and CoreTextNode since we can't use stage.createNode() or stage.createTextNode().

Peacock has been using Lightning v2's Element for several years now, so all our components extend that class. In order to migrate to Lightning v3, we need access to the new building blocks, CoreNode and CoreTextNode, so that our components can extend those.

Comment thread exports/index.ts
export type { AnimationSettings } from '../src/core/animations/CoreAnimation.js';
export type { TimingFunction } from '../src/core/utils.js';
export type { Inspector } from '../src/main-api/Inspector.js';
export type { CoreNodeRenderState } from '../src/core/CoreNode.js';
Copy link
Copy Markdown
Contributor Author

@guilhermesimoes guilhermesimoes Mar 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also like to report something here.

Is it intended for consumers of lightningjs/renderer to be able to do:

import { CoreNodeRenderState } from '@lightningjs/renderer';

if (renderState === CoreNodeRenderState.InViewport) { ... }

?

Because if so, then this isn't working. All enums are being exported as export declare enum X. In order to preserve enums for consumers, preserveConstEnums must be used.

@elsassph
Copy link
Copy Markdown
Contributor

@guilhermesimoes I think you aren't approaching that correctly - to create nodes you should be go through the renderer instance:

Both the official Blits and unofficial SolidJS frameworks use this API, and in both cases they don't directly extend those objects, which is potentially a departure from the Lightning 2 approach where you can extend the base Element type.

@guilhermesimoes
Copy link
Copy Markdown
Contributor Author

guilhermesimoes commented Mar 16, 2026

The entire Peacock codebase is written in a class based approach, more or less like this:

import { Component, Element } from '@lightningjs/core';

export class SomePage extends Component {
  private title: Element;

  constructor(stage: Stage) {
    super(stage);

    const title = (this.title = new Element(stage));
    title.y = SOME_PAGE_TITLE_Y;
    title.x = HORIZONTAL_SAFE_ZONE;
    title.text = 'Hello World';
  }
}

As you can imagine, migrating over 300 components is not an easy task. We could create our own Component and Element classes like so:

import {
  type Stage,
  type CoreNode // note, this type import isn't even available
} from '@lightningjs/renderer';

export class Element {
  private node: CoreNode;

  constructor(stage: Stage, props = {} as CoreNodeProps) {
    this.node = stage.createNode(props);
  }

  set x(x) {
    this.node.x = x;
  }

  get x() {
    return this.node.x;
  }

  // etc ...
}

But this approach has several disadvantages:

  1. For each element, we now create 2 class instances instead of only 1: our own Element and Lightning 3's CoreNode.
  2. We need to delegate all functions and properties, getters and setters, from Element down to CoreNode. If in a future Lightning release a new field is added to CoreNode, we need to make sure that we also add it to Element and delegate it accordingly. If we forget to add it, things may fail.

As such, we believe a better approach for a progressive migration from Lightning 2 to 3 is like so:

import {
  type Stage,
  type CoreNodeProps, // we also need this type import, which is also not available
  CoreNode
} from '@lightningjs/renderer';

export class Element extends CoreNode {
  constructor(stage: Stage, props = {} as CoreNodeProps) {
    super(stage, stage.resolveNodeDefaults(props));
  }
}

This approach:

  1. Does not create one extra class instance
  2. Does not require any delegation, it already extends the primitive CoreNode, so Lightning 3 can already accept it and render it.

We understand this may not fit in the Lightning team's vision of a declarative approach such as SolidJS or Blits, which at build time transform templates into nested calls to stage.createNode(). We want to get there too, but we have a long way to get there. We need to migrate to Lightning 3 first 😄

@elsassph
Copy link
Copy Markdown
Contributor

elsassph commented Mar 16, 2026

@guilhermesimoes I see, so you're using the classic LightningJS 2 (L2) Component class but without templating.

Let me clarify a bit: the LightningJS 3 (L3) renderer CoreNode/CoreTextNode do NOT correspond to L2 Element class - they correspond to L2 ElementCore, which the Element class internally creates and to which it forwards most properties.

As of now, there is no shortcut to migrating to L3. The LightningJS team has a limited capacity and they focus on the new Blits UI framework.

While I think it should be possible to reproduce some or all of L2 Application/Component/Element API using the core L3 renderer, that's a difficult project with little benefit ultimately: if your app works well with L2 engine then that's OK - it wouldn't run better by swapping the internals with L3 renderer.

@guilhermesimoes
Copy link
Copy Markdown
Contributor Author

Let me clarify a bit: the LightningJS 3 (L3) renderer CoreNode/CoreTextNode do NOT correspond to L2 Element class - they correspond to L2 ElementCore, which the Element class internally creates and to which it forwards most properties.

Yes, we know. We are aware.

if your app works well with L2 engine then that's OK - it wouldn't run better by swapping the internals with L3 renderer.

I'm confused. You don't want teams to upgrade to L3?
From our part, we want to upgrade to L3 because we want to start using SDF fonts and eventually move on to Blits / SolidJS.

As of now, there is no shortcut to migrating to L3. The LightningJS team has a limited capacity and they focus on the new Blits UI framework.

We understand that. We're not looking for shortcuts. For starters, we only need these very minor changes (2 class exports + 3 type exports). Is adding these exports a high maintenance burden to the LightningJS team?

@elsassph
Copy link
Copy Markdown
Contributor

Disclaimer: I'm not part of the team, so I can't comment on the decisions and priorities.

I don't think the export change and trying to extend the code nodes is wise though. FWIW if you want to eventually migrate to Blits or SolidJS, you need to follow the approach where the code nodes (created using the renderer.create* helpers) are wrapped in another instance, because that's how those frameworks function. Probably you will want a progressive migration where there it would be possible for your Component/Elements to interoperate inside e.g. a Blits/SolidJS app.

@guilhermesimoes
Copy link
Copy Markdown
Contributor Author

guilhermesimoes commented Mar 17, 2026

you need to follow the approach where the code nodes (created using the renderer.create* helpers) are wrapped in another instance

I already explained in #760 (comment) why that is a worse approach.

Disclaimer: I'm not part of the team

Oh, I had not realised that. I will wait for the team's input then.

@elsassph
Copy link
Copy Markdown
Contributor

elsassph commented Mar 17, 2026

I noted that you find it worse (and I don't necessarily disagree), but the reality is that it's how L2 Component/Element and L3's Blits and SolidJS frameworks work, so if you think in the future you'll use these frameworks, you won't escape the extra object pattern.

I think it would potentially help supporting your request if you could share a POC app using the modified API demonstrating how you can tie everything together.

@wouterlucas
Copy link
Copy Markdown
Contributor

wouterlucas commented Mar 17, 2026

Hey @guilhermesimoes 👋

Super excited to see Peacock dive into L3! We're on a similar track spinning up ION with @estobbart for FireTV/Consoles collaboration effort across the Sky/Comcast and the NBCU family. If you need us, we're basically standing by with snacks and support.

Your proposed approach looks good to me, totally reasonable for a transition period. Would love to see a small adaptation/transition layer in action. You can always re-evaluate how to go beyond this, making large scale changes to an existing app is always a big challenge.

@jfboeve … can we move this forward?

The LightningJS team has a limited capacity and they focus on the new Blits UI framework.

True, priority usually goes to internal work where goals align. Open source still matters, we just occasionally have to juggle team/department/company-wide and open source priorities.

if your app works well with L2 engine then that's OK - it wouldn't run better by swapping the internals with L3 renderer.

I'm confused. You don't want teams to upgrade to L3?
From our part, we want to upgrade to L3 because we want to start > using SDF fonts and eventually move on to Blits / SolidJS.

To be clear: yes, we absolutely want teams to upgrade to L3. We've seen major, measurable improvements across Xfinity, Rogers, and Sky apps — across a wide range of devices. Our group is heavily committed to consolidating and moving more L2 apps onto L3.

Some teams (cough HBO cough, love you guys 😇 ) are taking their time on L2 and that's their prerogative. But don't let that slow you down. You're part of the family, and we're here to support your move toward L3.

@guilhermesimoes
Copy link
Copy Markdown
Contributor Author

guilhermesimoes commented Mar 18, 2026

You're part of the family, and we're here to support your move toward L3.

That's great to hear!

We've seen major, measurable improvements across Xfinity, Rogers, and Sky apps — across a wide range of devices.

Awesome news, can't wait to take L3 to production and give our costumers an even faster app.

You can always re-evaluate how to go beyond this, making large scale changes to an existing app is always a big challenge.

We patched renderer to access these 5 exports and this approach is getting us somewhere (we can already see and interact with the app in L3, albeit in a more primitive format). Contributing these changes back to renderer seems natural so that we no longer need to patch it (we want to avoid this at all costs) and so that others that may be in a similar situation may also make use of it.

We will certainly re-evaluate our approach as we progress.

@jfboeve jfboeve merged commit d1d9d67 into lightning-js:main Mar 18, 2026
2 checks passed
@guilhermesimoes guilhermesimoes deleted the add-lightning3-exports branch March 18, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants