WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.54k stars 4.21k forks source link

Create a mechanism to expose unstable APIs to plugins #66197

Open jsnajdr opened 1 month ago

jsnajdr commented 1 month ago

The current Gutenberg policy, aligned with WordPress backward compatibility policy, is to not expose any private APIs to plugins at all. When a Gutenberg package exposes a private API, it's supposed to be used only by another Gutenberg package. For example, the Site Editor can use a private API from Block Editor or Components.

The packages try very hard to prevent plugins from using private API, there is the lock/unlock API and also @peterwilsoncc is hardening it by regularly changing the consent string in PRs like #55182.

However, this is a situation that treats the unstable APIs as "static" -- they already are here, and sometimes we review them and promote them to stable APIs. But I think we're not paying enough attention to the "dynamic" aspect, how new APIs are created and evolved before they are stabilized.

Currently, the only way how a new API can be reasonably created and evolved is when some Gutenberg app needs it. Because the Gutenberg packages can be broadly divided into "libraries" and "apps": libraries provide components, frameworks and utilities, and the apps (Post Editor, Site Editor, the 100+ core blocks) use them. If one of the apps needs something new from the libraries, we create a private API for that. That API can be modified as we learn more about the use cases and add new ones. Sometimes we stabilize an API and make it public, available to plugins.

The downside of this is that a plugin author never has a chance to participate in the development! They can use only something that is already finished. There's no way how a plugin author can experiment with private APIs and provide feedback, and participate in their evolution. Only the Gutenberg apps and blocks can be part of this process of trial and error.

This is now becoming a problem as we're working on new projects that go beyond Gutenberg, trying to rethink and refresh the entire wp-admin experience. The WooCommerce project would like to be part of the team, to use the new components like DataView or DataForm and rebuild the admin experience with them. Their use cases are more complex and rich than what is in Core and Gutenberg, we need them to verify that we're doing the Core APIs right.

So, can we find a way to allow plugins to participate in the evolution of new APIs, while at the same time keeping the WordPress backward compatibility contract?

One source of inspiration could be the JavaScript language and the TC39 process. After a new feature is added to the language standard, it needs to be finished and it's going to be there forever. But how is the feature developed and evolved?

Their answer is that potential new APIs go through several stages, stage 0 to stage 4. The stage signals how stable the feature is and how much you can rely on it. Developers can enable the unstable features in their build tools (the Babel transpiler etc.) or use polyfills. Browsers implement unstable APIs behind feature flags, and expose them unflagged in development versions (Google Canary, Firefox Nightly). That provides opportunities for testing, for developers to try them out and provide feedback.

Could WordPress have something similar?

colorful-tones commented 1 month ago

This sounds like the means for a great Make proposal.

tyxla commented 1 month ago

This might be worth feedback from a broader audience: @WordPress/gutenberg-core

peterwilsoncc commented 1 month ago

The background for the introduction of the private APIs in place of __unstable and __experimental APIs was due to their use in themes and plugins rendering them as faux-stable. Changing them would break many sites so WordPress became stuck with the initial API design, even though it was later discovered to be sub-optimal.

My concern with allowing plugin to opt-in to the private APIs is that WordPress would end up in a similar situation again. I worry that we'd end up in a situation in which WordPress couldn't unlock an API for risk of breaking sites (@adamziel worked on the code, so this may not be an issue -- I suggested it & try to track string changes each release).

__dangerousOptInToUnstableAPIsOnlyForCoreModules() does allow for plugins to op-in to private APIs while running the plugin, although the string needs to be maintained by plugins doing so.

https://github.com/WordPress/gutenberg/blob/3aa19d28dd46433c6c5677fe76a9e0f500678905/packages/private-apis/src/implementation.js#L62-L63

@jsnajdr is your request to allow opt-in to be easier only when running the Gutenberg plugin, or do you wish to be able to opt in for sites running WordPress Core?

youknowriad commented 1 month ago

I feel this need everyday when developing on Gutenberg. For a long term and sustainable project, a way to have a feedback loop for APIs, just like we do for features is needed. I know it's something that WordPress never had (aside from a small period where we had the experimental APIs in Gutenberg). I don't have a solution, but it's definitely a problem that is worth solving if we want to be shipping the right stable APIs.

draganescu commented 1 month ago

But isn't the consent string a way to opt in?

youknowriad commented 1 month ago

@draganescu Right now, the consent string can only be used by Core packages, not third-party packages. At least, that's the theory, they can pretend that they're a core package and use it but that's a hack really and can break anytime if the core package in question start loading in the page.

draganescu commented 1 month ago

Then the 1st thing that I can think of is to properly define the difference between opting into an API to participate into its formation vs relying on an unstable API.

talldan commented 1 month ago

A way to statically anyalyze the usage of the private APIs would also be good. For most of the experimental APIs we've resorted to using https://www.wpdirectory.net/ to search whether plugins are using an API, but it's not perfect, it can overmatch or be hard to find exact matches.

If there were a manifest or something that plugins had to use to say which private APIs they're using it'd be much easier to search for usage and even notify them when we're removing a private API.

Not sure how this would work, part of the problem is that an API can be so many things (function, prop, parameter, property etc ...) and there are often different techniques used for each.

ralucaStan commented 1 month ago

Introducing stage in the lifecycle of a new/experimental API would be good for consumers to understand its maturity. Between the 2 stages, private and stable it’s hard to know where an API is currently positioned ( as in closer to which stage).

This change could also encourage community feedback, which is ultimately the enabler for stabilizing something. It could also enable the maintainers to track better progress on APIs by observing how long it's been in a certain stage. This could prompt faster decision-making.

When it comes to usage of experimental APIs, it's clear that the risks are different depending on where the API is in its lifecycle. Using an API that is closer to becoming stable should in theory be less risky. What is a risk? Breaking changes or full removal of API.

I think this information about API maturity could speak more to developers about the type of involvement they could have and the risks/limits that come with it.

I agree coming up with these stages could be tricky, and there might be downsides to this approach, but it would allow for more flexibility and predictability then now.

Good changes from the status quo are to:

peterwilsoncc commented 1 month ago

I feel this need everyday when developing on Gutenberg. For a long term and sustainable project, a way to have a feedback loop for APIs, just like we do for features is needed. I know it's something that WordPress never had (aside from a small period where we had the experimental APIs in Gutenberg). I don't have a solution, but it's definitely a problem that is worth solving if we want to be shipping the right stable APIs.

@youknowriad I haven't been able to think of anything for WordPress Core but for sites running the Gutenberg plugin, it might be worth making the opt-in string static so site's using the APIs can safely do so while testing with the plugin.

I opt in for sites running the Gutenberg plugin and acknowledge these APIs may change without notice and are unavailable in WordPress Core

Extenders making use of it would need to do a little error catching during the transition period but it's a solvable problem.

ramonjd commented 1 month ago

Warning: left field idea incoming...

Could the experimental page be built out as a place to document/track/solicit feedback for experimental APIs?

It might be as feature-rich as the plugins page, with update/alert badges. Automation would be ideal, e.g., a script could scrape the JS code base for relevant data, which the page could publish, and some other flag in experimental PHP code (under /lib/experiments) or something.

🤷🏻

jsnajdr commented 1 month ago

is your request to allow opt-in to be easier only when running the Gutenberg plugin, or do you wish to be able to opt in for sites running WordPress Core?

@peterwilsoncc I didn't realize that we could distinguish between running and not running the Gutenberg plugin when I was writing down this issue. And yes, it could be a very good solution.

If a plugin wants to use unstable APIs, it's typically for an experimental feature that can be turned on/off in plugin settings. For example, WooCommerce has a Settings/Advanced/Features screen where you can enable a beta product editor:

Image

A new additional constraint would be that this beta editor can be active only when the Gutenberg plugin is installed and active. Today the purpose of the Gutenberg plugin is to provide a bi-weekly "technology preview" of what is coming to Core in the next release. And now it could also provide a "beta environment" to plugins that also want to offer their own "technology preview" features. It all fits together very well.

If you want to ship a feature to the general public, it won't be able to use the experimental APIs. The APIs need to be stabilized in Core before they can be used. That's certainly a limitation, but not a bad one.

How would the API for opting into the private APIs look like? Currently Core modules can do this:

__dangerousOptInToUnstableAPIsOnlyForCoreModules( 'I acknowledge...', '@wordpress/blocks' );

where there is a consent string that serves as a sort of password, and the module also needs to specify its name. Every module name can be used only once, and there is an allowlist of them. That partially prevents non-Core modules from impersonating as a Core module.

For experimental API access from plugins we could have a second function:

__dangerousOptInToUnstableAPIs( 'I confirm...' );

This function implementation would check globalThis.IS_GUTENBERG_PLUGIN. It would throw an error if the constant is false, and check the consent string otherwise.

How does that sound? @ralucaStan @gigitux @lysyjan would it satisfy the requirements for Woo and MailPoet plugins?

It would be also nice to have the private APIs documented and sorted into various stages. That could be a well-maintained private-apis.md file in the repo which would document each API and describe how stable it is.

youknowriad commented 1 month ago

@jsnajdr Just noting that we actually already do that. We already use globalThis.IS_GUTENBERG_PLUGIN to avoid shipping some experimental APIs to Core. An example that comes to my mind is the wp.editor.registerEntityAction API.

So I had assumed the discussion was more general, about Core as well.

Also, I do think there's value in improving our communication around the different stages of the different APIs.

gigitux commented 1 month ago

If a plugin wants to use unstable APIs, it's typically for an experimental feature that can be turned on/off in plugin settings. For example, WooCommerce has a Settings/Advanced/Features screen where you can enable a beta product editor:

This is not always true. For example, currently, we're using some private APIs for the Customize Your Store project that it is in production and belongs to the Woo onboarding flow. I shared some private APIs that we're using:

From a quick search, it looks like that we're using 20 times unlock():

Image

We can do this because these packages aren’t imported directly from WordPress Core; instead, we use the npm version.

My concern with allowing plugin to opt-in to the private APIs is that WordPress would end up in a similar situation again. I worry that we'd end up in a situation in which WordPress couldn't unlock an API for risk of breaking sites (@adamziel worked on the code, so this may not be an issue -- I suggested it & try to track string changes each release).

While I fully agree with our commitment to maintaining stable APIs, I’m not sure why we should take responsibility for not breaking plugins that use private APIs. By definition, these APIs are experimental, and it is the responsibility of plugin developers to ensure their plugins remain compatible with new versions of WordPress. As a platform, we should make this “contract” clear, and we should certainly communicate the status of private APIs more effectively and work towards stabilizing those that have been in use for several years and are relied upon by multiple plugins.

jsnajdr commented 1 month ago

we're using some private APIs for the Customize Your Store project that it is in production and belongs to the Woo onboarding flow.

If a production project needs private APIs, the first question is why these APIs are private and if it's still justified. There are many that could be stabilized right away.

Your first example uses the useGlobalSetting hook. This one was added 3 years ago in #35264 and it hasn't changed since. It has three parameters (path, block, source) and returns a state-like [ value, setValue] array. In Jan 2023 #47098 moved it from edit-site to block-editor, no other change ever happened. This hook and many other Global Styles APIs are a clear candidate for stabilization.

The second example uses the @wordpress/router package. What is special here is that:

While I fully agree with our commitment to maintaining stable APIs, I’m not sure why we should take responsibility for not breaking plugins that use private APIs.

In my view the API stability policy is there also to protect the user from us engineers 🙂 If a plugin tries to use some API that's no longer there or is different, the user's site will break and the user will be harmed. Then various groups of engineers can argue with each other about whose fault it is and who is responsible, but that doesn't help the user much -- their site is broken.

jsnajdr commented 1 month ago

We already use globalThis.IS_GUTENBERG_PLUGIN to avoid shipping some experimental APIs to Core. An example that comes to my mind is the wp.editor.registerEntityAction API.

Yes, maybe we don't really need much more than that. In its current form, wp.editor.registerEntityAction is a public function that behaves as a noop outside the Gutenberg plugin. Technically, we made a commitment to keep the function there so that a wp.editor.registerEntityAction() call doesn't crash.

If I make an analogy with public/protected/private modifiers in PHP or C++, we want to introduce "protected" APIs that can be used more widely than "private" ones, namely by plugins. Then registerEntityAction would no longer be public, but it would be a protected API that a plugin explicitly needs to opt-in into.

So I had assumed the discussion was more general, about Core as well.

We can discuss also Core and access to private APIs without the Gutenberg plugin active. It's just that we don't have any nice solution for that yet, and also it's not clear who needs such a Core access and what the requirements are.

youknowriad commented 1 month ago

We can discuss also Core and access to private APIs without the Gutenberg plugin active. It's just that we don't have any nice solution for that yet, and also it's not clear who needs such a Core access and what the requirements are.

For me the need is that we need a better feedback loop with extenders and Extenders can give us that feedback unless they ship their plugins to real users without the need for an additional Gutenberg plugin forced onto their users.

It's true that we've managed so far to have something "working" without it but it's far from ideal.

joshuatf commented 1 month ago

It seems like we're discussing two things in this issue:

  1. How we can safely expose private APIs to third party plugins.
  2. How we can get feedback on those APIs so that they can eventually become stable.

On the 1st point, as I understand it Gutenberg could remove or introduce a breaking change to a private API at any point in time (please correct me if I'm wrong here). This makes it unsafe for plugins like WooCommerce to consume these APIs and subsequently difficult to accomplish point 2 for Gutenberg to get feedback on these APIs.

It might also be dangerous relying on the Gutenberg plugin being active as a means to expose private APIs. This seems like it's introducing a dependency that can't be fully controlled by the consuming plugin. For example, one plugin might require version X and the other requires version Y, with version X having the private API that plugin A needs, while breaking changes are made in version Y.

Using NPM would be a simple solution that would allow plugins to pin versions with the private APIs without introducing breaking changes in upcoming versions. However, this eliminates the benefits of exposing packages on the wp global and is costly in terms of performance if multiple plugins are all pinning different versions of packages in order to guarantee that a certain API is in place.

I wonder if there's an opportunity to create a minimal package that houses the private APIs and could be pinned by consumers. However, in practice I think there might be too many interdependencies for those private APIs, creating the same performance issues we were trying to avoid.

adamziel commented 1 month ago

For me the need is that we need a better feedback loop with extenders and Extenders can give us that feedback unless they ship their plugins to real users without the need for an additional Gutenberg plugin forced onto their users.

I wanted to echo my comment from another thread. The consent string seems like an obvious thing to look at, but I think it's just a symptom of a deeper challenge with the dependency graph.

Here's my understanding of the situation:

Does that sound right? If yes, that last steps effectively replaces the dependency graph used by @wordpress/dataviews. The assumption seems to be "I'm sure window.wp is compatible with all possible versions of this dependency". Is that assumption correct? Aside of the private APIs, that is.

One solution would be for all the dataviews-reliant plugins to require the Gutenberg plugin after all. Then, instead of bundling the package we could perform the substitution to window.wp.dataViews and keep a coherent dependency graph.

mtias commented 1 month ago

The idea of using the presence of the Gutenberg plugin to expose unstable APIs so plugins can get ahead, try, provide feedback, etc, is how we've been thinking about it already. Gutenberg has become, as a matter of fact, a channel for early testing of both user and developer features. Plugins that have a dependency on Gutenberg would be well aware of it and should help promote APIs that become solid to be part of Core releases.

I also agree with @youknowriad that it'd be good to formalize the state of some of these, whether that is through "stages" or something else.

jsnajdr commented 1 month ago

@adamziel The @wordpress/dataviews package is special because it's not a part of the WordPress platform. There is no wp-dataviews script you can enqueue, no wp.dataviews global that needs to have a reliable contract with consumer. It's just another NPM package you can use and bundle in your project. It has no WordPress compatibility constraints.

The only problem with @wordpress/dataviews is that it uses private APIs from @wordpress/components, which is a part of the platform. That creates its own set of issues as discussed in #63657.

This discussion is mainly about packages that i) are part of the platform, and ii) expose private experimental APIs that often change. If plugins could use these private APIs freely, an upgrade from WordPress 6.6 to 6.7 would likely break many sites.

joshuatf commented 1 month ago

@youknowriad @mtias I have 2 concerns with requiring the Gutenberg plugin to be active to use these newer APIs:

  1. It requires another plugin install (Gutenberg) for some features that are currently shipped as enabled with WooCommerce core.

I think this point might signal that the underlying API should be marked as stable, but I'm not sure that a single plugin (Woo) can make that decision. Even once that decision is made, it means that we need to always install Gutenberg with at least the next 2 WP versions.

  1. If the private APIs can be removed or changed at any time, what happens when one plugin is using the APIs from Gutenberg version A while another plugin is using APIs from version B? Or what happens when plugins get auto-updated and the API is no longer available?

This seems like it might wreak havoc on consuming plugins relying on an API being present in a specific version of Gutenberg.

adamziel commented 1 month ago

I think this:

The only problem with @wordpress/dataviews is that it uses private APIs from @wordpress/components, which is a part of the platform.

contradicts this:

It has no WordPress compatibility constraints.

@jsnajdr isn't that an implicit dependency on a specific WordPress / Gutenberg version?

peterwilsoncc commented 1 month ago

The idea of using the presence of the Gutenberg plugin to expose unstable APIs so plugins can get ahead, try, provide feedback, etc, is how we've been thinking about it already. Gutenberg has become, as a matter of fact, a channel for early testing of both user and developer features. Plugins that have a dependency on Gutenberg would be well aware of it and should help promote APIs that become solid to be part of Core releases.

I couldn't agree more with this. Making it easier to opt-in when running Gutenberg (via a fixed string or some other means) would help make this feedback loop easier.

I have 2 concerns with requiring the Gutenberg plugin to be active to use these newer APIs:

1. It requires another plugin install (Gutenberg) for some features that are currently shipped as enabled with WooCommerce core.

I think this point might signal that the underlying API should be marked as stable, but I'm not sure that a single plugin (Woo) can make that decision. Even once that decision is made, it means that we need to always install Gutenberg with at least the next 2 WP versions.

2. If the private APIs can be removed or changed at any time, what happens when one plugin is using the APIs from Gutenberg version A while another plugin is using APIs from version B?  Or what happens when plugins get auto-updated and the API is no longer available?

This seems like it might wreak havoc on consuming plugins relying on an API being present in a specific version of Gutenberg.

The private APIs are, by definition, not ready for use in production. If a theme or plugin chooses to __dangerousOptInToUnstableAPIsOnlyForCoreModules() for production code, then it's up to the developer of the third-party code to manage the fact that that private API can be removed or changed at any time.

I do accept that sometime we (being WordPress Core developers) could sometime mark APIs stable more quickly but it needs to be done through an issue to allow for folks to discuss whether the API is, in fact, in good shape to be marked stable.

I DO want to make it easier for third party developers to assist with the stabalization of the APIs and making it easier for devs to use the APIs in non-production code will help open the feedback loop. What I don't want to do is end up back were we started of experimental APIs been used so widely in production code that WordPress Core gets stuck with the first or second draft of the API by making them available without running the Gutenberg plugin.

joshuatf commented 4 weeks ago

The private APIs are, by definition, not ready for use in production. If a theme or plugin chooses to __dangerousOptInToUnstableAPIsOnlyForCoreModules() for production code, then it's up to the developer of the third-party code to manage the fact that that private API can be removed or changed at any time.

@peterwilsoncc I understand the conundrum and why we're moving this direction. However, if we're wanting to get early feedback on these APIs, I think this method might present some challenges to plugins.

As a 3PD, needing to install an additional plugin for a feature to work is less than ideal, but not a deal breaker. Needing to install a plugin for a feature to work AND not knowing if the (latest) installed version will even house the private APIs that allow said feature to work is a dealbreaker.

Unless I'm misunderstanding something, without a way to pin a specific version of the plugin (i.e., with the required APIs), there's not a way to guarantee that a feature is supported at any given time. I know that WooCommerce will not be able to reliably use or provide feedback on any of these APIs if that's the case.

joshuatf commented 3 weeks ago

One more question I have if we opt for the plugin approach is how we safe guard against changes in a consumer plugin.

Do we need to have strict version checks to make sure the functions work as expected in the event a function is removed or signature changes?

if ( GUTENBERG_VERSION === '19.3.0' ) {
    doPrivateApiThing();
}
jsnajdr commented 3 weeks ago

isn't that an implicit dependency on a specific WordPress / Gutenberg version?

@adamziel The contradiction can be resolved by distinguishing between:

jsnajdr commented 3 weeks ago

@joshuatf I can offer two arguments that could address your concerns:

The private APIs wouldn't change or disappear abruptly and randomly. The changes can be discussed, prepared for, you should be able to detect whether you're dealing with the old or new version. The point is that for stable APIs, we guarantee that plugin authors don't need to do any extra work. Once a stable API is there, WordPress guarantees that it will continue to work exactly the same way, practically forever. But unstable API is not the exact opposite of that (random chaos) but rather that the plugin developer is expected to keep up with the latest changes and update their code.

Second, in the future we should have only very few permanently private APIs, if any. They should get stable in a reasonable amount of time. If a plugin succesfully implements a production-ready feature using a private API, that's a strong stabilizing force that creates pressure on Core to stabilize that API, so that plugins can ship a stable version of the feature to general public. That's one thing I hope that this proposal achieves: that the private status will always be only temporary, because we'll have a good process how to get new APIs widely used, get feedback, and improve them quickly.

jsnajdr commented 3 weeks ago

It would be also nice to have the private APIs documented and sorted into various stages. That could be a well-maintained private-apis.md file in the repo which would document each API and describe how stable it is.

I started working on the private API docs in #66558.

psealock commented 3 weeks ago

Requiring the presence of Gutenberg plugin to expose Private APIs is a good solution that doesn't work for the business demands of a plugin like WooCommerce whose features are often shipped under deadlines imposed either internally or by contractual obligations.

The ideal scenario would be to rely on semver via NPM, but as mentioned above by @joshuatf, this is costly on performance. What if there is a solution that offers the security of semver but forces developers to be respectful of changing APIs?

What if the opt-in string was per package and required pinning to a major version of that package?

__dangerousOptInToUnstableAPIsOnlyForCoreModules(
    'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
    '@wordpress/router',
    '1.10.0^',
    'woocommerce'
);
jsnajdr commented 3 weeks ago

doesn't work for the business demands of a plugin like WooCommerce whose features are often shipped under deadlines imposed either internally or by contractual obligations.

This seems to be a project management issue about priorities. If you have a contractual obligation to deliver something by a certain date, then obviously you want to implement that with stable APIs, and you cannot spend time trying out experimental APIs.

For stabilizing Core APIs, the overwhelming constraint is "quality": we need to be sure that the API is right and that we can commit to it long-term. Deadlines play a very small role in that process. If another project's major constraint is "time", that leads to problems. It's a classic project management "triangle" where a project is constrained by resources, time, scope and quality and you can improve one metric only by compromising on others.

What if the opt-in string was per package and required pinning to a major version of that package?

If I understand it correctly, this means that the opt-in call can fail. It can return an error saying either that the Gutenberg plugin is required and you don't have it, or that you're requesting a version of the package that is not available on this particular WordPress installation.

Then you'd have to implement some fallback using stable APIs. Having two versions of a feature, one stable and conservative, and the other is experimental and optional.

psealock commented 2 weeks ago

Thanks @jsnajdr

Deadlines play a very small role in that process.

Thats a good point. For the sake of the discussion best to avoid that perspective.

If I understand it correctly, this means that the opt-in call can fail.

Yes, thats exactly right. The failure is by design what would keep extension developers honest about using an unstable API. WooCommerce, for example, has an L-1 support policy so that only the current latest WP and the previous versions are supported. In this scenario lets say a Private API gets a major version bump, requiring all opted-in consumers to update their consent strings otherwise fatal errors will occur. WooCommerce is now greatly incentivised to proactively address the update, determine what code changes are required for the updated API, and finally handle the situation to avoid breakage. This would be a regular part of the development process and provide enough friction to dissuade lazy usage of private APIs.

We'd need to gracefully handle failed consent in the UI by showing a message to update WooCommerce. Unit testing with pre-release versions of Core WP can offer enough time to address issues. Also, new WooCommerce features based on unstable APIs are often hidden behind feature flags where merchants can opt in to the new experience. This allows for early feedback, which affects usage of unstable APIs and ultimately provides feedback to those APIs and enhancing stability.

costasovo commented 1 week ago

@jsnajdr I'm very grateful for this discussion. Thank you for starting it! The idea of stages is great, and having information about how close to stabilization an API is would help us avoid touching fresh or temporarily unstable APIs and encourage us to experiment with the APIs that are close to becoming stable.

In MailPoet, we are working on the email editor, and we use a couple of private APIs. The editor is currently behind a feature flag, but we are working towards preparing it for a release. There is no hard deadline, but we would like to release it in the next couple of months. So, there is a motivation to help stabilize the APIs we use.

That's one thing I hope that this proposal achieves: that the private status will always be only temporary because we'll have a good process for how to get new APIs widely used, get feedback, and improve them quickly.

The stages will give us a clue about the stability of an API, but what about the process for stabilization? As I mentioned, we use private APIs, and we have the motivation to help stabilize them. What are the steps we should take to provide feedback and ask for stabilization? For example, we use ExperimantalBlockCanvas because we need one prop that is not available on the stable BlockCanvas. Shall we open an issue where we describe our use-case and ask for stabilization? Or do you imagine a different process for sharing feedback about the usage of an unstable API?

As for private APIs, they are available only when Gutenberg is active. I'm thinking about a situation when a private API becomes stable, and it may take a couple of months until it makes it to WP Core. I think it is a bit of a shame because if we know the API is stable and the private version in WP Core is the same, I think we could release the feature to users earlier.

jsnajdr commented 1 week ago

we use ExperimantalBlockCanvas because we need one prop that is not available on the stable BlockCanvas. Shall we open an issue where we describe our use-case and ask for stabilization?

Yes, in this case open an issue or even a PR that adds the prop to BlockCanvas. I guess you need contentRef? That should be easy to stabilize, it provides a ref to the content element which anyone can get anyway using the .editor-styles-wrapper selector. There are also hooks like useFlashEditableBlocks that are private and could be either made public, or called inside BlockCanvas without having to expose them. This was also discussed in #57672, namely in https://github.com/WordPress/gutenberg/issues/57672#issuecomment-1905653066 where @youknowriad says that he would like to make contentRef and other props not needed at all. Let's discuss how to get there. The #57672 issue is about the Isolated Block Editor, I guess the MailPoet editor has a lot in common with that.

ralucaStan commented 5 days ago

we use ExperimantalBlockCanvas because we need one prop that is not available on the stable BlockCanvas. Shall we open an issue where we describe our use-case and ask for stabilization?

Ideally we should discuss, maybe in a separate discussions, what is the best way for developers to submit proposals, how to advocate for API changes, what makes a valid proposal/feature request, etc.

While reading about React's release channels and how they expose experimental API, I came across their RFC system https://github.com/reactjs/rfcs.

React RFCs (Request for Comments) are a structured way for the React team and community to propose and discuss changes or additions to the React framework.

What I like about this process is that: